Faq обработка событий от клавиатуры


Обработка событий от клавиатуры и мыши

Читайте также:

  1. Adobe Premiere Pro, как контрольные точки. Эти точки могут использоваться для запуска событий в файлах
  2. I. Обработка SWAPом документа Word.
  3. II. Обработка SWAPом Накопителя тестовых заданий.
  4. Алгебра случайных событий
  5. Алгебра событий.
  6. Буфер клавиатуры
  7. Вакуумная обработка катода в разборной диодной лампе
  8. Ввод цифр с цифровой клавиатуры
  9. Вероятность суммы двух несовместных событий равняется сумме вероятностей этих событий.
  10. Весенняя основная обработка почвы
  11. Виды случайных событий.
  12. Восприятие и интерпретация событий

План заняття

1. Обробка подій від клавіатури та миші

2. Розпізнання витоку події, при натисканні кнопок або клавіш, координат курсора

Событие Описание
onClick Щелчок мыши на компоненте и некоторые другие действия пользователя
onDblClick Двойной щелчок мыши на компоненте
onMouseDown Нажатие клавиши мыши на компоненте. Возможно распознавание нажатой кнопки и координат курсора мыши
onMouseMove Перемещение курсора мыши над компонентом. Возможно распознавание нажатой кнопки и координат курсора мыши
onMouseUp Отпускание ранее нажатой мыши над компонентом. Возможно распознавание нажатой кнопки и координат курсора мыши
onStartDrag Начало процесса «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта
onDragOver Перемещение «перетаскиваемого» объекта над компонентом. Возможно распознавание перетаскиваемого объекта и координат курсора мыши
onDragDrop Отпускание ранее нажатой кнопки мыши после «перетаскивания» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мыши
onEndDrag Еще одно событие при отпускании ранее нажатой кнопки мыши после «перетаскивани» объекта. Возможно распознавание перетаскиваемого объекта и координат курсора мыши
onEnter Событие в момент получения элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокуса
onExit Событие в момент потери элементом фокуса в результате манипуляций мышью, нажатия клавиши табуляции или программной передачи фокуса

Событие onClick происходит, если пользователь:

Щелкнул на компоненте

Выбрал элемент в сетке, дереве, списке, выпадающем списке, нажал клавишу со стрелкой

Нажал клавишу пробела, когда кнопка или индикатор были в фокусе

Нажал клавишу Enter, а активная форма имеет кнопку по умолчанию, указанную свойством Default

Нажал клавишу Esc, а активная форма имеет кнопку прерывания, указанную свойством Cancel

Нажал клавиши быстрого доступа к кнопке или индикатору

Приложение установило в true свойство Checked радиокнопки RadioButton

Приложение изменило свойство Checked индикатора CheckBox/

Вызван метод Click элемента меню.

Для формы событие onClick наступает, если пользователь щелкнул на пустом месте формы или на недоступном компоненте.

Рассмотрим последовательности отдельных событий, наступающих при том или ином действии пользователя.

В момент запуска приложения из рассматриваемых событий наступает только событие onEnter в компоненте, на который передается фокус.

Последовательность событий мыши при переключении с помощью мыши фокуса с одного элемента на другой:

Действие пользователя Событие
Перемещение курсора мыши в пределах первого компонента Множество событий onMouseMove в первом компоненте
Перемещение курсора мыши в пределах формы Множество событий onMouseMove в форме
Перемещение курсора мыши в пределах второго компонента Множество событий onMouseMove во втором компоненте
Нажатие кнопки мыши OnExit в первом компоненте
OnEnter во втором компоненте
OnMouseDown во втором компоненте
Отпускание кнопки мыши onClick во втором компоненте
onMouseUp во втором компоненте

Последовательность событий мыши при двойном щелчке на компоненте:

Дата добавления: 2014-12-25 ; Просмотров: 218 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

KeyListener – обработка событий клавиатуры

Работая с приложением, которое имеет графический интерфейс, пользователь прибегает к помощи не только мыши, но и клавиатуры. Java Swing даёт возможность разработчику приложения обработать различные события, которые поступают от клавиатуры в то время, когда пользователь нажимает клавиши. Давайте посмотрим, что необходимо сделать, чтобы иметь возможность слушать события клавиатуры. Для этого рассмотрим интерфейс KeyListener из пакета java.awt.event.

Как в случае и с обработкой других событий, для обработки событий клавиатуры необходимо реализовать специальный интерфейс, а затем добавить получившегося слушателя к интересуемому компоненту. Интерфейс, который нужно реализовать для обработки клавиш был упомянут выше – это КeyListener из пакета java.awt.event. KeyListener имеет три метода: keyTyped, keyPressed и keyReleased.

Когда вызывается каждый из методов системой? Метод keyTyped вызывается системой каждый раз, когда пользователь нажимает на клавиатуре клавиши символы Unicode. Метод keyPressed вызывается системой в случае нажатия любой клавиши на клавиатуре. Метод keyReleased вызывается при отпускании любой клавиши на клавиатуре. Чтобы добавить слушателя KeyListener к интересуемому компоненту для прослушивания событий клавиатуры, используется метод addKeyListener. В качестве параметра методу передается ссылка на слушателя. Для удаления слушателя используется метод removeKeyListener.

Давайте посмотрим, как можно добавить слушателя KeyListener к компоненту в самом простейшем случае.

Здесь создается текстовое поле JTextField. Затем при помощи метода addKeyListener добавляется анонимный слушатель, который реализует все методы интерфейса KeyListener.
Как правило не всегда нужно реализовывать все три метода интерфейса KeyListener. Однако если мы делаем implements KeyListener, то обязаны сделать реализацию каждого метода интерфейса, даже если они будут пустыми. На такой случай есть специальный абстрактный класс KeyAdapter, который содержит все три метода но с пустыми методами keyTyped, keyPressed и keyReleased. Тогда достаточно будет пронаследоваться от KeyAdapter и переопределить в нем только требуемый метод.

Если нет необходимости реализовывать все методы KeyListener, то можно сделать вот так:

Каждый раз, когда пользователь нажимает клавиши на клавиатуре и система вызывает методы keyTyped, keyPressed и keyReleased, в качестве параметра им передается объект KeyEvent, который содержит всю необходимую информацию о произошедшем событии. Отсюда можно узнать код клавиши, которая была нажата – метод getKeyCode. Были ли зажаты при этом такие клавиши, как Alt, Shift или Ctrl. Проверить это можно вызвав соответственно методы isAltDown, isShiftDown и isControlDown. Класс KeyEvent содержит большой набор констант. Каждая константа содержит код соответствующей клавиши. Поэтому нет необходимости коды всех клавиш. Достаточно использовать какую-то из констант. По названиям констант можно легко определить, какой клавише она соответствует. Например KeyEvent. VK_ENTER или KeyEvent.VK_F.

Стоит сказать, что события от клавиатуры будут генерироваться системой только тогда, когда компонент, который мы слушаем, находится в фокусе.

Посмотрим теперь на тестовый пример.

Здесь происходит обработки нажатия клавиш компонентом JPanel. Вообще по умолчанию JPanel не должен получать фокуса, однако это можно зделать, если очень захотеть при помощи метода setFocusable и передать этому методу true в качестве параметра.

Обработка событий клавиатуры с помощью KeyListener в TextField

Иногда появляется необходимость совершить определенные действия по нажатию клавиш в поле TextField . Далее разберемся как можно обрабатывать события, которые поступают с клавиатуры.

Для начала создаем JTextField

помешаем его на панель или фрейм

Теперь нужно добавить слушатель, который будет вызываться каждый раз при вводе данных в TextField. Роль слушателя выполняет интерфейс KeyListener из пакета java.awt.event.

Интерфейс KeyListener имеет 3 метода:

— void keyPressed (KeyEvent e);

Вызывается при нажатии пользователем на любую клавишу.

— void keyReleased (KeyEvent e);

Вызывается после того, как пользователь нажмет и отпустит любую клавишу.

— void keyTyped ( KeyEvent e);

Срабатывает каждый раз, когда пользователь вводит символы Unicode. Таблица символов Unicode

Добавить интерфейс слушателя можно двумя способами:

1) реализовать этот интерфейс и все его методы;

2) расширить абстрактный класс KeyAdapter, переопределяя только необходимые методы.

Кроме того, мы можем сделать так, чтобы событие срабатывало при нажатии какой-то конкретной клавиши. Каждый символ, цифра, буква и клавиши управления на клавиатуре имеют свой код (код ключа). Добавляем проверку в любой из переопределенных методов. Например, тело метода будет выполняться только после нажатия пользователем клавиши Enter:

Далее пример небольшой реализации. Что я хочу получить ?

У меня имеется поле TextField c именем numberOfRouteTextField. Пользователь вводит количество путей. Затем, сразу после после ввода числа, появляется таблица с числом строк равным введенному числу.

Faq обработка событий от клавиатуры

Допустим, есть форма, на ней есть lable. Как сделать так, чтобы этот lable изменял свое значение в зависимости от того, какую я нажал кнопку?

Есть public enum Keys в котором каждой кнопке, присвоен номер. Вопрос, как к нему подступиться?

