Любая программа, написанная в среде Kylix, постоянно обрабатывает какие-либо
события. Событием может быть движение мышкой, нажатие клавиши на клавиатуре
или на мышке, закрытие окна и т. д. Программисту остается лишь перехватывать
эти события и писать методы, которые будут выполняться при генерации какого-либо
события.
Событие (event) - это механизм, который связывает какое-либо системное й|юисшествие
с конкретным кодом, называемым обработчиком события (event handler).
Посмотрим простой случай, когда происходит системное событие нажатия кнопкой
мыши на форме. С точки зрения программиста, событие - это всего лишь имя, связанное
с системным событием, в нашем случае - onciick, которое связано с обработчиком
события. Например, кнопка guttoni Имеет метод OnClick. По умолчанию Kylix генерирует
обработчик события - метод Button1Click, связанный с событием Onclick. Программист
должен добавить код, который выполняется при нажатии на кнопку Buttoni внутри
метода Button1Click.
Итак, для наглядного представления процесса обработки рассмотрим простую схему
(рис. 8.16).
Рис. 8.16. Схема обработки события
Рассмотрим основные события, которые может обрабатывать компилятор Куlyх. Для
начала перечислим эти события:
ОnСhаngе
OnClick
OnDblClick
OnDragDrop
OnDragOver
OnKeyPress
OnKeyUp
OnMouseDown
OnMouseMove
OnPaint
OnEnDrag
OnEnter
OnExit
OnKeyDown
OnProgress
OnStartDrag
OnMouseUp
Рассмотрим каждое событие более подробно.
Событие OnChange наступает после изменения какого-либо графического г объекта.
Создавайте обработчик такого события для выполнения каких-либо операций, происходящих
после изменения графического объекта.
Событие OnClick какого-либо компонента наступает в случае, если пользователь
нажал и отпустил левую кнопку мыши в тот момент, когда указатель мыши находился
на компоненте. Кроме того, событие OnClick происходит в следующих случаях:
при выборе пользователем путем нажатия клавиш управления курсором элемента в
сетке (Grid), дереве (Tree), списке (List) или выпадающем списке (DropDown List);
- при нажатии пользователем клавиши <Пробел> или <Enter> в тот момент,
когда компонент (например, кнопка) был в фокусе
(Component.Focused = True);
- при нажатии пользователем клавиши <Enter> в случае, если активная форма
имеет кнопку по умолчанию;
- при нажатии пользователем клавиши <Esc> в случае, если активная форма
имеет кнопку прерывания;
- при нажатии пользователем комбинации клавиш быстрого доступа ("горячих"
клавиш) для доступа к кнопке или пункту меню. Например, в свойстве caption кнопки
формы записано &ПУСК, при этом надпись на кнопке имеет вид Пуск. В этом
случае, если пользователь нажимает комбинацию клавиш <Alt>+<n>,
происходит событие OnClick;
- при установке приложением свойства Checked переключателя RadioButton в true;
- при изменении приложением свойства Checked индикатора CheckBox;
- при вызове метода Click элемента меню приложения.
Событие Onclick возникает для формы в том случае, когда пользователь щелкнул
на любом месте формы, незанятом компонентами.
Событие OnDblclick наступает тогда, когда пользователь дважды щелкнул левой
кнопкой мыши на компоненте, причем отпустил кнопку мыши после второго щелчка
над компонентом.
Примечание
К одному и тому же компоненту нельзя написать обработчики событий OnClick и
OnDblclick, поскольку первый из них всегда перехватит первый из щелчков.
Событие OnStartDrag наступает, когда пользователь начинает перетаскивать компонент,
т. е. нажал над компонентом левую кнопку мыши и, не отпуская ее, начал смещать
курсор мыши. Событие имеет параметр Sender, который содержит наименование перетаскиваемого
компонента, или объекта перетаскивания (в случае, если компонент является компонентом
контейнерного типа).
Событие OnDragDrop компонента наступает, когда пользователь отпускает перетаскиваемый
компонент над другим компонентом. В обработчике события нужно описать, что должно
происходить в момент отпускания перетаскиваемого компонента. При этом параметр
source должен соответствовать перетаскиваемому компоненту, а параметр sender
должен соответствовать компоненту, над которым компонент будет отпущен. Кроме
того, два параметра (х и y) служат для хранения координат курсора мыши над компонентом.
Система координат в данном случае соответствует клиентской части компонента.
Событие OnDragOver компонента наступает, когда перетаскиваемый компонент пересекает
границу данного компонента и оказывается над ним. Это событие возникает все
время, пока пользователь перемещает компонент над компонентом-приемником. Как
только пользователь отпускает компонент (отпускает левую кнопку мыши), происходит
событие OnDragDrop, описанное выше. Для того чтобы определить, компоненты какого
типа принимает данный компонент, используют параметр Accept. Если компонент
может
принимать любые компоненты, можно оставить обработчик OnDragOver пустым, но
он обязательно должен присутствовать. Например:
procedure TForm1.ListBox2DragOver (Sender, Source: TObject; x, y: Integer;
State: TDragState; var Accept: Boolean);
begin.
// Данный комментарий нужен, чтобы компилятор не удалил этот пустой
// обработчик
end;
Во время перетаскивания компонента форма указателя мыши может изменяться. Для
установки этого свойства служит свойство DragCursor компонента, на который будет
переноситься другой компонент.
Приведем простой пример использования событий OnDragDrop и OnDragOver.
Для наглядного применения события OnDragDrop создадим приложение, которое позволит
пользователю перетаскивать строки одного списка в другой. Итак, расположим на
форме два списка ListBox: ListBox1 и ListBox2. Добавим строки в первый список
путем редактирования его свойства Items. Назовем строки строка 1 строка 10 (рис.
8.17).
Рис. 8.17. Пример применения событий OnDragDrop и OnDragOver
Для простоты будем перетаскивать строки из первого списка во второй. Поменяем
значение свойства DragMode спискаа ListBox1 На dmAutomatic, что обеспечит автоматическое
начало перетаскивания. Теперь для второго списка (ListBox2) напишем обработчик
события OnDragOver (листинг 8.2).
Листинг 8.2 Обработка события ОnDragOver
procedure TForm1. ListBox2DragOver (Sender, Source: TObject; x, y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := Source is TListBox;
end;
В данном обработчике мы указываем, что на компонент ListBox2 можно перетаскивать
компоненты типа TListBox. Затем в обработчике события OnDragDrop запишем следующий
код (листинг 8.3).
Листинг 8.3 Код обработки OnDragOver
procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; x, y: Integer) ;
begin
ListBox2. Items .Add (ListBox1. Items [ListBox1. Itemlndex]);
end;
Таким образом, мы добавляем выбранную строку компонента компонент ListBox2.
Все! Можно запускать приложение при помощи клавиши <F9>. Попробуйте перетащить
любую строку из первого списка во второй.
Событие OnEndDrag - последнее из событий, которые предназначены для обработки
переноса одного компонента на другой. Оно наступает при любом окончании процесса
переноса, как успешного, так и неудачного (когда компонент отпущен над формой
или компонентом, неспособными его принять). Данное событие наступает в перетаскиваемом
компоненте. Это событие может применяться для реакции приложения на перетаскивание
(например, "выполнено успешно" или "неудача"). В обработчике
этого события параметр sender - это сам объект перетаскивания, а параметр Target
принимает значение компонента-приемника (при успешном перетаскивании) или значение
nil - при неудачном переносе. Приведем пример (листинг 8.4).
Листинг 8.4 Обработка события OnEndDrag
procedure TForm1.Component1EndDrag(Sender,
Target: TObject;
X, Y: integer);
begin
If Target = Nil then ShowMessage('Перенесение объекта '+
(Sender as TControl).Name +
'завершилось неудачно')
else
ShowMessage((Sender as TControl).Name +
' перенесен в '
+ (Target as TControl).Name);
end;
Добавим код, записанный в листинге 8.3, в вышеописанное приложение. При этом
код нужно поместить в обработчике события OnEndDrag для первого списка (ListBoxi).
В результате, при каждом успешном перетаскивании строки из первого списка во
второй будет выдаваться окно-сообщение (рио. 8.18), а при неудачном - окно-сообщение,
изображенное на рис. 8.19.
Событие OnEnter наступает, когда компонент получает фокус. Данное событие не
наступает при переключении между разными формами приложения или между различными
приложениями. При переключении между компонентами контейнерного типа (т. е.
между компонентами, которые могут размещать на себе другие компоненты, например
панели) событие OnEnter наступает сначала для компонента контейнерного типа,
а затем - для содержащегося в нем компонента.
Рис. 8.18. Окно, выдаваемое при успешном перетаскивании строки из ListBox1в
ListBox2
Рис. 8.19. Окно, выдаваемое при неудачном перетаскивании строки из ListBox1в
ListBox2
Событие OnExit является противоположным по отношению к OnEnter. Событие наступает
в момент, когда компонент теряет фокус, т. е. когда фокус переходит к другому
компоненту. Это событие также не наступает при переключении между разными формами
или приложениями. В отличие от события OnEnter, событие OnExit наступает сначала
для компонента, содержащегося в компоненте-контейнере, а затем - для самого
компонента контейнерного типа.
Приведем пример, иллюстрирующий события OnEnter и OnExit. Расположим форме кнопку
Button1 и группу переключателей RadioGroup1 (рис. 8.20). Добавим в группу переключателей
несколько строк (путем редактирования свойства Items).
Рис. 8.20. Пример, иллюстрирующий работу событий OnEnter и OnExit
Запустим приложение. Фокус при запуске будет передан компоненту, который был
размещен на форме первым (в нашем случае это кнопка Button1). Если теперь выбрать
щелчком мыши любой переключатель группы переключателей, то произойдет следующее:
• для кнопки Button1 наступит событие OnExit;
• для группы переключателей RadioGroupi наступит событие OnEnter;
• для выбранного переключателя из группы наступит событие OnEnter.
Если после этого выбрать щелчком мыши кнопку Button1, то события произойдут
в следующем порядке:
• для активного переключателя группы наступит событие OnExit;
• для группы переключателей наступит событие OnExit;
• для кнопки Button1 Наступит Событие OnEnter.
Событие OnKeyDown наступает, когда пользователь нажимает любую клавишу. Данное
событие происходит для компонента, имеющего фокус в момент нажатия кнопки. С
помощью данного события можно обрабатывать все клавиши, включая <Shift>,
<Alt> и <Ctrl>. В процедуру-обработчик передаются, кроме параметра
Sender, такие параметры, как Key и Shift. Параметр Key определяет нажатую клавишу.
В случае, если нажата не алфавитно-цифровая клавиша, в параметр передается виртуальный
код клавиши. Приведем таблицу кодов клавиш (табл. 8.19).
Таблица 8.19. Коды клавиш
Символическое имя клавиши | Название клавиши | Символическое имя клавиши | Название клавиши |
Key_Escape | <Esc> | Key_Period | <.> |
Key_Tab | <Tab> | Key_Slash | </> |
Key_Backtab, |
<Shift>+<Tab> | Key_0 | <0> |
Key_Backspace, Key_Backspace |
<Backspace> | Key_1 | <1> |
Key_Return | <Return> | Key_2 | <2> |
Key_Enter | <Enter> | Key_3 | <3> |
Key_lnsert | <lnsert> | Key_4 | <4> |
Key_Delete | <Delete> | Key_5 | <5> |
Key_Pause | <Pause> | Key_6 | <6> |
Key_Print | <PrintScreen> | Key_7 | <7> |
Key_SysReq | <SysRq> |
Key_8 | <8> |
Key_Home | <Home> | Key_9 | <9> |
Key_End | <End> | Key_Colon | <:> |
Key_Left | <стрелка влево> | Key_Semicolon | <;> |
Key_Up | <стрелка вверх> | Key_Less | <меньше> |
Key_Right | <стрелка вправо> | Key_Equal | <=> |
Key_Dovn | <стрелка вниз> | Key_Greater | <больше> |
Key_PageUp | <PageUp> | Key_Question | <?> |
Key_PageDown | <PageDown> | Key_At | <@> |
Key_Shift | <Shift> | Key_BracketLeft | <[> |
Key_Cpntroli | <Ctrl> | Key_Backslash | <\> |
Key_Alt | <Alt> | Key_BracketRight | <]> |
Key_CapsLock | <Caps Lock> | Key_AnsiiCircum | <^> |
Key_NumLock | <NumLock> | Key_Underscore | <_> |
Key_ScrollLock | <Scroll Lock> | Key_BraceLeft | <{> |
Key_F1 | <F1> | Key_Bar | <|> |
Key_F2 | <F2> | Key_BraceRight | <}> |
Key_F3 | <F3> | Key_AsciiTilde | <~> |
Key_F4 | <F4> | Key_paragraph | <параграф> |
Key_F5 | <F5> | Key_unknown | Неизвестная клавиша |
Key_F6 | <F6> | Key_A | <A> |
Key_F7 | <F7> | Key_B | <B> |
Key_F8 | <F8> | Key_C | <C> |
Key_F9 | <F9> | Key_D | <D> |
Key_F10 | <F10> | Key_F | <F> |
Key_F11 | <F11> | Key_G | <G> |
Key_F12 | <F12> | Key_I | <I> |
Key_Space | <пробел> | Key_J | <J> |
Key_Exclam | <!> | Key_К | <К> |
Key_NumberSign | <#> | Key_L | <L> |
Key_Dollar | <$> | Key_М | <М> |
Key_Percent | <%> | Key_N | <N> |
Key_mpersand | <&> | Key_O | <O> |
Key_Apostrophe | <'> | Key_Р | <Р> |
Key_Asterisk | <*> | Key_Q | <Q> |
Key_Plus | <+> | Key_R | <R> |
Key_Comma | <,> | ... | ... |
Key_Minus | <-> | Key_Z | <Z> |
Параметр Shift является множеством, которое может быть пустым или может содержать
следующие элементы:
ssShift - при нажатой клавише <Shift>;
ssAit - при нажатой клавише <Alt>;
ssCtri - при нажатой клавише <Ctrl>.
Приведем пример использования события OnKeyDown. Предположим, что нам необходимо
распознать, когда пользователь нажмет комбинацию клавиш <Ctrl>+<Shift>+<L>.
В обработчике события OnKeyDown напишем следующий код:
if ((Key = ord ('L')) and (ssShift in Shift) and (ssCtrl in Shift))
then ShowMessage ('Нажата комбинация клавиш <Ctrl>+<Shift>+<L>');
В вышеприведенном примере мы использовали функцию ord (), которая позволяет
по символу клавиши получить код клавиши (в нашем случае, код Клавиши <L>).
Теперь всякий раз, когда фокус будет у компонента, к которому привязан данный
обработчик, и как только пользователь нажмет комбинацию клавиш <Ctrl>+<Shift>+<L>,
будет выводиться окно (рис. 8.21).
Рис. 8.21. Окно, появляющееся при обработке события OnKeyDown
Событие OnKeyPress наступает при нажатии пользователем символьной клавиши. Данное
событие имеет параметр Key, который содержит символ нажатой клавиши и имеет
тип char. При этом различаются символы .верхнего и нижнего регистров, а также
раскладка клавиатуры.
Примечание
С помощью данного события невозможно обработать нажатие функциональных клавиш
и клавиш <Shift>, <Ctrl> или <Alt>. Таким образом, когда вы
нажмете комбинацию клавиш <Shift>+<b>, в параметр Key события OnKeyPress
поступит значение "В" - клавиша <Shift> только поменяет регистр
символа. При нажатии комбинации клавиш <АК>+<любая символьная клавиша>
событие OnKeyPress не наступает. При нажатой комбинации клавиш <Ctrl>+<любая
символьная клавиша> событие OnKeyPress наступает, но в параметр Key ничего
не передается.
Событие OnkeyUp наступает при отпускании пользователем любой ранее нажатой клавиши.
Данное событие позволяет обрабатывать все клавиши, и событие OnKeyDown. По своим
параметрам и поведению событие ikeyup равносильно событию OnKeyDown.
ытие OnMouseDown наступает при нажатии пользователем любой опки мыши в тот момент,
когда указатель мыши находится над компонентом. Данное событие имеет параметры
Button, shift, х и y. Параметр Button определяет, какая кнопка мыши нажата:
mbLeft - левая кнопка;
mbMiddle - средняя кнопка;
mbRight - правая кнопка.
Параметр Shift равносилен параметру Shift для событий, связанных с обработкой
клавиатуры. Таким образом, можно обрабатывать нажатие любой кнопки мыши одновременно
с клавишами <Shift>, <Ctrl> или <Alt>.
Параметры х и y содержат координаты указателя мыши в области компонента.
Событие OnMouseUp наступает, когда пользователь отпускает любую кноппку мыши
над компонентом. По своим функциям и параметрам данное событие аналогично событию
OnMouseDown.
Событие OnMouseMove наступает при перемещении указателя мыши над компонентом.
Данное событие возникает независимо от того, нажаты какие-либо кнопки мыши или
нет.
Примечание
При нажатой левой кнопке мыши данное событие не возникает. Эта особенность почему-то
не документирована.
Данное событие имеет следующие параметры: Shift, x и у, аналогичные вышеописанным.
Событие OnPaint наступает, когда приложение получает сообщение о необходимости
перерисовки испорченного изображения. Изображение может испортиться от перекрытия
окон одного или нескольких приложений. В обработчике данного события программист
должен разместить процедуру, выполняющую перерисовку изображения. Например,
если на форме был размещен рисунок, хранящийся в компоненте BitMap, можно для
перерисовки изображения использовать следующий обработчик события OnPaint:
Canvas.Draw (0, 0, BitMap);
Событие OnProgress наступает при прохождении медленных процессов, связанных
с изменением графического изображения. Данное событие позволяет строить индикаторы
хода выполнения процесса. Событие OnProgress имеет следующие параметры: Stage,
PercentDone, RedrawNow, R и Msg. Параметр Stage предназначен для указания стадии
прогресса (начало, продолжение, окончание) и может принимать значения psstarting
(начало), psRunning (продолжение), psEnding (окончание). Параметр PercentDone
показывает, какая часть процесса выполнена. Параметр RedrawNow показывает, может
ли в настоящий момент изображение успешно отобразиться на экране. Параметр R
служит для указания области изображения, которая изменена и требует перерисовки.
Наконец, параметр Msg служит для отображения сообщений о ходе процесса. Этот
параметр имеет строковый тип. Параметр Msg может быть пустым.