Теория / Обработка событий
.pdfОбработка событий Понятие события и его обработки
Операционная система Windows (Linux) - многозадачная, т.е. несколько программ в ней могут функционировать одновременно. Когда, например, мы щёлкаем по кнопке в окне нашей программы, система Windows определяет, что произошло событие именно в нашей программе, и посылает ей сообщение об этом. Наша программа должна соответствующим образом отреагировать на него. Для этого мы, как программисты, должны написать код-обработчик этого события.
Таким образом, программа для Windows представляет собой набор подпрограмм, каждая из которых ответственна за обработку конкретного события и вызывается только при его возникновении.
Каждый компонент имеет набор событий, на которые он может реагировать.
Программист сам определяет, какие события в программе требуется обрабатывать Событие (Event) – это то, что происходит во время работы программы. В Lazarus
каждому событию присвоено имя. Например, щелчок кнопкой мыши – это событие OnClick, двойной щелчок мышью событие OnDblClick
Удобство Lazarus (Delphi) состоит в том, что мы избавлены от необходимости получать сообщения от Windows сами, среда программирования это делает за нас.
В Lazarus обработка события определяется специальной процедурой, которую должен написать программист. Обработка требует какого-либо действия в ответ на событие. Многие компоненты уже имеют готовые реакции на стандартные события.
На рисунке показана схема работы программы, основанной на событиях:
Основная программа обычно содержит всего несколько строк, ее задача — сделать все начальные установки и сообщить операционной системе адрес процедуры обработки сообщений (или оконной процедуры). В эту процедуру будут направляться все сообщения, предназначенные данной программе: информация о действиях пользователя, а также сообщения операционной системы (например, сигналы таймера).
Обработчики событий
Получив сообщение от операционной системы, процедура обработки сообщений «разбирается» с ним: вызывает обработчик этого сообщения, если он существует. Если такого обработчика нет, программа никак не реагирует на полученное сообщение.
Обратите внимание, что здесь основная программа напрямую не связана с процедурами-обработчиками, она сама их не вызывает. Их вызывает процедура обработки сообщений, получив сообщение от операционной системы.
Во все обработчики событий передается параметр Sender типа TОbject. Этот параметр содержит указатель на компонент, в котором произошло событие. Он не требуется, если пишется обработчик события для одного конкретного компонента. Однако часто один обработчик применяется для нескольких компонентов. При этом какие-то
операции могут быть общими для любых источноков события, а какие-то требовать специфических действий. Тогда Sender можно использовать для распознавания источника события. Тип TОbject не имеет никаких полезных для пользователя свойств и методов и объект Sender нужно рассматривать как объект одного из производных от Tоbject типов (объектная модель в Delphi).
Copied from: http://articles.org.ru/lection/mouse.php
Создание обработчика события
Создать обработчик события можно двумя способами.
Для перехода к процедуре обработки следует либо дважды щелкнуть на выбранном компоненте, (будет создана процедура обработки наиболее часто используемого события) либо выбрать событие в списке Инспектора и дважды щелкнуть на поле рядом с именем события.
В обоих случаях откроется окно редактора кода с заготовкой (шаблоном) процедуры.
Код, автоматически сформированный средой программирования, не рекомендуется менять.
Для компонента Edit наиболее часто используются следующие события: OnChange – при изменении значения
OnClick – при щелчке OnDblClick – при двойном щелчке OnEnter – при входе в компонент
OnKeyPress – при нажатии клавиши OnExit – при выходе из редактирования
Событиz OnClick и OnEnter часто используются, например, для очистки строки ввода.
Событие OnKeyPress можно использовать для фильтрации ввода.
Например, если в поле требуется вводить число, то можно создать обработчик, в котором будут игнорироваться нажатия всех клавиш, кроме цифр и точки.
Примеры создания процедур обработки событий
В начале работы любой программы происходит очень важное событие основного компонента - Формы, onCreate. Оно происходит перед появлением Формы на экране. Это событие используется для задания свойств тех элементов программы, которые нуждаются в настройке, например, размеры и положение Формы на экране. Если вы захотите сделать невидимую программу, можно приравнять нулю ширину Width и высоту Height Формы. На этапе проектирования сделать этого нельзя, т.к. это помешает работе, поэтому делаем это по событию onCreate:
Form1.Width := 0;
Form1.Height := 0;
Дополнительно нужно убрать и заголовок Формы, выбрав в Инспекторе Объектов параметр BorderStyle равным None. Теперь Форма на экране не появится. Единственным визуальным признаком останется появление её "значка" на панели задач.
Компонент Form1 – событие OnCreate
При создании окна можно указать начальные параметры его элементов. Например, задать тип выпадающего списка ComboBox:
procedure TForm1.FormCreate(Sender: TObject); begin
// задаем тип списка и его элементы
ComboBox1.Style := csDropDownList; ComboBox1.Items.Add('алюминий');
ComboBox1.Items.Add('пластик');
ComboBox1.Items.Add('текстиль'); ComboBox1.ItemIndex:=0;
end;
Компонент Form1 – событие OnActivate
// Обработка события активизации формы procedure TForm1.FormActivate(Sender: TObject); begin
// передача фокуса ввода списку ComboBox1
ComboBox1.SetFocus;
end;
Компонент Edit – событие OnKeyPress
Для компонента Edit можно выполнить проверку – является ли вводимый символ цифрой или BackSpace. Остальные символы будут игнорироваться:
procedure Edit4KeyPress(Sender: TObject; var Key: char); begin
if not ( key in [ '0' .. '9' , #8] ) then Key := #0 ;
end;
В этом примере #8 – код клавиши BackSpace, а оператор in [ '0' .. '9' , #8] означает проверку принадлежности заданному множеству.
Еще один пример фильтрации ввода: допускаются только цифры и Backspace, а при нажатии Enter введенный текст передается компоненту Label:
procedure Edit2KeyPress(Sender: TObject; var Key: char); // фильтрация ввода begin
case Key of
#8,'0'..'9': ; // цифры и клавиша <Backspace> #13: // клавиша <Enter> Label2.Caption:=StrToInt(Edit2.Text);
else key := Chr(0); // остальные символы запрещены end; { case }
end;
Можно передать управление другому компоненту – например, при непустом вводе передать фокус кнопке:
// нажатие клавиши в поле редактирования
procedure Edit1KeyPress(Sender: TObject; var Key: Char); begin
if (key = #13) and (Length(Edit1.Text) > 0) then Button1.SetFocus;
end;
Компонент Edit – событие OnChange
Если после изменений поле Edit пустое, то деактивировать кнопку: // изменился текст в поле редактирования
procedure Edit1Change(Sender: TObject);
begin
if Length(Edit1.Text) > 0 then Button1.Enabled := True
else
Button1.Enabled := False; end;
Компонент Edit – событие OnClick
Пусть, например, требуется очищать строку ввода при щелчке на ней. Щелчок мышью на компоненте – это событие OnClick. Следовательно, в Инспекторе объектов переходим на вкладку «События» и дважды щелкаем на OnClick. В обработчике события следует записать:
// очистить текст при щелчке мышью в поле Edit procedure TForm2.Edit1Click(Sender: TObject); begin
Edit1.Text:='';
end;
Напоминание: пустая строка – это две одинарные кавычки (апострофы) рядом. Можно также использовать специально предназначенный для этого метод Clear
компонента Edit: Edit1.Clear;
Компонент Button – событие OnClick
Создадим процедуру обработки события «щелчок на кнопке». Дважды щелкнем на кнопке, откроется заготовка процедуры.
// щелчок на кнопке
procedure TForm1.Button1Click(Sender: TObject); var w: integer;
begin
w:= StrToInt(Edit1.Text)-100-10; Label3.Caption:=IntToStr(w);
end;
События мыши и клавиатуры
Мышь и клавиатура – основные устройства, используемые пользователем при работе с приложениями. Поэтому среда программирования предусматривает большое количество событий
События мыши
onClick - Щелчок мыши на компоненте и некоторые другие действия пользователя. onDblClick - Двойной щелчок мыши на компоненте.
onMouseDown - Нажатие клавиши мыши на компоненте. Возможно распознавание нажатой кнопки и координат курсора мыши.
onMouseMove - Перемещение курсора мыши над компонентом. Возможнораспознавание нажатой кнопки и координат курсора мыши.
onMouseUp - Отпускание ранее нажатой мыши над компонентом. Возможно распознавание нажатой кнопки и координат курсора мыши.
onStartDrag - Начало процесса «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта.
onDragOver - Перемещение «перетаскиваемого» объекта над компонентом. Возможно распознавание перетаскиваемого объекта и координат курсора мыши.
onDragDrop - Отпускание ранее нажатой кнопки мыши после «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мыши
onEndDrag - Еще одно событие при отпускании ранее нажатой кнопки мыши после «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мыши
onEnter - Событие в момент получения элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокуса
onExit - Событие в момент потери элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокуса
Помимо параметра Sender в обработчик событий мыши передаются параметры Button, Shift, X, Y. Параметр Button типа TmouseButton определяет нажатую в этот момент кнопку мыши. Тип TmouseButton – перечислимый тип, определяемый следующим образом:
TmouseButton=(mbLeft, mbRight, mbMiddle);
Значение MbLeft – нажатие левой кнопки мыши, MbRight – правой, MbMiddle – средней.
Например, если вы хотите, чтобы обработчик реагировал на нажатие только левой кнопки мыши, можно первым оператором записать:
If (Button<>mbLeft) then exit;
Параметр Shift типа TShiftState определяет, какие вспомогательные клавиши на клавиатуре нажаты в момент нажатия мыши. Тип TshiftState – множество, определенное следующим образом:
TshiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);
Поскольку Shift является множеством, проверять наличие в нем тех или иных элементов надо операцией in. Например, если нужно прореагировать на событие, заключающееся в нажатии левой кнопки мыши при нажатой клавише Alt, можно использовать оператор:
If (Button=msLeft) and (ssAlt in Shift) then ... или If (ssLeft in Shift) ...
Аналогичные параметры Button и Shift передаются и в обработчик события OnMouseUp. Только параметр Button соответствует не нажимаемой в данный момент, а отпускаемой кнопке.
Во все события, связанные с мышью, передаются также координаты курсора X и Y . Эти параметры определяют координаты курсора в клиентской области компонента. Благодаря этому можно обеспечить различную реакцию в зависимости от того, в какой части клиентской области расположен курсор. Пусть, например, в приложении имеется компонент Image1, содержащий некоторое изображение, и нужно обеспечить пользователя соответствующими пояснениями в зависимости от того, на какую часть изображения он покажет мышью:
События клавиатуры.
В оконных компонентах Delphi (Lazarus) определены три события, связанные с клавиатурой:
onKeyDown - Событие наступает при нажатии пользователем любой клавиши. Можно распознать нажатые клавиши, включая функциональные, и кнопки мыши, но нельзя распознать символ нажатой клавиши
onKeyPress - Событие наступает при нажатии пользователем клавиши символа. Можно распознать только нажатую клавишу символа, различить символ в верхнем и
нижнем регистре, различить символы кириллицы и латинские, но нельзя распознать функциональные клавиши и кнопки.
onKeyUp - Событие наступает при отпускании пользователем любой клавиши. Можно распознать нажатые клавиши, включая функциональные, и кнопки мыши, но нельзя распознать символ отпускаемой клавиши
Кроме того, при нажатии пользователем клавиши табуляции фокус может переключаться с элемента на элемент, что вызывает события onEnter и onExit.
Последовательность событий клавиатуры при нажатии клавиш Shift-н:
Действия пользователя |
Событие |
|
Нажатие клавиши Shift |
OnKeyDown. - Возможно распознавание нажатой клавиши Shift |
|
Нажатие клавиши «н» |
OnKeyDown. - Возможно распознавание нажатой клавиши Shift, |
|
|
|
нажатой клавиши «н», но отличить верхний регистр от нижнего |
|
|
и латинский от русского невозможно |
|
|
OnKeyPress. - Возможно распознавание символа с учетом |
|
|
регистра и языка, но невозможно распознавание нажатой |
|
|
клавиши Shift |
Отпускание |
клавиши |
OnKeyUp. - Возможно распознавание нажатой клавиши Shift, |
«н» |
|
отпущенной клавиши «н», но отличить верхний регистр от |
|
|
нижнего и латинский от русского невозможно |
Отпускание |
клавиши |
OnKeyUp - Возможно распознавание отпущенной клавиши Shift |
Shift |
|
|
Распознавание нажатых клавиш. |
Заголовок обработчика событий может иметь следующий вид:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Параметр Sender типа TОbject содержит указатель на компонент, в котором произошло событие. Он не требуется, если пишется обработчик события для одного конкретного компонента.
Параметр Shift представляет собой множество элементов, отражающих нажатые в это время функциональные клавиши. Только в OnKeyDown множество нажатых множество возможных элементов параметра Shift сокращено до ssShift, ssAlt, ssCtrl. Информация о нажатых клавишах мыши отсутствует.
Параметр Key определен как var, т.е. может изменяться в обработчике события. Это целое число, а не символ. Key определяет нажатую в момент события клавишу клавиатуры. Некоторые коды:
Клавиша |
Десятеричное |
Шестнадцатеричное |
Символическое имя |
Сравнение по |
|
число |
|
|
функции ord |
F1 |
112 |
$70 |
VK_F1 |
|
Enter |
13 |
$0D |
VK_RETURN |
|
Shift |
16 |
$10 |
VK_SHIFT |
|
Ctrl |
17 |
$11 |
VK_CONTROL |
|
Alt |
18 |
$12 |
VK_MENU |
|
Esc |
27 |
$1B |
VK_ESCAPE |
|
0 ) |
48 |
$30 |
|
Ord(‘0’) |
1 ! |
49 |
$31 |
|
Ord(‘1’) |
N n Т т |
78 |
$4E |
|
Ord(‘N’) |
Y y Н н |
89 |
$59 |
|
Ord(‘Y’) |
Параметр Key является целым числом, определяющим клавишу, а не символ. Реакцию на нажатие клавиши Enter можно проверить так:
If (Key= VK_RETURN) then ...
Для клавиш символов и цифр можно воспользоваться функцией ord , определяющей код символа. Коды латинских символов в верхнем регистре совпадают с виртуальными кодами, используемыми в параметре Key:
If (Key= ord(‘Y’)) then ...
Пример распознавания комбинации клавиш Alt-X:
If (Key= ord(‘X’)) and (ssAlt in Shift)) then ...;
Заголовок обработчика onKeyPress :
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
Параметр Key определяет нажатую клавишу символа, имеет тип char. В данном случае в обработчик передается не виртуальный код клавиши, а символ, по которому моно определить, прописная это буква, или строчная, русская или латинская.
Пусть ответ на вопрос положителен, если пользователь ввел «Д» или «д», и отрицателен, если – «Н» или «н»:
If ((Key= ‘Д’) or (Key= ‘д’)) then ... или If (Key in [‘Н’, ‘н’]) then ... или
Реакцию на все возможные ответы обеспечивает структура case:
Case Key of
‘Д’, ‘д’: ... ; ‘Н’, ‘н’: ... ; else beep end;
Copied from: https://multiurok.ru/files/70-lazarus-obrabotka-sobytii.html