Пробовал вот так для кнопок нумпада:

здесь 97 — это номер кнопки 1 на доп. клавиатуре.

Данный код выводит в lable единичку, но при нажатии на любую кнопку на клавиатуре.

Кроме того, как написать единственный метод для обработки всех кнопок? Т.е, чтобы код нажатой кнопки , передавался в метод и далее c помощью if — else уже можно присвоить лейблу значение нажатой кнопки. Может как-то проще можно!?

Faq обработка событий от клавиатуры

При проектировании приложения необходимо предусмотреть удобную для пользователя последовательность фокусировки элементов.

Желательно, чтобы фокус автоматически переключался с одного компонента на другой в оптимальной последовательности при нажатии пользователем клавиши Enter после окончания работы с компонентом. Следует также предоставить пользователю возможность переключать фокус с помощью клавиши Табуляции. Очевидно, что с помощью мыши пользователь также имеет возможность переключать фокус.

Компонент формы, который в данный момент находится в фокусе, является значением (его имя) свойства формы ActiveControl . Его можно установить во время проектирования на тот компонент, который должен быть в фокусе первоначально.

В процессе выполнения это свойство меняется.

Программная возможность переключения фокуса — это использование метода SetFocus .

Например, если в какой-то момент необходимо переключить фокус на компонент Memo1 , следует вызвать этот метод Memo1.SetFocus;

Во время проектирования можно установить последовательность фокусировки с помощью Табуляции.

Последовательность табуляции задается свойством TabOrder .

Замечание. Первоначально последовательность табуляции определяется той последовательностью, в которой размещались компоненты на форме. (У первого элемента св-во = 0, у второго — 1 и т.д.). Если не задано свойство формы ActivControl , то первоначально в фокусе будет элемент, у которого TabOrder=0 .

Для задания последовательности табуляции проще всего воспользоваться командой Edit | Tab Order и в режиме диалога задать необходимую последовательность.

Для того, чтобы вывести компонент из последовательности табуляции можно использовать свойство компонента TabStop . Если TabStop=false , компоненту невозможно передать фокус с помощью клавиши Tab (мышью можно).

Следует обращать внимание на значение свойства TabStop . ( TabStop=true для компонентов, на которые должен переходить фокус при помощи клавиши табуляции)

Как реализовать переключение фокуса на другой компонент после нажатия клавиши Enter рассмотрим после того, как разберемся с событиями, возникающими при работе с мышью и клавиатурой.

Все действия пользователя при взаимодействии с приложени­ем сводятся к перемещению мыши, нажатию кнопок мыши и на­жатию клавиш клавиатуры. Поэтому важно понимать, что происходит при этих манипуляциях пользователя.

Обработка событий мыши

В компонентах Delphi определен ряд событий, связанных с мышью. Основные из них:

Щелчок мыши на компоненте и некоторые другие действия пользователя

Двойной щелчок мыши на компоненте.

Нажатие клавиши мыши над компонентом. Возмож­но распознавание нажатой кнопки и координат кур­сора мыши.

Перемещении курсора мыши над компонентом. Воз­можно распознавание нажатой кнопки и координат курсора мыши.

Отпускание ранее нажатой кнопки мыши над ком­понентом. Возможно распознавание нажатой кнопки и координат курсора мыши.

Событие в момент получения элементом фокуса в ре­зультате манипуляции мышью, нажатия клавиши табуляции или программной передачи фокуса.

Событие в момент потери элементом фокуса в резу­льтате манипуляции мышью, нажатия клавиши та­буляции или программной передачи фокуса.


Наиболее широко используется событие OnClick. Обычно оно наступает, если пользователь щелкнул на компоненте, т.е. нажал и отпустил кнопку мыши, когда указатель мыши нахо­дился на компоненте. Но это событие происходит также и при не­которых других действиях пользователя. Оно наступает, если:

• Пользователь выбрал элемент в сетке, дереве, списке, выпада­ющем списке, нажав клавишу со стрелкой.

• Пользователь нажал клавишу пробела, когда кнопка или ин­дикатор были в фокусе.

• Пользователь нажал клавишу Enter, а активная форма имеет кнопку по умолчанию, указанную свойством Default.

• Пользователь нажал клавишу Esc, а активная форма имеет кнопку прерывания, указанную свойством Cancel.

• Пользователь нажал клавиши быстрого доступа к кнопке или индикатору. Например, если свойство Caption индикатора за­писано как ‘&Попужирный’ и символ ‘П’ подчеркнут, то нажа­тие пользователем комбинации клавиш Alt+П вызовет событие OnClick в этом индикаторе.

• Приложение установило в true свойство Checked радиокноп­ки RadioButton.

• Приложение изменило свойсто Checked индикатора Check-Box.

• Вызван метод Click элемента меню.

Для формы событие OnClick наступает, если пользователь щелкнул на пустом месте формы или на недоступном компонен­те.

Необходимо четко представлять последовательность отдельных событий, наступающих при том или ином действии пользователя. Рассмотрим эти последователь­ности.

Каждое действие пользо­вателя, связанное с нажатием или отпусканием кнопки мыши, приводит к серии последовательно наступающих событий.

Например, рассмотрим простейшее действие пользователя: пере­ключение с помощью мыши фокуса с одного элемента на другой. Последовательность событий мыши в этом случае приведена в табли­це

Перемещение курсора мыши в пределах первого компонента

Множество событий OnMouseMove в первом компоненте

Перемещение курсора мыши в пределах формы

Множество событий OnMouseMove в форме

Перемещение курсора мыши в пределах второго компонента

Множество событий OnMouseMove во втором компоненте

Нажатие кнопки мыши

OnExit в первом компоненте

OnEnter во втором компоненте

OnMouseDown во втором компоненте

Отпускание кнопки мыши

OnClick во втором компоненте

OnMouseUp во втором компоненте

События OnMouseMove происходят постоянно в процессе пе­ремещения курсора мыши и даже просто при его дрожании, не­избежном, если пользователь не снимает руки с мыши. Это надо учитывать, и пользоваться этим событием очень осторожно, по­скольку оно, в отличие от других, происходит многократно.

В об­работчиках событий OnMouseDown и OnMouseUp можно распо­знать, какая кнопка мыши нажата и в какой точке компонента находится в данный момент курсор мыши.

Если щелчок делается на объекте, который уже находится в этот момент в фокусе, то не происходят события OnExit и OnEnter. В этом случае при нажа­тии кнопки наступает только событие OnMouseDown, а при отпу­скании кнопки — события OnClick и OnMouseUp.

Теперь рассмотрим последовательность событий при двойном щелчке на компоненте.

Первое нажатие кнопки мыши

OnMouseDown. Возможно распознавание на­жатой кнопки и координат курсора мыши

Первое отпускание кнопки мыши

OnMouseUp. Возможно распознавание нажа­той кнопки и координат курсора мьгпГи

Второе нажатие кнопки мыши

OnMouseDown. Возможно распознавание на­жатой кнопки и координат курсора мыши

Второе отпускание кнопки мыши

OnMouseUp. Возможно распознавание нажа­той кнопки и координат курсора мыши.

Распозна­вать нажатую кнопку мыши по-прежнему можно только в собы­тиях OnMouseDown и OnMouseUp. Если же надо распознать именно двойной щелчок какой-то определенной кнопкой мыши, то можно, например, ввести некую переменную, являющуюся флагом двойного щелчка, устанавливать этот флаг в обработчике события OnDblClick, а в обработчиках событий OnMouseDown или OnMouseUp проверять этот флаг и, если он установлен, то сбрасывать его и выполнять запланированные действия.

Распознавание источника события,

нажатых кнопок и клавиш, координат курсора

Распознавание источника события

Во все обработчики событий, связанных с манипуляциями мыши (как и во все другие обработчики), передается параметр Sender типа TObject. Этот параметр содержит указатель на ком­понент, в котором произошло событие. Он не требуется, если пишется обработчик события для одного конкретного компонента. Однако часто один обработчик применяется для нескольких ком­понентов. При этом какие-то операции могут быть общими для любых источников события, а какие-то требовать специфических действий. Тогда Sender можно использовать для распознавания источника события. Правда, поскольку тип TObject не имеет ни­каких полезных для пользователя свойств и методов, то объект Sender следует рассматривать как объект одного из производных от TObject типов.

Если необходимо распознать только тип объекта, можно использовать операцию is.

Например if (Sender is TListBox) then . . .

так можно проверить, является ли источник события компонентом типа TListBox.

Если требуется распознать объект по имени или другому свой­ству, можно использовать операцию as.

Например, if (Sender as TControl).Name = ‘Edit 1 ‘ then .

так можно проверить, является ли этот компонент компонентом с именем Edit1.

В данном случае можно было бы просто опреде­лить, не является ли Sender объектом Edit1:

if (Sender = Edit 1 ) then .

Операцию as можно также использовать, если надо приме­нить к источнику события некоторый метод.

Например, оператор (Sender as TWinControl) . ScaleBy (11,10) ;

увеличивает на 10% размер любого оконного компонента, в кото­ром произошло обрабатываемое событие.

