Работа с Edit и Memo

Переопределение символов при вводе текста




Уроки Delphi
  1.  Первая программа
  2.  Использование компонентов
  3.  События Delphi
  4.  Типы данных Delphi
  5.  Создание своих типов данных
  6.  Выражения и операторы
  7.  Работа с файлами в Delphi
  8.  Дополнительные формы
  9.  Подпрограммы в Delphi
  10. Исключительные ситуации
  11. Взаимодействие приложения с пользователем
  12. Указатели в Delphi
  13. Обзор компонентов
  14. Работа со строками
  15. Создание интерфейса
  16. Графика в Delphi
  17. Многопоточность в Delphi
  18. Динамическое создание
        компонентов
Поиск по сайту




 Это важно:
   Метод Application.ProcessMessages;

 Это полезно:
   Параметр Sender в обработчиках событий;










Бояться не надо



Кофе-Брейк зеленый чай в СПб

   Этот урок содержит ответ на вопрос в одном из комментариев. Вот как он был сформулирован:


   Иван, добавлено 21.04.10, 16:02:29
   Привет. Я хочу сделать так, чтобы при вводе так сказать пароля в окно edit, выводились звездочки, но звездочками не значились. Т.е. ввел 50, при нажатии "Ок" к примеру, у меня все было нормально. Как бы пароль принят. Я пробовал пример и мне интересно, за что отвечает "Pass:=Pass+Key;". Что это действие выполняет. И где и каким типом объявлена переменная Pass.

Ответ: Для того чтобы при вводе пароля вместо вводимых символов появлялись звёздочки, нужно переопределять переменную Key в обработчике OnKeyPress. Она имеет тип Char (т.е. символ):
  Key:='*';
Предварительно нужно сохранить вводимый символ в предварительно обнулённой глобальной переменной Pass типа String:
  Pass:=Pass+Key;
Таким образом, обработчик будет выглядеть так:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
  Pass:=Pass+Key;
  Key:='*';
end;

В дальнейшем на совпадение с паролем нужно анализировать переменную Pass.


Иван, добавлено 21.04.10, 22:45:56
Понятно. Спасибо. Но из этого вытекает другой вопрос. При наборе текста выводятся звездочки, это отлично, т.к. и хотели именно этого, но если после ввода чего-то в edit мне захотелось стереть то, что написал, клавишей "Backspace", то вместо стирания происходит ввод. И это видно по тому, что ничего не стирается, а звездочки увеличиваются.

Ответ: Для решения этой задачи нам нужно отлавливать нажатие клавиши "Backspace". Но обработчик OnKeyPress обрабатывает только нажатие клавиш с символами. Значит, нужно воспользоваться обработчиком OnKeyDown или OnKeyUp. В них переменная Key имеет тип Word, то есть число. Клавиша "Backspace" кодируется числом 8. Код любой клавиши можно узнать и без справочников, выполнив в одном из этих обработчиков:

Caption:=IntToStr(Key);  //Код клавиши выводится в заголовок Формы

Итак, при нажатии "Backspace" нужно стирать по последнему символу и в Edit, и в Pass:

if(Key=8) then
 begin
  Edit1.Text:=copy(Edit1.Text, 1, Length(Edit1.Text)-1);
  Pass:=copy(Pass, 1, Length(Pass)-1); //На самом деле, здесь отнимать нужно 2, далее увидите сами!
 end;

Правда, выясняется, что при этом всё равно происходит ввод. Следовательно, нужно вообще запретить ввод в Edit через обработчик OnKeyPress, присвоив переменной Key пустой символ #0, а менять Edit здесь же. Далее, возникает следующая проблема: при изменении в Edit курсор перемещается в начало. Значит, нужно самим перемещать его в конец! Вот что получилось в итоге:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  Pass:=Pass+Key;
  Key:=#0;
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if(Key=8) then
  begin
   Edit1.Text:=copy(Edit1.Text, 1, Length(Edit1.Text)-1);
   Pass:=copy(Pass, 1, Length(Pass)-2); //Да, здесь именно минус 2, попробуйте сами, отнимите 1!
  end
  else Edit1.Text:=Edit1.Text+'*';
Edit1.SelStart:=Length(Edit1.Text); //Перемещение курсора в конец
Caption:=Pass; //Просто проверка, в реальной программе удалить
end;

Однако, при нажатии некоторых служебных клавиш наш Edit меняется. Чтобы этого не происходило, нужно коды этих клавиш собрать во множество, и менять Edit только если Key не принадлежит этому множеству. Вот как объявить множество:

  var SlaveKey: set of 9..123;

Вот какие коды в него включить (если какие забыл, добавьте!):

  SlaveKey:=[9, 13, 16..20, 27, 33..40, 45..46, 112..123];

Вот где проверять:

  else if (not(Key in SlaveKey)) then Edit1.Text:=Edit1.Text+'*';

Однако замечаем, что при нажатии Escape (Esc, код 27) переменная Pass меняется, Edit нет. Исправляем здесь:

  if((Key=8)or(Key=27)) then

Теперь последний символ можно стереть не только нажатием Backspace, но и Escape. Это нам не мешает.

Эти принципы использованы в демонстрационной программе, предоставляющей по паролю доступ к редактированию текста. Её можно скачать, и использовать модуль проверки пароля в своих проектах.

   Необходимо сказать о том, что пароль в открытом виде хранить небезопасно, хоть в файле на диске, хоть в самой программе. Стоит открыть любой файл или даже запароленную программу простым Windows-блокнотом, и сохранённый пароль можно легко отыскать. Поэтому перед сохранением пароль шифруют функцией необратимого шифрования - то есть, зная зашифрованный пароль, исходную форму восстановить невозможно. Для шифрования часто применяют хеш-функцию md5, которая реализована и в Delphi:

function md5(s: string): string;
begin
Result := '';
with TIdHashMessageDigest5.Create do
  try
    Result := AnsiLowerCase(AsHex(HashValue(s)));
  finally
    Free;
  end;
end;

   Для работы этой функции необходимо добавить в список используемых модулей модуль IdHashMessageDigest из пакета Indy. Теперь введённый пользователем текст необходимо зашифровать и только потом сравнивать с сохранённым в файле также зашифрованным паролем. А злоумышленник, даже найдя зашифрованный пароль, не сможет по нему восстановить оригинальную фразу пароля!


Предыдущий урок           В начало урока          Следующий урок  

Уроки Delphi начинающим



Вопросы и комментарии (8)      Решение задач в Delphi

Оставить комментарий:

Имя  

Текст комментария