Что такое
Открываем новый проект. Сразу же форму переименовываем в fMain, в
свойстве Caption пишем "Мой блокнот". Сохраните проект под именем Editor. Это будет более профессиональная версия редактора текстов,
какой мы уже делали. Считайте, что это вторая версия программы, что и
напишете в окне fAbout.
Установите на форму компонент Memo, удалите весь текст из его
свойства Lines. Поверх Memo установите MainMenu и PopupMenu. Перейдите
на вкладку Dialogs в палитре компонентов, и также поверх Memo
установите OpenDialog, SaveDialog, FontDialog и ColorDialog. Все эти
компоненты не визуальные, пользователь их видеть не сможет. У Memo
сразу же укажите свойство Align=alClient, а свойство ScrollBar=ssVertical. Рекомендую для лучшего вида выбрать шрифт (свойство Font )
Times New Roman, а размер = 12. На всех компьютерах с русской Windows
есть этот шрифт, однако если вы будете писать программу для продажи в
Интернет, лучше оставить шрифт по умолчанию, это гарантирует, что он
будет читаться на всех компьютерах в мире.
Во всех Execute. Это метод логического типа, он возвращает True, если False в противном случае (например, пользователь
отказался от выбора файла). В связи с этим,
if OpenDialog1.Execute then...
В OpenDialog – открыть файл, и SaveDialog – сохранить файл), есть свойство FileName, которое
возвращает строку – адрес и имя выбранного файла. Вот, собственно, и
все, что нам нужно от этих
FontDialog в свойстве Font возвращает выбранный шрифт. Это
свойство непростое, оно имеет тип TFont, и присвоить его можно только
другому шрифту, например:
Memo1.Font := FontDialog1.Font;
Точно также, ColorDialog возвращает свойство Color – цвет,
имеющее тип TColor, и это свойство можно присвоить только объекту,
имеющему такой же тип:
Memo1.Color := ColorDialog1.Color;
Продолжим наш проект. Откройте редактор главного меню. Создайте раздел "Файл" и подразделы "Открыть", "Сохранить", "Закрыть", "-" и "Выход". Создайте раздел "Параметры" и подразделы "Выбрать шрифт" и "Выбрать цвет". Создайте раздел "Справка" и подраздел "О программе".
Теперь открываем редактор PopupMenu и вписываем разделы "Открыть",
"Сохранить", "Закрыть", "-" и "Выход". Сразу же на форме выделяем саму
форму (это можно сделать в окне Object – TreeView), и в свойстве PopupMenu выбираем наше меню. Теперь это меню откроется, если
пользователь щелкнет правой кнопкой по любому месту на форме.
Теперь нам нужно настроить фильтры в OpenDialog (Открыть)
и SaveDialog (Сохранить). Фильтры позволяют отображать в этих Filter OpenDialog, откройте редактор
фильтров. В первой колонке напишите "Текстовые документы", во второй –
"*.txt". В строке ниже укажите "Все файлы", а во второй колонке –
"*.*". Тоже самое сделайте для SaveDialog:
(рис 13.1) Настройка фильтра файловых диалоговТеперь, открывая файл, вы увидите только эти два типа файлов.
Подумаем о том, что программа должна знать – изменился ли текст в Memo. Ведь пользователь может закрыть программу и не сохранить текст,
а потом будет ругать программиста за то, что он этого не предусмотрел.
При этом имеем в виду, что у нас есть много команд меню, значит, будет
много процедур. А чтобы дать программе знать, изменился ли текст,
разумнее всего создать переменную логического типа – изменился текст,
присваиваем ей True, иначе False. Чтобы с этой переменной можно было
работать из всех процедур, она должна быть глобальной. Делаем
глобальную переменную перед словом implementation:
izmen : Boolean; //изменился ли текст в Memo
Событию onChange компонента Memo присвойте строку:
izmen := True;
Как только изменится текст в Memo, переменная тут же будет выдавать
истину.
Теперь еще один момент – программа должна знать имя и адрес открытого файла. Если имени файла нет, то программа будет выводить диалоговое окно, а если мы файл открывали и имя есть, то программа просто будет перезаписывать тот файл без вывода диалогового окна. Стало быть, делаем еще одну глобальную переменную:
myfile : String; //Адрес и имя открытого файла
Я специально не беру широко распространенные слова "File" или "FileName", так как они могут быть зарезервированными или в компонентах могут быть свойства с такими именами, в результате получится конфликт названий.
Соображаем дальше. Открыть файл можно будет командой меню "Файл –
Открыть", либо командой PopupMenu "Открыть". Стало быть, нам придется
дважды писать один и тот же код? А если он будет большим и сложным?
Можно конечно и скопировать его, компилятор это выдержит, и программа
будет работать нормально. А как же оптимизация кода? Два одинаковых
кода в программе будут занимать в два раза больше места в памяти и на
диске! Для этого мы имеем пользовательские функции и процедуры.
Вспоминаем – функцию или процедуру мы должны описать ВЫШЕ того
места, где будем ее использовать, значит, первую нашу процедуру мы
должны описать в разделе implementation, прямо под строчкой {$R *..
Сейчас вы узнаете еще кое-что новенькое. В таких вот
Memo1.
то компилятор сразу выдаст ошибку. Обращаться к компоненту нужно, указав сначала имя формы, на которой он находится:
fMain.Memo1.
Однако такой код будет не слишком удобен – каждый раз придется
обращаться к компонентам через форму. Лишний набор кода, излишне
длинный текст. Выход есть – функция with (с). Эта функция имеет
вид:
with fMain do begin ... end;
где fMain – имя формы с нужными нам компонентами. Теперь между
скобок begin...end этой конструкции мы можем обращаться к компонентам
формы напрямую. Пишем общую для всех процедуру открытия файла:
{Процедура открытия файла}
procedure Otkrivaem;
begin
with fMain do begin //делать вместе с формой
if OpenDialog1.Execute then begin //если диалог выполнен
//присваиваем переменной myfile адрес и имя выбранного файла:
myfile := OpenDialog1.FileName;
//читаем этот файл в Memo:
Memo1.Lines.LoadFromFile(myfile);
izmen := False; //файл только открыт, изменений еще нет
end; //if
end; //with
end;
Теперь создаем обработчик событий для команды меню "Файл – Открыть". Там вызываем нашу процедуру:
Otkrivaem;
Тоже самое делаем для команды PopupMenu "Открыть".
Дальше – сложней. Открыть файл просто, но вот при сохранении нам придется учитывать много вещей:
myfile пуста и не содержит имя файла. В таком случае придется выводить SaveDialog1, чтобы пользователь указал имя файла. Когда он укажет имя, присвоить его переменной myfile и сохранить Memo в указанный файл.myfile это имя уже есть, Видите? Пользоваться
{Процедура сохранения файла}
procedure Sohranyaem;
begin
with fMain do begin
//если изменений не было, выходим из процедуры,
//ничего не делая:
if not izmen then Exit;
//Если файл уже открывался, и в переменной myfile
//есть его адрес и имя, просто перезаписываем этот файл:
if myfile <> '' then begin
Memo1.Lines.SaveToFile(myfile);
izmen := False;
Exit; //выходим после сохранения
end; //if
{Файл новый, переменная myfile еще пуста. Дальше есть два варианта:
пользователь выберет или укажет файл в диалоге, или не сделает этого}
//если выбрал файл:
if SaveDialog1.Execute then begin
//прописываем адрес и имя файла в переменную:
myfile := SaveDialog1.FileName;
//если нет расширения *.txt то добавляем его:
if copy(myfile, length(myfile)-3, 4) <> '.txt' then
myfile := myfile + '.txt';
//сохраняем Memo в указанный файл:
Memo1.Lines.SaveToFile(myfile);
//файл сохранен, изменений нет:
izmen := False;
end //if
//если не выбрал файл:
else ShowMessage('Вы не указали имя файла, файл не сохранен!');
end; //with
end;
Приведенный выше код имеет достаточно подробные комментарии, так
что все должно быть понятно. Новое, что вы могли увидеть – директива Exit. Эта директива досрочно завершает работу процедуры (или функции).
То есть, если выполнено условие и отработан нужный код, Exit
заставляет процедуру завершить работу. Остальной код, который есть в
этой процедуре, не выполняется.
Теперь мы можем создать обработчик главного меню "Файл – Сохранить", и там прописать вызов этой процедуры:
Sohranyaem;
Тоже самое делаем для команды PopupMenu "Сохранить".
Далее идет команда главного и всплывающего меню "Выход". Тут все просто, в обоих случаях пишем команду
Close;
Далее идет раздел "Параметры". Создаем обработчик "Выбрать шрифт", там все просто:
if FontDialog1.Execute then
Memo1.Font := FontDialog1.Font;
Точно также и с подразделом "Выбрать цвет":
if ColorDialog1.Execute then
Memo1.Color := ColorDialog1.Color;
Далее вернемся в раздел "Файл". Здесь у нас остался подраздел "Закрыть". Создаем для него обработчик, и запишем текст:
{если файл не сохранен, предупреждаем пользователя об этом. Если он
желает сохранить, то вызываем процедуру сохранения:}
if izmen then
if Application.MessageBox('Файл изменен. Сохранить?', 'Внимание!',
MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;
//теперь закрываем текущий файл:
Memo1.Clear; //очищаем Мемо
myfile := ''; //нет имени текущего файла
izmen := False; //нет изменений
Здесь не так много текста, и он вполне понятен, поэтому не будем для него делать отдельную процедуру. Просто скопируйте текст, создайте обработчик событий для "Закрыть" PopupMenu и вставьте этот же текст туда.
Примерно тоже самое нам придется сделать и для события формы onClose – ведь мы заранее не можем знать, каким образом пользователь
закроет форму, через команду главного меню "Файл – Закрыть", через
команду всплывающего меню "Закрыть", нажмет ли он красный крестик
наверху или нажмет горячие клавиши <Alt + F4>! Поэтому для проверки –
есть ли в программе несохраненный текст, мы используем событие onClose, которое случается при попытке закрыть форму, то есть в данном
случае всю программу. Здесь код будет таким же, как и в предыдущем
примере, но раз мы закрываем всю программу, нам не нужно выполнять
блок закрытия файла. Просто проверим, есть ли изменения, и если они
есть, выведем запрос – сохранить ли их. Если пользователь ответит
"Да", значит, вызовем процедуру сохранения:
{если файл не сохранен, предупреждаем пользователя об этом. Если он
желает сохранить, то вызываем процедуру сохранения:}
if izmen then
if Application.MessageBox('Файл изменен. Сохранить?', 'Внимание!',
MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;
Теперь введем еще одну команду для обоих меню – "Очистить". Она будет предназначена на случай, если пользователь введет абракадабру, а потом решит очистить текст. Я намеренно оставил это действие на конец, чтобы вы могли усвоить, что в процессе работы над программой меню может изменяться!
Откройте редактор MainMenu, в разделе "Файл" в самом низу добавьте подраздел "Очистить". Затем мышкой перетащите его на место линии разделов, при этом линия опустится вниз, а новый подраздел встанет на ее место:
(рис 13.2) Вид главного менюСоздайте для команды "Очистить" обработчик, и впишите туда текст:
{MainMenu - Файл - Очистить}
procedure TfMain.N17Click(Sender: TObject);
begin
//очищаем Мемо:
Memo1.Clear;
//если открытого файла нет, то нет и изменений:
if myfile = '' then izmen := false
//иначе текст изменен:
else izmen := true;
end;
Сделайте то же самое для всплывающего меню – создайте раздел "Очистить", а в его обработчик скопируйте тот же текст.
Осталось создать модальное окно fAbout, где Вы укажете, что это
текстовый редактор, второй версии. Сделайте это самостоятельно и
привяжите вызов этой формы к команде главного меню "Справка – О
программе".
Все, сохраняйте, компилируйте и проверяйте, как работает программа! У нас получился несложный, но вполне профессиональный редактор текстов. Одно замечание: текст мы сохраняем, но вот выбранный шрифт и цвет окна Вы сохранить не можете, об этом мы будем говорить на других лекциях, когда научимся сохранять параметры.
Что такое
Открываем новый проект. Сразу же форму переименовываем в fMain, в
свойстве Caption пишем "Мой блокнот". Сохраните проект под именем Editor. Это будет более профессиональная версия редактора текстов,
какой мы уже делали. Считайте, что это вторая версия программы, что и
напишете в окне fAbout.
Установите на форму компонент Memo, удалите весь текст из его
свойства Lines. Поверх Memo установите MainMenu и PopupMenu. Перейдите
на вкладку Dialogs в палитре компонентов, и также поверх Memo
установите OpenDialog, SaveDialog, FontDialog и ColorDialog. Все эти
компоненты не визуальные, пользователь их видеть не сможет. У Memo
сразу же укажите свойство Align=alClient, а свойство ScrollBar=ssVertical. Рекомендую для лучшего вида выбрать шрифт (свойство Font )
Times New Roman, а размер = 12. На всех компьютерах с русской Windows
есть этот шрифт, однако если вы будете писать программу для продажи в
Интернет, лучше оставить шрифт по умолчанию, это гарантирует, что он
будет читаться на всех компьютерах в мире.
Во всех Execute. Это метод логического типа, он возвращает True, если False в противном случае (например, пользователь
отказался от выбора файла). В связи с этим,
if OpenDialog1.Execute then...
В OpenDialog – открыть файл, и SaveDialog – сохранить файл), есть свойство FileName, которое
возвращает строку – адрес и имя выбранного файла. Вот, собственно, и
все, что нам нужно от этих
FontDialog в свойстве Font возвращает выбранный шрифт. Это
свойство непростое, оно имеет тип TFont, и присвоить его можно только
другому шрифту, например:
Memo1.Font := FontDialog1.Font;
Точно также, ColorDialog возвращает свойство Color – цвет,
имеющее тип TColor, и это свойство можно присвоить только объекту,
имеющему такой же тип:
Memo1.Color := ColorDialog1.Color;
Продолжим наш проект. Откройте редактор главного меню. Создайте раздел "Файл" и подразделы "Открыть", "Сохранить", "Закрыть", "-" и "Выход". Создайте раздел "Параметры" и подразделы "Выбрать шрифт" и "Выбрать цвет". Создайте раздел "Справка" и подраздел "О программе".
Теперь открываем редактор PopupMenu и вписываем разделы "Открыть",
"Сохранить", "Закрыть", "-" и "Выход". Сразу же на форме выделяем саму
форму (это можно сделать в окне Object – TreeView), и в свойстве PopupMenu выбираем наше меню. Теперь это меню откроется, если
пользователь щелкнет правой кнопкой по любому месту на форме.
Теперь нам нужно настроить фильтры в OpenDialog (Открыть)
и SaveDialog (Сохранить). Фильтры позволяют отображать в этих Filter OpenDialog, откройте редактор
фильтров. В первой колонке напишите "Текстовые документы", во второй –
"*.txt". В строке ниже укажите "Все файлы", а во второй колонке –
"*.*". Тоже самое сделайте для SaveDialog:
(рис 13.1) Настройка фильтра файловых диалоговТеперь, открывая файл, вы увидите только эти два типа файлов.
Подумаем о том, что программа должна знать – изменился ли текст в Memo. Ведь пользователь может закрыть программу и не сохранить текст,
а потом будет ругать программиста за то, что он этого не предусмотрел.
При этом имеем в виду, что у нас есть много команд меню, значит, будет
много процедур. А чтобы дать программе знать, изменился ли текст,
разумнее всего создать переменную логического типа – изменился текст,
присваиваем ей True, иначе False. Чтобы с этой переменной можно было
работать из всех процедур, она должна быть глобальной. Делаем
глобальную переменную перед словом implementation:
izmen : Boolean; //изменился ли текст в Memo
Событию onChange компонента Memo присвойте строку:
izmen := True;
Как только изменится текст в Memo, переменная тут же будет выдавать
истину.
Теперь еще один момент – программа должна знать имя и адрес открытого файла. Если имени файла нет, то программа будет выводить диалоговое окно, а если мы файл открывали и имя есть, то программа просто будет перезаписывать тот файл без вывода диалогового окна. Стало быть, делаем еще одну глобальную переменную:
myfile : String; //Адрес и имя открытого файла
Я специально не беру широко распространенные слова "File" или "FileName", так как они могут быть зарезервированными или в компонентах могут быть свойства с такими именами, в результате получится конфликт названий.
Соображаем дальше. Открыть файл можно будет командой меню "Файл –
Открыть", либо командой PopupMenu "Открыть". Стало быть, нам придется
дважды писать один и тот же код? А если он будет большим и сложным?
Можно конечно и скопировать его, компилятор это выдержит, и программа
будет работать нормально. А как же оптимизация кода? Два одинаковых
кода в программе будут занимать в два раза больше места в памяти и на
диске! Для этого мы имеем пользовательские функции и процедуры.
Вспоминаем – функцию или процедуру мы должны описать ВЫШЕ того
места, где будем ее использовать, значит, первую нашу процедуру мы
должны описать в разделе implementation, прямо под строчкой {$R *..
Сейчас вы узнаете еще кое-что новенькое. В таких вот
Memo1.
то компилятор сразу выдаст ошибку. Обращаться к компоненту нужно, указав сначала имя формы, на которой он находится:
fMain.Memo1.
Однако такой код будет не слишком удобен – каждый раз придется
обращаться к компонентам через форму. Лишний набор кода, излишне
длинный текст. Выход есть – функция with (с). Эта функция имеет
вид:
with fMain do begin ... end;
где fMain – имя формы с нужными нам компонентами. Теперь между
скобок begin...end этой конструкции мы можем обращаться к компонентам
формы напрямую. Пишем общую для всех процедуру открытия файла:
{Процедура открытия файла}
procedure Otkrivaem;
begin
with fMain do begin //делать вместе с формой
if OpenDialog1.Execute then begin //если диалог выполнен
//присваиваем переменной myfile адрес и имя выбранного файла:
myfile := OpenDialog1.FileName;
//читаем этот файл в Memo:
Memo1.Lines.LoadFromFile(myfile);
izmen := False; //файл только открыт, изменений еще нет
end; //if
end; //with
end;
Теперь создаем обработчик событий для команды меню "Файл – Открыть". Там вызываем нашу процедуру:
Otkrivaem;
Тоже самое делаем для команды PopupMenu "Открыть".
Дальше – сложней. Открыть файл просто, но вот при сохранении нам придется учитывать много вещей:
myfile пуста и не содержит имя файла. В таком случае придется выводить SaveDialog1, чтобы пользователь указал имя файла. Когда он укажет имя, присвоить его переменной myfile и сохранить Memo в указанный файл.myfile это имя уже есть, Видите? Пользоваться
{Процедура сохранения файла}
procedure Sohranyaem;
begin
with fMain do begin
//если изменений не было, выходим из процедуры,
//ничего не делая:
if not izmen then Exit;
//Если файл уже открывался, и в переменной myfile
//есть его адрес и имя, просто перезаписываем этот файл:
if myfile <> '' then begin
Memo1.Lines.SaveToFile(myfile);
izmen := False;
Exit; //выходим после сохранения
end; //if
{Файл новый, переменная myfile еще пуста. Дальше есть два варианта:
пользователь выберет или укажет файл в диалоге, или не сделает этого}
//если выбрал файл:
if SaveDialog1.Execute then begin
//прописываем адрес и имя файла в переменную:
myfile := SaveDialog1.FileName;
//если нет расширения *.txt то добавляем его:
if copy(myfile, length(myfile)-3, 4) <> '.txt' then
myfile := myfile + '.txt';
//сохраняем Memo в указанный файл:
Memo1.Lines.SaveToFile(myfile);
//файл сохранен, изменений нет:
izmen := False;
end //if
//если не выбрал файл:
else ShowMessage('Вы не указали имя файла, файл не сохранен!');
end; //with
end;
Приведенный выше код имеет достаточно подробные комментарии, так
что все должно быть понятно. Новое, что вы могли увидеть – директива Exit. Эта директива досрочно завершает работу процедуры (или функции).
То есть, если выполнено условие и отработан нужный код, Exit
заставляет процедуру завершить работу. Остальной код, который есть в
этой процедуре, не выполняется.
Теперь мы можем создать обработчик главного меню "Файл – Сохранить", и там прописать вызов этой процедуры:
Sohranyaem;
Тоже самое делаем для команды PopupMenu "Сохранить".
Далее идет команда главного и всплывающего меню "Выход". Тут все просто, в обоих случаях пишем команду
Close;
Далее идет раздел "Параметры". Создаем обработчик "Выбрать шрифт", там все просто:
if FontDialog1.Execute then
Memo1.Font := FontDialog1.Font;
Точно также и с подразделом "Выбрать цвет":
if ColorDialog1.Execute then
Memo1.Color := ColorDialog1.Color;
Далее вернемся в раздел "Файл". Здесь у нас остался подраздел "Закрыть". Создаем для него обработчик, и запишем текст:
{если файл не сохранен, предупреждаем пользователя об этом. Если он
желает сохранить, то вызываем процедуру сохранения:}
if izmen then
if Application.MessageBox('Файл изменен. Сохранить?', 'Внимание!',
MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;
//теперь закрываем текущий файл:
Memo1.Clear; //очищаем Мемо
myfile := ''; //нет имени текущего файла
izmen := False; //нет изменений
Здесь не так много текста, и он вполне понятен, поэтому не будем для него делать отдельную процедуру. Просто скопируйте текст, создайте обработчик событий для "Закрыть" PopupMenu и вставьте этот же текст туда.
Примерно тоже самое нам придется сделать и для события формы onClose – ведь мы заранее не можем знать, каким образом пользователь
закроет форму, через команду главного меню "Файл – Закрыть", через
команду всплывающего меню "Закрыть", нажмет ли он красный крестик
наверху или нажмет горячие клавиши <Alt + F4>! Поэтому для проверки –
есть ли в программе несохраненный текст, мы используем событие onClose, которое случается при попытке закрыть форму, то есть в данном
случае всю программу. Здесь код будет таким же, как и в предыдущем
примере, но раз мы закрываем всю программу, нам не нужно выполнять
блок закрытия файла. Просто проверим, есть ли изменения, и если они
есть, выведем запрос – сохранить ли их. Если пользователь ответит
"Да", значит, вызовем процедуру сохранения:
{если файл не сохранен, предупреждаем пользователя об этом. Если он
желает сохранить, то вызываем процедуру сохранения:}
if izmen then
if Application.MessageBox('Файл изменен. Сохранить?', 'Внимание!',
MB_YESNO+MB_ICONQUESTION) = IDYES then Sohranyaem;
Теперь введем еще одну команду для обоих меню – "Очистить". Она будет предназначена на случай, если пользователь введет абракадабру, а потом решит очистить текст. Я намеренно оставил это действие на конец, чтобы вы могли усвоить, что в процессе работы над программой меню может изменяться!
Откройте редактор MainMenu, в разделе "Файл" в самом низу добавьте подраздел "Очистить". Затем мышкой перетащите его на место линии разделов, при этом линия опустится вниз, а новый подраздел встанет на ее место:
(рис 13.2) Вид главного менюСоздайте для команды "Очистить" обработчик, и впишите туда текст:
{MainMenu - Файл - Очистить}
procedure TfMain.N17Click(Sender: TObject);
begin
//очищаем Мемо:
Memo1.Clear;
//если открытого файла нет, то нет и изменений:
if myfile = '' then izmen := false
//иначе текст изменен:
else izmen := true;
end;
Сделайте то же самое для всплывающего меню – создайте раздел "Очистить", а в его обработчик скопируйте тот же текст.
Осталось создать модальное окно fAbout, где Вы укажете, что это
текстовый редактор, второй версии. Сделайте это самостоятельно и
привяжите вызов этой формы к команде главного меню "Справка – О
программе".
Все, сохраняйте, компилируйте и проверяйте, как работает программа! У нас получился несложный, но вполне профессиональный редактор текстов. Одно замечание: текст мы сохраняем, но вот выбранный шрифт и цвет окна Вы сохранить не можете, об этом мы будем говорить на других лекциях, когда научимся сохранять параметры.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.