Илон Маск рекомендует:  Что такое код ncurses_noecho

Распознавание нажатых кнопок

Помимо параметра Sender в обработчики событий OnMouseDown и OnMouseUp передаются параметры, позволяющие распо­знать нажатую кнопку, нажатые при этом вспомогательные кла­виши, а также определить координаты курсора мыши. Заголовок обработчика события OnMouseDown или OnMouseUp может иметь, например, следующий вид:

procedure TForm 1 .Edit 1 MouseDown (Sender : TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

Параметр Button определяет нажатую в этот момент кнопку мыши.

Тип TMouseButton — перечислимый тип, определяемый следующим образом:

TMouseButton = (mbLeft, mbRight, mbMiddle) ;

mbLeft — нажатие левой кнопки мыши, mbRight — правой, а mbMiddle — средней.

Например, если необходимо, чтобы обработчик реагировал на на­жатие только левой кнопки, можно написать: if (Button <> mbLeft) then exit;

Параметр Shift определяет, какие вспомога­тельные клавиши на клавиатуре нажаты в момент нажатия кнопки мыши.

Тип TShiftState — множество, определенное сле­дующим образом:

TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble) ;

Элементы этого множества соответствуют нажатию клавиш Shift (ssShift), Alt (ssAlt), Ctrl (ssCtrl), а также кнопок: левой (ssLeft), правой (ssRight), средней (ssMiddle).

Информация о на­жатых кнопках в параметрах Button и Shift имеет различный смысл.

Параметр Button соответствует кнопке, нажимаемой в данный момент, а параметр Shift содержит информацию о том, какие кнопки были нажаты, включая и те, которые были нажаты ранее.

Например, если пользователь нажмет левую кнопку мыши, а затем, не отпуская ее, нажмет правую, то после первого нажатия множество Shift будет равно [ssLeft], а после второго — [ssLeft, ssRight]. Если до этого пользователь нажал и не отпус­тил какие-то вспомогательные клавиши, то информация о них также будет присутствовать в множестве Shift.

Так как Shift является множеством, проверять наличие в нем тех или иных элементов надо операцией in.

Например, если необходимо прореагировать на событие, заключающееся в нажа­тии левой кнопки мыши при нажатой клавише Alt, можно испо­льзовать оператор:

if (Button = mbLeft) and (ssAlt in Shift) then .

Замечание. Здесь условие (Button = mbLeft) можно заменить эквивалентным ему условием

if (ssLeft in Shift) .

Аналогичные параметры Button и Shift передаются и в обра­ботчик события OnMouseUp. Отличие только в том, что параметр Button соответствует не нажимаемой в данный момент, а отпус­каемой кнопке. Параметр Shift передается также в обработчик события OnMouseMove, так что и в этом обработчике можно определить, какие клавиши и кнопки нажаты.

Распознавание координат курсора

Во все события, связанные с мышью, передаются также коор­динаты курсора Х и Y.

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

В событие OnMouseDown компонента (формы) можно ввести обработчик, в котором можно анализи­ровать координаты курсора, например

В оконных компонентах Delphi определены три события, свя­занные с клавиатурой.

OnKeyDown — наступает при нажатии пользователем любой клавиши.

Можно распознать нажатые клавиши, вклю­чая функциональные, и кнопки мыши, но нельзя рас­познать символ нажатой клавиши

OnKeyPress — наступает при нажатии пользователем клави­ши символа.


Можно распознать нажатую клавишу символа, различить символ в верхнем и нижнем реги­стре, различить символы кириллицы и латинские, но нельзя распознать функциональные клавиши и кноп­ки

OnKeyUp — наступает при отпускании пользователем лю­бой клавиши.

Можно распознать нажатые клавиши, включая функциональные, и кнопки мыши, но нельзя распознать символ отпускаемой клавиши

Кроме того, при нажатии пользователем клавиши табуляции фокус может переключаться с элемента на элемент, что вызывает события OnEnter и OnExit.

Важно четко представлять последовательность событий, про­исходящих при нажатии пользователем клавиши или комбина­ции клавиш.

Пусть, например, пользователь нажал клавишу Shift (перевел ввод в верхний регистр), а затем нажал клавишу симво­ла “н”. Последовательность событий для этого случая приведена в таблице.

Нажатие клавиши Shift

OnKeyDown. Возможно распознавание нажатой клавиши Shift

Нажатие клавиши “н”

OnKeyDown. Возможно распознавание нажатой клавиши Shift, нажатой клави­ши “н”, но отличить верхний регистр от нижнего и латинский символ от русско­го невозможно

ОпКеу Press. Возможно распознавание символа с учетом регистра и языка, но невозможно распознавание нажатой кла­виши Shift

Отпускание клавиши “н”

OnKeyUp. Возможно распознавание на­жатой клавиши Shift, отпущенной клави­ши “н”, но отличить верхний регистр от нижнего и латинский символ от русско­го невозможно

Отпускание клавиши Shift

OnKeyUp. Возможно распознавание от­пущенной клавиши Shift

Замечание. Событие OnKeyPress заведомо наступа­ет, если нажимается только клавиша символа или клавиша сим­вола при нажатой клавише Shift. Если же клавиша символа нажи­мается одновременно с какой-то из вспомогательных клавиш, то событие OnKeyPress может не наступить (произойдут только со­бытия OnKeyDown при нажатии и OnKeyUp при отпускании) или, если и наступит, то укажет на неверный символ. Например, при нажатой клавише Alt событие OnKeyPress при нажатии сим­вольной клавиши не наступает. А при нажатой клавише Ctrl со­бытие OnKeyPress при нажатии символьной клавиши наступает, но символ не распознается.

Куда поступают события клавиатуры?

У формы имеется свойство KeyPreview. Оно влияет на обработку событий, поступающих от клавиатуры число этих событий не входит нажатие клавиш со стрелками, клавиш табуляции и т.п.). По умолчанию свойство KeyPreview = false и события клавиатуры поступают на обработчики, предусмотренные в активном в данный момент компоненте. Но если задать значение KeyPreview = true, то сначала эти со­бытия будут поступать на обработчики формы, если таковые предусмотрены, и только потом поступят на обработчики активного компонента.

Распознавание нажатых клавиш

Заголовок обработчика события OnKeyDown может иметь, на­пример, следующий вид:

procedure TForm 1 .Edit 1 KeyDown (Sender : TObject; var Key: Word; Shift: TShiftState) ;

Параметр Sender указывает на источник события

Параметр Shift, представляет множество элементов, отражающих нажатые в это время функциональные клавиши.

Здесь множество возможных элементов параметра Shift сокращено до ssShift (нажата клавиша Shift), ssAlt (нажата клавиша Alt) и ssCtrl (нажата клавиша Ctrl). Информация о нажатых кнопках мыши отсутствует.

Основной параметр — параметр Key.

Обратите внимание, что он определен как var, т.е. может изменяться в обработчике события. Обратите внимание, что это целое число, а не символ.

Параметр Key определяет нажатую в момент события клавишу клавиатуры.

Полную таблицу этих кодов можно посмотреть во встроенной справке Delphi. Ниже приведены для дальнейшего обсуждения только несколько строк из нее, соответствующих наиболее распространенным клавишам.

Обработка событий клавиатуры и мыши

При использовании библиотеки GLAUX предполагается, что программа разработана в соответствии с некоторой структурой-макетом: сначала создается окно приложения, затем устанавливаются параметры OpenGL, регистрируются функции обратной связи и запускается функция главного цикла. Макет консольного приложения был приведен в предыдущей лекции (п.3) и с тех пор он используется во всех рассматриваемых примерах. Функции обратной связи реализуются программистом, а вызываются изнутри GLAUX. Большую часть времени программа проводит в главном цикле внутри функции auxMainLoop():

void auxMainLoop( void (CALLBACK* display)(void) )

вызвать функцию реакции на изменение размеров окна;

вызвать функцию рисования сцены display();

while ( не закрыто окно приложения )

if ( изменен размер окна )

вызвать функцию реакции на изменение размера окна;

if ( нажата клавиша )

вызвать функцию обработки этой клавиши;

if ( нажата кнопка мыши )

вызвать функцию обработки этой кнопки;

if ( было перемещение мыши при нажатой кнопке )

вызвать функцию обработки перемещения мыши;

вызвать фоновую функцию;

Т.о., из главного цикла GLAUX могут вызываться функции обратной связи, в которых программист определил реакцию на некоторые внешние события. Эти функции обычно называются обработчиками событий. Чтобы GLAUX вызывала их, обработчики надо зарегистрировать до входа в главный цикл.

Обработчик события от клавиатуры должен соответствовать прототипу:

void CALLBACK FunctionName(void);

где FunctionName – произвольное имя, выбираемое программистом.

Для регистрации функции FunctionName() в качестве обработчика нажатия кнопки клавиатуры служит функция:

void auxKeyFunc(int keyCode, void (CALLBACK* FunctionName)(void));

где keyCode – код клавиши (соответствующие константы хранятся в файле glaux.h, например, AUX_ESCAPE и AUX_A).

Прототип обработчика событий мыши отличается от клавиатурного обработчика:

void CALLBACK FunctionName(AUX_EVENTREC* event);

При вызове обработчика GLAUX передает ему информацию о произошедшем событии в параметре event типа AUX_EVENTREC. Эта структура имеет вид:

GLint event; // Тип события: AUX_MOUSEDOWN, AUX_MOUSEUP,

GLint data[4]; // [0] горизонтальная координата мыши

// [1] вертикальная координата мыши

// [2] не используется

// [3] код нажатой кнопки (AUX_LEFTBUTTON,

// AUX_MIDDLEBUTTON или AUX_RIGHTBUTTON)

Для регистрации обработчика события от мыши надо использовать функцию:

void auxMouseFunc( int button, int action,

void (CALLBACK* FunctionName)(AUX_EVENTREC*) );

Параметр button задает кнопку, с которой связано событие: AUX_LEFTBUTTON (левая), AUX_MIDDLEBUTTON (средняя), AUX_RIGHTBUTTON (правая).

Параметр action задает тип события: AUX_MOUSEDOWN (нажатие кнопки), AUX_MOUSEUP (отпускание кнопки), AUX_MOUSELOC (перемещение мыши при нажатой кнопке).

Пример обработки события от мыши: изменение цвета вращающегося объекта по нажатию левой кнопки мыши

Перечислим изменения, которые необходимо внести в программу 2.1, чтобы по нажатию левой кнопки мыши цвет вращающегося чайника циклически изменялся в следующей последовательности: желтый, красный, зеленый, синий.

1) Надо добавить в программу описание глобальной переменной, в который будет храниться порядковый номер текущего цвета (0/1/2/3 – желтый/красный/зеленый/синий):

int clr_number = 0;

2) Значение переменной clr_number надо учесть в функции рисования трехмерной сцены, чтобы перед рисованием чайника устанавливался соответствующий цвет:

case 0 : glColor3f( 0.5, 0.5, 0 ); break;

case 1 : glColor3f( 1, 0, 0 ); break;

case 2 : glColor3f( 0, 1, 0 ); break;

case 3 : glColor3f( 0, 0, 1 ); break;

default : glColor3f( 1, 1, 1 ); break;

3) В раздел прототипов надо внести прототип обработчика события от мыши:

void CALLBACK mouse_leftbtn( AUX_EVENTREC* event );

4) В функции-обработчике выполняется изменение номера текущего цвета:

void CALLBACK mouse_leftbtn( AUX_EVENTREC* event )

if ( ++clr_number == 3 )

5) Перед входом в главный цикл GLAUX надо зарегистрировать обработчик события «нажатие левой кнопки мыши»:

auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEDOWN, mouse_leftbtn );

Композиция нескольких преобразований

Для генерации анимационных изображений объектов, движущихся относительно друг друга, часто бывает удобно применять последовательность нескольких преобразований, параметры которых определяются текущим положением объектов. В данном параграфе показывается применение композиции нескольких преобразований для двух моделей: для простейшей модели солнечной системы (несколько объектов вращаются вокруг собственных осей и по орбитам вокруг солнца) и для модели манипулятора робота (при отображении манипулятора требуется выполнять преобразование координатных систем отдельных сегментов).

Модель солнечной системы


Рассмотрим простейшую модель солнечной системы, которая состоит из солнца и одной планеты, движущейся по круговой орбите. Планета совершает полный оборот по орбите за 365 дней, а оборот вокруг своей оси за 24 часа.

Оба тела рисуются в виде каркасных сфер, для отображения сцены применяется перспективная проекция (функция gluPerspective()).

Угловое движение планеты по орбите и вокруг собственной оси учитывается с помощью функции glRotated(). Для размещения планеты на орбите применяется функция glTranslated().

Центр сферы, изображающей солнце, находится в начале координат. Вращение солнца вокруг собственной оси не показывается (хотя это легко сделать с помощью функции glRotated()). Для рисования планеты, обращающейся вокруг солнца (рис. 2.1), требуется выполнить несколько модельных преобразований.

Рис. 2.1.Движение планеты по орбите и вокруг своей оси.

Для определения порядка модельных преобразований надо представить, что должно происходить с модельной системой координат. Сначала модельная система координат совпадает с мировой. В этом состоянии надо функцией glRotated() повернуть модельную систему координат относительно мировой системы на угол, соответствующий текущему положению планеты на орбите. Затем glTranslated() выполняет перенос модельной системы координат по радиусу орбиты. После этого выполняется еще один вызов glRotated(), поворачивающий модельную систему координат вокруг оси вращения планеты в соответствии с временем суток на планете. После выполнения всех трех преобразований, можно нарисовать планету.

Описанные преобразования выполняются в программе 2.2. Фоновой функции в этой программе нет, поэтому изменение времени производится клавишами курсора: увеличение/уменьшение времени суток с помощью стрелок вверх/вниз (на 1 час), дней – с помощью стрелок вправо/влево (на 1 день).

void CALLBACK resize( int width, int height );

void CALLBACK display();

void CALLBACK dayAdd();

void CALLBACK daySubtract();

void CALLBACK hourAdd();

void CALLBACK hourSubtract();

// Счетчики дней и часов

int day_cnt = 0, hour_cnt = 0;

// Создание экранного окна

auxInitDisplayMode( AUX_RGBA | AUX_DEPTH | AUX_DOUBLE );

auxInitPosition( 50, 10, 400, 400);

auxInitWindow( «Лекция 2, Программа 2.2» );

// Включение ряда параметров OpenGL

glEnable( GL_ALPHA_TEST ); // Учет прозрачности

glEnable( GL_DEPTH_TEST ); // Удаление невидимых поверхностей

glEnable( GL_BLEND ); // Разрешение смешения цветов

glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

glEnable( GL_LIGHTING ); // Учет освещения

glEnable( GL_LIGHT0 ); // Включение нулевого источника света

// Задание положения и направления нулевого источника света

glLightfv( GL_LIGHT0, GL_POSITION, pos );

glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, dir );

// Регистрация обработчиков событий

auxKeyFunc( AUX_LEFT, daySubtract );

auxKeyFunc( AUX_RIGHT, dayAdd );

auxKeyFunc( AUX_UP, hourAdd );

auxKeyFunc( AUX_DOWN, hourSubtract );

// Вход в главный цикл GLAUX

void CALLBACK resize( int width, int height )

glViewport( 0, 0, width, height );

gluPerspective( 60.0, (float)width/(float)height, 1.0, 20.0 );

gluLookAt( 0,0,5, 0,0,0, 0,1,0 );

void CALLBACK display(void)

// Очистка буфера кадра

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glColor3f( 1.0, 1.0, 1.0 );

auxWireSphere( 1.0 ); // Солнце

glRotated( (double)day_cnt*360.0/365.0, 0.0, 1.0, 0.0 );

glTranslated( 2.0, 0.0, 0.0 );

glRotated( (double)hour_cnt*360.0/24.0, 0.0, 1.0, 0.0 );

auxWireSphere( 0.2 ); // Планета

// Копирование содержимого буфера кадра на экран

void CALLBACK dayAdd()

day_cnt = (day_cnt + 1) % 360;

void CALLBACK daySubtract()

day_cnt = (day_cnt — 1) % 360;

void CALLBACK hourAdd()

hour_cnt = (hour_cnt + 1) % 24;

void CALLBACK hourSubtract()

hour_cnt = (hour_cnt — 1) % 24;

Программа 2.2.Модель солнечной системы.

Обработка событий

Некоторые программы с применением JavaScript event работают напрямую с вводимыми пользователем данными. Момент возникновения и порядок таких взаимодействий не могут быть предсказаны заранее.

Обработчики событий

Реагировать на нажатие клавиши можно, постоянно считывая ее состояние, чтобы поймать момент нажатия клавиши, прежде чем она снова не будет отпущена.

Именно так обрабатывался ввод данных на примитивных машинах. Более прогрессивным является определение нажатия клавиши и его постановка в очередь. Затем программа может периодически проверять очередь новых событий и реагировать на то, что там находит. В таком случае программа должна не забывать просматривать очередь и делать это часто.

В период от нажатия клавиши и до обнаружения программой этого события, она фактически не отвечает на запросы. Такой подход называется поллингом ( опросом ).

Большинство программистов стараются избегать его, если это возможно.

Самым лучшим способом считается реализация системы, которая дает коду возможность реагировать на события, когда они происходят. Браузеры реализуют ее, предоставляя возможность регистрировать функции обработчиков для конкретных JavaScript event :

Функция addEventListener регистрируется таким образом, что ее второй аргумент вызывается всякий раз, когда происходит событие, описанное первым аргументом.

События и узлы DOM

Каждый обработчик событий браузера регистрируется в контексте. При вызове функции addEventListener она вызывается как метод для всего окна, так как в браузере глобальный диапазон эквивалентен объекту window . Каждый элемент DOM имеет свой собственный метод addEventListener , который позволяет отслеживать события именно в этом элементе:

В данном примере обработчик подключен к узлу кнопки. JavaScript mouse events приводит в действие обработчик, а клик в остальной части документа — нет.

Установив для узла атрибут onclick , мы получим тот же результат. Но узел имеет только один атрибут onclick , поэтому можно зарегистрировать для каждого узла только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков. Так мы застрахованы от случайной замены обработчика, который уже был зарегистрирован.

Метод removeEventListener , вызывается с аргументами, аналогичными addEventListener . Он удаляет обработчик:

Чтобы отменить функцию обработчика, мы задаем для нее имя ( например, once ). Так мы передаем ее как в addEventListener , так и в removeEventListener .

Объекты событий

Хотя мы не упоминали об этом в приведенных выше примерах, в функции обработчиков JavaScript event передается аргумент: объект события. Он предоставляет дополнительную информацию о событии. Например, если мы хотим знать, какая клавиша мыши была нажата, нужно получить значение свойства объекта события which :

Информация, хранящаяся в объекте, различается зависимости от типа события. Свойство объекта type всегда содержит строку, идентифицирующую событие (например, « click » или « mousedown «).

Распространение

Обработчики событий ( например, JavaScript touch events ), зарегистрированные для родительских узлов, также будут принимать события, которые происходят в дочерних элементах. Если была нажата кнопка, находящаяся внутри абзаца, обработчики событий абзаца также получат событие click .

Событие распространяется от узла, в котором оно произошло, в родительский узел и в корень документа. После того, как все обработчики, зарегистрированные в конкретном узле, вступили в действие по очереди, возможность реагировать на событие получают обработчики, зарегистрированные для всего окна.

Илон Маск рекомендует:  Пять вещей, которые надо знать об HTML5

В любой момент обработчик события может вызвать для объекта события метод stopPropagation , чтобы предотвратить распространение события дальше. Это может быть полезно, когда у вас есть кнопка внутри другого интерактивного элемента, и вы не хотите, чтобы при нажатии кнопки активировалось поведение, заданное для клика мышью по внешним элементам.

В следующем примере мы регистрируем обработчики « MouseDown » как для кнопки, так и для абзаца. При клике правой клавишей ( JavaScript mouse events ) обработчик вызывает метод stopPropagation , который предотвращает запуск обработчика абзаца. При нажатии на кнопку другой клавишей мыши запускаются оба обработчика:

Большинство объектов событий имеют свойство target , которое указывает на узел, в котором они возникли. Вы можете использовать это свойство, чтобы случайно не обрабатывать какое-то событие, которое распространяется вверх из узла.

Также можно использовать JavaScript event target , чтобы расширить диапазон события определенного типа. Например, если у вас есть узел, содержащий длинный список кнопок, более удобно зарегистрировать один обработчик клика для внешнего узла и использовать свойство target , чтобы отслеживать, была ли нажата кнопка, а не регистрировать экземпляры обработчика для всех кнопок:

Действия по умолчанию


Со многими событиями связаны действия по умолчанию. Если вы нажмете на ссылку, то перейдете к целевому элементу ссылки. Если нажмете стрелку вниз, браузер прокрутит страницу вниз. Если вы кликните правой клавишей мыши, откроется контекстное меню.

Для большинства типов событий обработчики JavaScript event вызываются до выполнения действий по умолчанию. Если не нужно, чтобы выполнялось поведение по умолчанию, нужно вызвать для объекта события метод preventDefault .

Его использовать для реализации пользовательских сочетаний клавиш или контекстных меню. Или, чтобы переопределить поведение, которое ожидают пользователи. Ниже приводится ссылка, по которой нельзя перейти:

Старайтесь не делать так, если у вас нет на это веских причин.

В зависимости от браузера некоторые события не могут быть перехвачены. В Google Chrome , например, сочетание клавиш ( event keycode JavaScript ) для закрытия текущей вкладки ( Ctrl-W или Command-W ) не может быть обработано с помощью JavaScript .

События клавиш

Когда пользователь нажимает клавишу на клавиатуре, браузер запускает событие « keydown «. Когда он отпускает клавишу, срабатывает событие « keyup «:

Также это событие срабатывает, когда пользователь нажимает и удерживает клавишу, или пока клавиша удерживается. Например, если требуется увеличить скорость персонажа в игре, нажав на клавишу со стрелкой, и снова уменьшить ее, отпустив клавишу, то нужно быть осторожным, чтобы не увеличивать скорость каждый раз, пока клавиша нажата.

В предыдущем примере использовано свойство объекта event keycode JavaScript . С его помощью определяется, какая именно клавиша была нажата или отпущена. Ноне всегда очевидно, как привести числовой код клавиши к фактической клавише.

Для считывания значений клавиш букв и цифр используется код символа Unicode . Он связан с буквой ( в верхнем регистре ) или цифрой, обозначенной на клавише. Метод charCodeAt для строк позволяет получить это значение:

С другими клавишами связаны менее предсказуемые коды клавиш. Лучший способ определить нужный код, это поэкспериментировать. Зарегистрировать обработчик события нажатия клавиши, который фиксирует коды клавиш, которые он получает, и нажать нужную клавишу.

Такие клавиши, как Shift , Ctrl , Alt порождают события, как обычные клавиши. Но при отслеживании комбинаций клавиш также можно определить, нажаты ли эти клавиши, по свойствам событий клавиатуры и JavaScript mouse events : shiftKey , ctrlKey , altKey и metaKey :

События « keydown » и « keyup » предоставляют информацию о фактическом нажатии клавиш. Но что, если нам нужен сам вводимый текст? Получать текст из кодов клавиш неудобно. Для этого существует событие, « keypress «, которое срабатывает сразу после « keydown «. Оно повторяется вместе с « keydown «, пока клавиша нажата. Но только для клавиш, с помощью которых производится ввод символов.

Свойство charCode в объекте события содержит код, который может быть интерпретирован, как код символа Unicode . Мы можем использовать функцию String.fromCharCode , чтобы преобразовать этот код в строку из одного символа.

Узел DOM , в котором происходит событие зависит, от того элемента, который находился в фокусе ввода при нажатии клавиши. Обычные узлы не могут находиться в фокусе ввода ( если не установить для них атрибут tabindex ), но такие элементы, как ссылки, кнопки и поля формы, могут.

Если никакой конкретный элемент не выделен фокусом ввода, то в качестве целевого узла для событий клавиши и JavaScript touch events выступает document.body .

Клики мыши

Нажатие клавиши мыши также приводит в действие ряд событий. События « mousedown » и « mouseup » похожи на « keydown » и « keyup «. Они запускаются, когда нажата и отпущена клавиша мыши. Данные события возникают в узлах DOM, на которые был наведен указатель мыши, когда возникло событие.

Для общего узла, к которому относилось как нажатие, так и освобождение клавиши мыши, после события « mouseup » запускается событие « click «. Например, если нажать клавишу мыши на одном пункте, а затем переместить курсор на другой пункт и отпустить кнопку, то событие « click » будет происходить в элементе, который содержит оба эти пункта.

Если два клика возникли близко друг к другу, также запускается событие « dblclick » ( двойной клик ). Оно возникает после второго клика. Чтобы получить точную информацию о месте, где произошло событие мыши, нужно получить значение свойств pageX и pageY , которые содержат координаты события ( в пикселях ) относительно левого верхнего угла документа.

Ниже приведена реализация примитивной программы для рисования. Каждый раз при нажатии мыши в документе ( под курсором ) добавляется точка:

Свойства clientX и clientY подобны pageX и pageY , но они относятся к видимой части документа. Они могут использоваться для сравнения координат мыши с координатами, возвращаемыми функцией getBoundingClientRect .

Движение мыши

Каждый раз, когда перемещается курсов мыши, срабатывает событие « mousemove » из набора JavaScript mouse events . Оно может быть использовано для отслеживания положения мыши. Это применяется при реализации возможности перетаскивания элементов мышью.

В следующем примере программа выводит на экран панель и устанавливает обработчики событий таким образом, что при перетаскивании эта панель становится уже или шире:

Обратите внимание, что обработчик « mousemove » зарегистрирован для всего окна. Даже если во время изменения размеров мышь выходит за пределы панели, мы все равно обновляем ширину панели и прекращаем JavaScript touch events , когда клавиша мыши была отпущена.

Мы должны прекратить изменение размера панели, когда пользователь отпускает клавишу мыши. К сожалению, не все браузеры устанавливают для событий « mousemove » свойство which . Существует стандартное свойство buttons , которое предоставляет аналогичную информацию, но оно также поддерживается не во всех браузерах. К счастью, все основные браузеры поддерживают что-то одно: либо buttons , либо which . Функция buttonPressed в приведенном выше примере сначала пытается использовать свойство buttons , и, если оно не доступно, переходит к which .

Когда курсор мыши наводится или покидает узел, запускаются события « mouseover » или « mouseout «. Они могут использоваться для создания эффектов при наведении курсора мыши, вывода какой-нибудь подписи или изменения стиля элемента.

Чтобы создать такой эффект, недостаточно просто начать его отображение при возникновении события « mouseover » и завершить после события « mouseout «. Когда мышь перемещается от узла к одному из его дочерних элементов, для родительского узла происходит событие « mouseout «. Хотя указатель мыши не покинул диапазон распространения узла.

Что еще хуже, эти JavaScript event распространяются так же, как и другие события. Когда мышь покидает один из дочерних узлов, для которого зарегистрирован обработчик, возникнет событие « mouseout «.

Чтобы обойти эту проблему, можно использовать свойство объекта события relatedTarget . В случае возникновения события « mouseover » оно указывает, на какой элемент был наведен курсор мыши до этого. А в случае возникновения « mouseout » — к какому элементу перемещается указатель. Мы будем изменять эффект наведения мыши только, когда relatedTarget находится вне нашего целевого узла.

В этом случае мы изменяем поведение, потому что курсор мыши был наведен на узел из-за его пределов ( или наоборот ):

Функция isInside отслеживает родительские связи заданного узла или пока не будет достигнута верхняя часть документа ( когда node равен нулю ). Либо не будет найден родительский элемент, который нам нужен.

Эффект наведения гораздо проще создать с помощью псевдоселектора CSS :hover , как показано в следующем примере. Но когда эффект наведения предполагает что-то более сложное, чем просто изменение стиля целевого узла, тогда нужно использовать прием с использованием событий « mouseover » и « mouseout » ( JavaScript mouse events ):

События прокрутки

Каждый раз, когда элемент прокручивается, в нем срабатывает JavaScript scroll event . Его можно использовать для отслеживания того, что в данный момент просматривает пользователь; для отключения анимации, расположенной вне окна просмотра.

В следующем примере мы выводим индикатор прогресса в правом верхнем углу документа и обновляем его, чтобы он по частям заливался другим цветом по мере прокрутки страницы вниз:

Установив для элемента свойство position или fixed , мы получим тот же результат, что и при установке position:absolute . Но так мы также блокируем прокрутку элемента вместе с остальной частью документа. В результате индикатор прогресса будет статически закреплен в верхнем углу. Внутри него находится еще один элемент, размер которого изменяется в соответствии с текущим прогрессом.

В качестве единиц измерения при установке ширины мы используем % , а не рх , чтобы размеры элемента изменялись пропорционально размеру индикатора прогресса.

Глобальная переменная innerHeight содержит высоту окна, которую мы должны вычесть из общей доступной прокручиваемой высоты документа. Нельзя прокручивать окно ниже при достижении нижней части документа. С innerHeight также может использоваться innerWidth . Разделив pageYOffset ( текущую позицию окна прокрутки ) на максимально допустимую позицию прокрутки и умножив на 100, мы получаем процент для индикатора прогресса.

Вызов preventDefault для JavaScript scroll event не предотвращает прокрутку. Обработчик события вызывается только после того, как происходит прокручивание.

События фокуса ввода

Когда элемент находится в фокусе ввода, браузер запускает в нем событие « focus «. Когда фокус ввода снимается, запускается событие « blur «.

Эти два события не имеют распространения. Обработчик родительского элемента не уведомляется, когда дочерний элемент выделяется фокусом ввода.

В следующем примере выводится подсказка для текстового поля, которое в данный момент находится в фокусе ввода:

Объект окна получает события « focus » и « blur «, когда пользователь переходит или покидает вкладку, окно браузера, в котором выводится документ.

Событие загрузки

Когда завершается загрузка страницы, для объектов тела документа и окна возникает JavaScript event «load» . Оно используется для планирования инициализации действий, для которых требуется загрузка всего документа. Не забывайте, что содержимое

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

Функция cancelAnimationFrame работает так же, как clearTimeout . Она вызывается значением, возвращаемым requestAnimationFrame , чтобы отменить кадр ( если он еще не был вызван ).

Похожий набор функций, setInterval и clearInterval используется для установки таймера, который должен повторять действие каждые X миллисекунд:

Дробление

Некоторые типы событий могут запускаться много раз в течение короткого периода времени ( например, « mousemove » и javascript scroll event ). При обработке таких событий, нужно быть осторожным, чтобы это не происходило очень долго, иначе обработчик будет выполнять действие столько времени, что взаимодействие с документом станет медленным и скачкообразным.

Если нужно сделать что-то нестандартное в таком обработчике, можно использовать setTimeout , чтобы быть уверенными, что это не растянется слишком надолго. Это обычно называют дроблением события. Существует несколько отличающихся друг от друга подходов к дроблению.

В первом примере мы хотим сделать что-то, когда пользователь печатает. Но не хотим делать это после каждого события нажатия клавиши. Когда пользователь быстро печатает, нужно подождать, пока не произойдет пауза. Вместо немедленного выполнения действия в обработчике события мы устанавливаем задержку. Мы также очищаем предыдущую задержку ( если таковая имеется ). Если события происходят через короткие интервалы времени ( меньше, чем установленная нами задержка ), то задержка от предыдущего события отменяется:

Передача неопределенного значения для clearTimeout или его вызов для задержки, которая уже запущена, не даст никакого результата. Нам больше не нужно быть осторожными относительно того, когда его вызывать, мы просто делаем это для каждого события.

Можно использовать иной сценарий, если нужно разделить ответы небольшим промежутком времени. Но чтобы при этом они запускались во время серии событий, а не только после нее. Например, можно отправлять в ответ на события « mousemove » ( JavaScript mouse events ) текущие координаты мыши, но только через каждые 250 миллисекунд:

Заключение

Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не имеем прямого контроля. Для регистрации такого обработчика используется метод addEventListener .

Каждое событие относится к определенному типу (« keydown «, « focus » и так далее ), который идентифицирует его. Большинство событий вызывается для конкретного элемента DOM , а затем распространяются на родительские узлы элемента. Это позволяет обработчикам, связанным с этими элементами, обрабатывать их.

Когда вызывается обработчик, ему передается объект события с дополнительной информацией о действии. Этот объект также содержит методы, позволяющие остановить дальнейшее распространение события ( stopPropagation ) или предотвратить обработку события браузером по умолчанию ( preventDefault ).

Нажатие клавиш порождает события « keydown «, « keypress » и « keyup «. Нажатие мыши порождает события « mousedown «, « mouseup » и « click «. Перемещение мыши — « mousemove «, « mouseenter » и « mouseout «.

JavaScript scroll event можно определить с помощью события « scroll «, а смена фокуса — « focus » и « blur «. После завершения загрузки документа для окна возникает событие « load «.

Только одна часть JavaScript программы может работать одновременно. Обработчики событий и другие запланированные скрипты должны дожидаться, когда закончится выполнение других скриптов в очереди.

Данная публикация представляет собой перевод статьи « Handling Events » , подготовленной дружной командой проекта Интернет-технологии.ру

Симфония на клавиатуре

-Рабинович, а вы выписали на следующий год какие-нибудь газеты?
-Нет,зачем,если есть Internet.
— А в туалет с клавиатурой ходить будете?

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

События клавиатуры, наряду с событиями мыши, являются основными элементами взаимодействия пользователя с программой. В данной статье пойдёт речь о трёх событиях, которые позволяют отлавливать нажатия клавиш в приложении Delphi: OnKeyDown, OnKeyUp и OnKeyPress.

Для получения ввода с клавиатуры, приложения Delphi могут использовать два метода. Самый простой способ, это воспользоваться одним из компонентов, автоматически реагирущем на нажатия клавиш, таким как Edit. Второй способ заключается в создании процедур в форме, которые будут обрабатывать нажатия и отпускания клавиш. Эти обработчики могут обрабатывать как нажатия одиночных клавиш, так и комбинаций. Итак, вот эти события:

OnKeyDown — вызывается, когда на клавиатуре нажимается любая клавиша. OnKeyUp — вызывается, когда любая клавиша на клавиатуре отпускается. OnKeyPress — вызывается, когда нажимается клавиша, отвечающая за определённый ASCII символ.

Теперь самое время посмотреть, как выглядят в программе заголовки обработчиков:

Все события имеют один общий параметр, обычно называемый Key. Этот параметр используется для передачи кода нажатой клавиши. Параметр Shift (в процедурах OnKeyDown и OnKeyUp), указывает на то, была ли нажата клавиша в сочетании с Shift, Alt, и Ctrl.

Фокус, это способность получать пользовательский ввод через мышь или клавиатуру. Получать события от клавиатуры могут только те объекты, которые имеют фокус. На форме активного приложения в один момент времени может быть активным (иметь фокус) только один компонент.

Некоторые компоненты, такие как TImage, TPaintBox, TPanel и TLabel не могут получать фокус, другими словами, это компоненты, наследованные от TGraphicControl. Так же не могут получать фокус невидимые компоненты, такие как TTimer.

События OnKeyDown и OnKeyUp обеспечивают самый низкий уровень ответа клавиатуры. Обработчики OnKeyDown и OnKeyUp могут реагировать на все клавиши клавиатуры, включая функциональные и комбинации с клавишами Shift, Alt, и Ctrl.

События клавиатуры — не взаимоисключающие. Когда пользователь нажимает клавишу, то генерируются два события OnKeyDown и OnKeyPress, а когда отпускает, то только одно: OnKeyUp. Если пользователь нажмёт одну из клавиш, которую OnKeyPress не сможет определить, то будет сгенерировано только одно событие OnKeyDown, а при отпускании OnKeyUp.

Илон Маск рекомендует:  Библиотека CURL в PHP

OnKeyPress возвращает различные значения ASCII для ‘g’ и ‘G,’. Однако, OnKeyDown и OnKeyUp не делают различия между верхним и нижним регистром.

Параметры Key и Shift

Параметр Key можно изменять, чтобы приложение получило другой код нажатой клавиши. Таким образом можно ограничивать набор различных символов, которые пользователь может ввести с клавиатуры. Например разрешить вводить только цифры. Для этого добавьте в обработчик события OnKeyPress следующий код и установите KeyPreview в True (см. ниже).

Это выражение проверяет, содержит ли параметр Key символы нижнего регистра (‘a’..’z’) и символы верхнего регистра (‘A’..’Z’). Если так, то в параметр заносится значение нуля, чтобы предотвратить ввод в компонент Edit (например).

В Windows определены специальные константы для каждой клавиши. Например, VK_RIGHT соответствует коду клавиши для правой стрелки.

Чтобы получить состояния специальных клавиш, таких как TAB или PageUp можно воспользоваться API функцией GetKeyState. Клавиши состояния могут находиться в трёх состояниях: отпущена, нажата, и включена. Если старший бит равен 1, то клавиша нажата, иначе отпущена. Для проверки этого бита можно воспользоваться API функцией HiWord. Если младший бит равен 1, то клавиша включена. Вот пример получения сосотояния специальной клавиши:

В событиях OnKeyDown и OnKeyUp, Key является беззнаковым двухбайтовым (Word) значением, которое представляет виртуальную клавишу Windows. Для получания значения символа можно воспользоваться функцией Chr. В событии OnKeyPress параметр Key является значением Char, которое представляет символ ASCII.


События OnKeyDown и OnKeyUp имеют параметр Shift с типом TShiftState. В Delphi тип TShiftState определён как набор флагов, определяющих состояние Alt, Ctrl, и Shift при нажатии клавиши.

Например, следующий код (из обработчика OnKeyUp) соединяет строку ‘Ctrl +’ с нажатой клавишей и отображает результат в заголовке формы:

Если нажать Ctrl + A, то будут сгенерированы следующие события:

Переадресация событий клавиатуры в форму

Клавиатурный обработчик может работать на двух уровнях: на уровне компонентов и на уровне формы. Свойство формы KeyPreview определяет, будут ли клавиатурные события формы вызываться перед клавиатурными событиями компонентов, так как форма может получать все нажатия клавиш, предназначенные для компонента имеющего в данный момент фокус.

Чтобы перехватить нажатия клавиш на уровне формы, до того как они будут переданы компонентам на форме, необходимо установить свойство KeyPreview в True. После этого компонент как и раньше будет получать события, однако сперва они будут попадать в форму, чтобы дать возможность программе разрешить или запретить ввод различных символов.

Допустим, У Вас на форме есть несколько компонентов Edit и процедура Form.OnKeyPress выглядит следующим образом:

Если один из компонентов Edit имеет фокус и свойство KeyPreview установлено в False, то этот код не будет выполнен — другими словами, если пользователь нажмёт клавишу ‘5’, то в компоненте Edit, имеющем фокус, появится символ «5».

Однако, если KeyPreview установлено в True, то событие формы OnKeyPress будет выполнено до того, как компонент Edit увидит нажатую клавишу. Поэтому, если пользователь нажмёт клавишу ‘5’, то в Key будет подставлено нулевое значение, предотвращая тем самым попадание числовых символов в Edit.

Copyright © 2004-2020 «Delphi Sources». Delphi World FAQ

События клавиатуры

Начиная с самого рассвета компьютерной промышленности, клавиатура была первичным устройством ввода информации, и вероятнее всего сохранит свою позицию ещё долгое время.
События клавиатуры, наряду с событиями мыши, являются основными элементами взаимодействия пользователя с программой. В данной статье пойдёт речь о трёх событиях, которые позволяют отлавливать нажатия клавиш в приложении Delphi: OnKeyDown, OnKeyUp и OnKeyPress.

Для получения ввода с клавиатуры, приложения Delphi могут использовать два метода. Самый простой способ, это воспользоваться одним из компонентов, автоматически реагирующем на нажатия клавиш, таким как Edit. Второй способ заключается в создании процедур в форме, которые будут обрабатывать нажатия и отпускания клавиш. Эти обработчики могут обрабатывать как нажатия одиночных клавиш, так и комбинаций. Итак, вот эти события:
OnKeyDown — вызывается, когда на клавиатуре нажимается любая клавиша. OnKeyUp — вызывается, когда любая клавиша на клавиатуре отпускается. OnKeyPress — вызывается, когда нажимается клавиша, отвечающая за определённый ASCII символ.

Теперь самое время посмотреть, как выглядят в программе заголовки обработчиков:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
.
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
.
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

Все события имеют один общий параметр, обычно называемый Key. Этот параметр используется для передачи кода нажатой клавиши. Параметр Shift (в процедурах OnKeyDown и OnKeyUp), указывает на то, была ли нажата клавиша в сочетании с Shift, Alt, и Ctrl.

Фокус
Фокус, это способность получать пользовательский ввод через мышь или клавиатуру. Получать события от клавиатуры могут только те объекты, которые имеют фокус. На форме активного приложения в один момент времени может быть активным (иметь фокус) только один компонент.

Некоторые компоненты, такие как TImage, TPaintBox, TPanel и TLabel не могут получать фокус, другими словами, это компоненты, наследованные от TGraphicControl. Так же не могут получать фокус невидимые компоненты, такие как TTimer.

OnKeyDown, OnKeyUp
События OnKeyDown и OnKeyUp обеспечивают самый низкий уровень ответа клавиатуры. Обработчики OnKeyDown и OnKeyUp могут реагировать на все клавиши клавиатуры, включая функциональные и комбинации с клавишами Shift, Alt, и Ctrl.

События клавиатуры — не взаимоисключающие. Когда пользователь нажимает клавишу, то генерируются два события OnKeyDown и OnKeyPress, а когда отпускает, то только одно: OnKeyUp. Если пользователь нажмёт одну из клавиш, которую OnKeyPress не сможет определить, то будет сгенерировано только одно событие OnKeyDown, а при отпускании OnKeyUp.

OnKeyPress
OnKeyPress возвращает различные значения ASCII для ‘g’ и ‘G,’. Однако, OnKeyDown и OnKeyUp не делают различия между верхним и нижним регистром.

Параметры Key и Shift
Параметр Key можно изменять, чтобы приложение получило другой код нажатой клавиши. Таким образом можно ограничивать набор различных символов, которые пользователь может ввести с клавиатуры. Например разрешить вводить только цифры. Для этого добавьте в обработчик события OnKeyPress следующий код и установите KeyPreview в True (см. ниже).

f Key in [‘a’..’z’] + [‘A’..’Z’] then Key:=#0

Это выражение проверяет, содержит ли параметр Key символы нижнего регистра (‘a’..’z’) и символы верхнего регистра (‘A’..’Z’). Если так, то в параметр заносится значение нуля, чтобы предотвратить ввод в компонент Edit (например).
В Windows определены специальные константы для каждой клавиши. Например, VK_RIGHT соответствует коду клавиши для правой стрелки.

Чтобы получить состояния специальных клавиш, таких как TAB или PageUp можно воспользоваться API функцией GetKeyState. Клавиши состояния могут находиться в трёх состояниях: отпущена, нажата, и включена. Если старший бит равен 1, то клавиша нажата, иначе отпущена. Для проверки этого бита можно воспользоваться API функцией HiWord. Если младший бит равен 1, то клавиша включена. Вот пример получения сосотояния специальной клавиши:

if HiWord(GetKeyState(vk_PageUp)) <> 0 then
ShowMessage(‘PageUp — DOWN’)
else
ShowMessage(‘PageUp — UP’);

В событиях OnKeyDown и OnKeyUp, Key является беззнаковым двухбайтовым (Word) значением, которое представляет виртуальную клавишу Windows. Для получания значения символа можно воспользоваться функцией Chr. В событии OnKeyPress параметр Key является значением Char, которое представляет символ ASCII.

События OnKeyDown и OnKeyUp имеют параметр Shift с типом TShiftState. В Delphi тип TShiftState определён как набор флагов, определяющих состояние Alt, Ctrl, и Shift при нажатии клавиши.

Например, следующий код (из обработчика OnKeyUp) соединяет строку ‘Ctrl +’ с нажатой клавишей и отображает результат в заголовке формы:

if ssCtrl in Shift then
Form1.Caption:= ‘Ctrl +’ + Chr(Key);

Если нажать Ctrl + A, то будут сгенерированы следующие события:

KeyDown (Ctrl) // ssCtrl
KeyDown (Ctrl+A) //ssCtrl + ‘A’
KeyPress (A)
KeyUp (Ctrl+A)

Переадресация событий клавиатуры в форму
Клавиатурный обработчик может работать на двух уровнях: на уровне компонентов и на уровне формы. Свойство формы KeyPreview определяет, будут ли клавиатурные события формы вызываться перед клавиатурными событиями компонентов, так как форма может получать все нажатия клавиш, предназначенные для компонента имеющего в данный момент фокус.

Чтобы перехватить нажатия клавиш на уровне формы, до того как они будут переданы компонентам на форме, необходимо установить свойство KeyPreview в True. После этого компонент как и раньше будет получать события, однако сперва они будут попадать в форму, чтобы дать возможность программе разрешить или запретить ввод различных символов.

Допустим, У Вас на форме есть несколько компонентов Edit и процедура Form.OnKeyPress выглядит следующим образом:

procedure TForm1.FormKeyPress
(Sender: TObject; var Key: Char);
begin
if Key in [‘0’..’9′] then Key := #0
end;

Если один из компонентов Edit имеет фокус и свойство KeyPreview установлено в False, то этот код не будет выполнен — другими словами, если пользователь нажмёт клавишу ‘5’, то в компоненте Edit, имеющем фокус, появится символ «5».

Однако, если KeyPreview установлено в True, то событие формы OnKeyPress будет выполнено до того, как компонент Edit увидит нажатую клавишу. Поэтому, если пользователь нажмёт клавишу ‘5’, то в Key будет подставлено нулевое значение, предотвращая тем самым попадание числовых символов в Edit.

События от клавиатуры и мыши

Для большинства видимых элементов определен набор обработчиков событий, связанных с мышью и клавиатурой. Изначально источником этих событий является драйвер клавиатуры или драйвер мыши, затем ядро Windows преобразует их в стандартный вид и пересылает окну программы. Прежде чем послать сообщение о вводе с клавиатуры, ядро Windows определяет, какое окно является активным. В Delphi-программах активными элементами будут одна из форм (или главная форма) и элемент, определенный свойством ActiveControl.

События от клавиатуры получают только некоторые оконные компоненты.

Событие OnKeyPress возникает при нажатии клавиши на клавиатуре. Обычно это событие обрабатывается в том случае, когда необходима реакция на нажатие одной клавиши на клавиатуре. Параметр Key имеет тип Char и содержит ASCII-код нажатой клавиши. Для клавиш, которые не имеют ASCII-кодов (соответствующих символов), таких как Shift или F1, событие OnKeyPress не возникает. При использовании комбинаций клавиш, например Shift+A, возникает только одно событие OnKeyPress. Так, при нажатии комбинации Shift+A параметр Key будет иметь значение “А” (зависит от состояния переключателя Caps Lock). Для обработки нажатий клавиш, не имеющих ASCII-эквивалентов, и комбинаций клавиш необходимо использовать события OnKeyDown и OnKeyUp.

Событие OnKeyPress имеет типTKeyPressEvent и описано следующим образом:

TKeyPressEvent = procedure (Sender: TObject; var Key: Char) of Оbject;

Событие OnKeyDown происходит при нажатии клавиши на клавиатуре. Обработчик этого события получает информацию о нажатой клавише и состоянии клавиш Shift, Alt и Ctrl, а также о нажатой кнопке мыши. Информация о клавише передается параметром Key, который имеет тип Word. Для определения того, какая именно клавиша была нажата, необходимо использовать коды виртуальных клавиш.

OnKeyDown(Sender: TObject; var Key: Word; Shift:TShiftState);

Параметр Key содержит код нажатой клавиши, а параметр Shift может иметь одно из следующих значений:

ssShift – нажата клавиша Shift;

ssAlt – нажата клавиша Alt;

ssCtrl – нажата клавиша Ctrl;

ssLeft, ssMiddle, ssRight – нажаты левая, средняя и правая кнопки мыши; ssDouble – нажаты правая и левая кнопки мыши.

Событие OnKeyUp является парным событием для OnKeyDown и возникает, когда пользователь отпускает нажатую ранее клавишу. Как и для события OnKeyDown, возможно распознать клавиши типа Shift, Alt и Ctrl и кнопки манипулятора мышь

Для большинства видимых элементов определен набор обработчиков событий, связанных с мышью.

Событие OnClick возникает при нажатии кнопки мыши в области компонента. Это событие также происходит, когда пользователь:

1) выбрал элемент таблицы (grid), древовидного списка (outline), списка или комбинированного списка нажатием одной из клавиш управления курсором;

2) нажал клавишу Enter, когда активным элементом формы была кнопка со значением по умолчанию (заданная свойством Default);

3) нажал клавишу Esc, когда в активной форме имелась кнопка Cancel (заданная свойством Cancel);

4) нажал клавишу для вызова кнопки. Например, если кнопка имела заголовок ‘&Bold’, клавишей для вызова кнопки будет клавиша “В”.

Событие OnDblClick возникает при двойном нажатии кнопки мыши в области компонента.

Событие OnMouseDown происходит при нажатии кнопки мыши, когда курсор находится в области компонента. Обработчик этого события использу­ется в тех случаях, когда необходимо предпринять какие-либо действия при нажатии кнопки мыши в области компонента. Параметр Button этого события позволяет определить, какая кнопка была нажата, а параметр Shift – были ли нажаты клавиши Shift, Ctrl или Alt при нажатии кнопки мыши. Событие OnMouseDown имеет типTMouseEvent, описанный следующим образом:

TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift:

TShiftState; X, Y: Integer) of Оbject;

Параметры Х и Y содержат координаты курсора мыши в момент нажатия клавиши.

Событие OnMouseMove происходит при перемещении манипулятора мышь. Параметр Shift позволяет определить, были ли нажаты клавиши Shift, Ctrl или Alt при нажатии кнопки мыши. Событие OnMouseMove имееттипTMouseMoveEvent, описанный следующим образом:

TMouseMoveEvent = procedure(Sender; TObject; Shift: TShiftState; X, Y: Integer) of Оbject;

Событие OnMouseUp является парным событию OnMouseDown и возникает в том случае, когда пользователь отпустил ранее нажатую кнопку мыши. Параметр Shift позволяет определить, были ли при этом нажаты клавиши Shift, Ctrl или Alt. Параметры X и Y содержат координаты курсора мыши в момент нажатия клавиши. Параметр Button имеет тип TMouseButton.

У событий системы Delphi существует приоритет. Событие OnClick является более важным, чем OnMouseUp, и должно обрабатываться первым. Приоритет события OnDblClick выше, чем приоритет событий OnMouseDown и OnMouseUp.

Событие OnEnter возникает, когда компонент получает фокус ввода.

Событие OnExit возникает, когда компонент теряет фокус.

6.2.3. События протокола Drag&Drop

Операционная система Windows широко использует специальный прием связывания программ с данными, который называется Drag&Drop (перетащи и отпусти). Разработчик может предусмотреть возможность “перетаскивания” целых компонентов, а также обмена содержимым между компонентами. В Delphi этот протокол базируется на двух свойствах и трех событиях.

Свойство DragMode определяет, как будет выполняться весь комплекс действий, связанных с Drag&Drop: dmManual – вручную; dmAutomatic – автоматически (свойствами и методами компонентов).

Свойство DragCursor определяет вид указателя мыши в момент, когда над компонентом “перетаскиваются данные”.

Событие OnDragOver возникает в момент перемещения указателя мыши с “грузом” над компонентом. Заголовок процедуры:

Procedure (Sender, Source : TObject; X, Y:Integer; State : TDragState;

Var Accept: Boolean);

где Sender – компонент, который возбудил событие; Source – компонент-отправитель “груза”; X, Y – текущие координаты указателя мыши в пикселях клиентской области компонента; State – состояние указателя (dsDragEnter – только что появился над компонентом; dsDragLeave – только что покинул компонент или была отпущена кнопка мыши; dsDragMove – перемещается над компонентом). В параметре Accept обработчик сообщает, готов ли компонент принять данные.

Событие OnDragDropвозникает в случае, когда пользователь “отпустил” перетаскиваемый объект. Параметры обработчика совпадают по назначению с одноименными параметрами OnDragOver. В обработчике OnDragDrop должен содержаться код, который будет выполняться, когда пользователь “отпустил” объект. Параметр Source указывает на объект, который был “отпущен”, а параметр Sender – на объект, принявший перетащенный объект.

При завершении перетаскивания возникает событие OnEndDrag. Заголовок процедуры: Procedure (Sender, Target : TОbject; X, Y : Integer), где Sender – отправитель данных; Targer – получатель данных или Nil, если никто не принял “посылку”; X, Y – координаты мыши в момент отпускания левой кнопки.

Форма

Стандартный проект в Delphi состоит из форм. Каждую форму описывают два файла – файл формы, описывающий свойства формы и размещенных на ней компонентов, и модуль, содержащий описание экземпляра класса формы и исходный код.

Любая программа имеет, как минимум, одну связанную с ней форму, которая называется главной, – эта форма появляется на экране в момент старта программы. Однако программа может иметь сколько угодно форм, каждая из которых решает какую-то локальную задачу и появляется на экране по мере надобности.

Любое приложение Windows должно иметь хотя бы одно окно. Даже если приложение при запуске ничего не показывает на экране, для него все равно автоматически создается дескриптор главного окна – указатель на область памяти, отведенную для его размещения.

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

Дата добавления: 2020-11-18 ; просмотров: 727 | Нарушение авторских прав

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL