Какое событие класса control отвечает за работу с клавиатурой
Класс Control является базовым для всех классов, с помощью которых строится пользовательский интерфейс. К таким классам относятся формы, кнопки, меню, поля ввода и другие.
В классе Control реализованы базовые возможности интерфейсных элементов. В нём есть методы для обработки информации, вводимой пользователем с помощью клавиатуры и мыши. Для объектов класса Control можно определять размер, положение, цвет фона, вид и цвет шрифта и многое другое.
Наиболее важные свойства класса Control :
BackColor — определяет цвет фона;
ForeColor — задаёт цвет символов;
Font — характеризует шрифт символов текста;
Location — содержит координаты левого верхнего угла элемента. Свойства Left и Top позволяют обратится к координатам верхнего угла поотдельности;
Size — определяет размеры элемента. Через свойства Height и Width можно обращаться к высоте и ширине по отдельности;
Enabled — определяет доступность элемента ( true — элемент доступен, false — не доступен, хотя может быть и видим, если имеет графическое представление. Как правило, недоступный элемент, например, пункт меню выглядит серым);
Visible — определяет видимость элемента ( true — элемент видим (и доступен!), false — не видим (и не доступен)).
Основные методы класса Control:
Focus() — задание фокуса ввода элементу управления. Результат: true — элемент получил фокус ввода, false — не получил. Данные, вводимые пользователем с помощью клавиатуры, направляются в элемент управления, который получил фокус ввода;
Show() — отображает элемент управления, свойство Visible становится равным true ;
Hide() — скрывает элемент управления,свойство Visible в этом случае устанавливается в значение false ;
Invalidate() — обновляет изображение элемента управления.
Некоторые события класса Control:
Click — событие, возникающее при щелчке мышью по элементу управления;
DoubleClick — событие, возникающее при двойном щелчке мышью;
MouseDown — событие, которое возникает при ходе левой клавиши мыши вниз (нажимание клавиши);
MouseUp — событие, которое возникает при ходе левой клавиши мыши вверх (отпускание клавиши);
MouseMove — событие, которое возникает при перемещении курсора мыши над объектом ;
KeyDown — событие, возникающее при нажатии клавиши на клавиатуре;
KeyUp — событие, возникающее при отпускании клавиши на клавиатуре;
Paint — событие, которое возникает в тот момент, когда весь элемент управления или его часть объявляется недействительной и требуется его перерисовка.
Средства базового класса Control. События клавиатуры. События проверки.
Класс Control содержит более 300 членов, и описать их все (или хотя бы большую часть) в одной главе просто невозможно. Следовательно, вам все равно придется обратиться к электронной документации [Кстати говоря, пакет форм Windows автоматически опознает операции с колесом мыши и обеспечивает прокрутку формы/элемента там, где это имеет смысл. Таким образом, в большинстве случаев вам не придется использовать новое событие Control.MouseWheel.]. Однако события клавиатуры и события проверки, занимающие важное место в работе элементов, несколько отличаются от своих прототипов из VB6, и при работе с ними следует помнить о некоторых нюансах.
События клавиатуры
Три события клавиатуры инициируются в тех же ситуациях, что и их аналоги из прежних версий VB.
- KeyPress: происходит при нажатии клавиши, когда элемент обладает фокусом.
- KeyDown: происходит при переходе клавиши в нажатое состояние, когда элемент обладает фокусом.
- Key Up: происходит при отпускании клавиши, когда элемент обладает фокусом.
По аналогии с VB6 событие KeyDown инициируется раньше события KeyPress, которое, в свою очередь, предшествует KeyUp. Событие KeyPress использует объект KeyPressEventArgs, в свойстве KeyChar которого передается информация о нажатой клавише.
События KeyDown и KeyUp, как и в VB6, могут использоваться для проверки клавиш-модификаторов (таких, как CTRL и ALT). Класс KeyEventArgs, передаваемый этим событиям, обладает несколько большими возможностями, чем класс KeyPressEventArgs события KeyPress. Класс KeyEventArgs содержит свойство KeyData, в котором при помощи перечисляемого типа Key передается полная информация о комбинациях клавиш и о состоянии клавиш-модификаторов в момент нажатия.
Свойства Modifiers и SHIFT позволяют узнать об одновременном нажатии трех клавиш (ALT + SHIFT + другая клавиша). Например, следующая команда проверяет, была ли нажата клавиша-модификатор ALT:
Примечание
Если вас не интересуют такие мелочи, как различия между левой и правой клавишей SHIFT, удобнее воспользоваться свойствами Control SHIFT и ALT класса KeyEventArgs.
К сожалению, значения свойств KeyChar и KeyData нельзя сбросить, поскольку они доступны только для чтения [Возможно, этот недочет будет исправлен в окончательной версии.]. Впрочем, введенный символ можно "поглотить" и тем самым предотвратить его появление в элементе; для этого свойству Handled объекта события задается значение True. Пример:
В результате неверный символ не появится в текстовой поле.
События проверки
Команда e.Cancel = True отменяет передачу фокуса от текстового поля другому элементу, если в поле нет ни одного символа.
С другой стороны, событие Validated инициируется после утраты фокуса элементом, но до передачи его другому элементу. Таким образом, в обработчике события Validated можно обновить состояние других элементов формы.
Примечание
Если свойство CausesValidation элемента равно False, события Validating и Validated не инициируются.
Класс Control является базовым для всех отображаемых элементов, то есть элементов, которые составляют графический интерфейс пользователя, например кнопок, списков, полей ввода и форм. Класс Control реализует базовую функциональность интерфейсных элементов. Он содержит методы обработки ввода пользователя с помощью мыши иклавиатуры, определяет размер, положение, цвет фона идругие характеристики элемента. Для каждого объекта можно определить родительский класс, задав свойство Parent, при этом объект будет иметь, например, такой же цвет фона, как и его родитель (речь идет не о наследовании, а о взаимоотношениях объектов во время выполнения программы, например, если на форме размещена кнопка, форма является родительским объектом по отношению к кнопке).
Наиболее важные свойства класса Control перечислены в табл. 14.2, методы — в табл. 14.3.
Таблица 14.2.Основные свойства класса Control
Anchor Определяет, какие края элемента управления будут привязаны
к краям родительского контейнера. Если задать привязку всех краев, элемент будет изменять размеры вместе сродительским
BackColor, Определяют параметры отображения рабочей области формы:
BackgroundImage, Font, цвет фона, фоновый рисунок, шрифт, цвет текста, вид
ForeColor, Cursor указателя мыши
Bottom, Right Координаты нижнего правого угла элемента. Могут устанавливаться
также через свойство Size
Top, Left Координаты верхнего левого угла элемента. Эквивалентны свойству
Bounds Возвращает объект типа Rectangle (прямоугольник), который определяет
размеры элемента управления
ClientRectangle Возвращает объект Rectangle, определяющий размеры рабочей области
ContextMenu Определяет, какое контекстное меню будет выводиться при щелчке на
элементе правой кнопкой мыши
Dock Определяет, у какого края родительского контейнера будет отображаться
Location Координаты верхнего левого угла элемента относительно верхнего левого угла
контейнера, содержащего этот элемент, в виде структуры типа Point.
Структура содержит свойства X и Y
Height, Width Высота и ширина элемента
Size Высота и ширина элемента в виде структуры типа Size. Структура содержит
свойства Height и Width
Created, Disposed, Возвращают значения типа bool, определяющие текущее
Enabled, Focused, состояние элемента: создан, удален, использование
Visible разрешено, имеет фокус ввода, видимый
Handle Возвращает дескриптор элемента (уникальное целочисленное значение,
ModifierKeys Статическое свойство, используемое для проверки состояния
модифицирующих клавиш (Shift, Control, Alt). Возвращает результат в виде
объекта типа Keys
MouseButtons Статическое свойство, проверяющее состояние клавиш мыши. Возвращае
результат в виде объекта типа MouseButtons
Opacity Определяет степень прозрачности элемента управления. Может изменяться от
0 (прозрачный) до 1 (непрозрачный)
Parent Возвращает объект, родительский по отношению к данному (имеется в виду н
базовый класс, а объект-владелец)
Region Определяет объект Region, при помощи которого можно управлять
очертаниями и границами элемента управления
TabIndex, TabStop Используются для настройки последовательности перемещения с помощью
клавиши Tab по элементам управления, расположенным на форме
Focus Установка фокуса ввода на элемент (в элемент, имеющий фокус ввода,
направляется ввод пользователя с клавиатуры)
GetStyle, SetStyle Получение и установка флагов управления стилем элемента. Используются
значения перечисления Control Styles (см. далее)
Hide, Show Управление свойством Visible (Hide — скрыть элемент, Show — отобразить
Invalidate Обновление изображения элемента путем отправки соответствующего
можно было обновлять не всю область, занимаемую элементом, а лишь ее
ОnХХХХ Методы-обработчики событий (OnMouseMove, OnKeyDown, OnResize,
OnPaint и т. п.), которые могут быть замещены в производных классах
Refresh Обновление элемента и всех его дочерних элементов
SetBounds, Управление размером и положением элемента SetLocation, SetClientArea
Перечисление Control Styles задает возможные значения стиля формы в виде битовых флагов, поэтому можно использовать их комбинации. Значения всех констант перечисления можно посмотреть в электронной документации, а для первого знакомства достаточно одного - ResizeRedraw. Этот стиль определяет, что при изменении размеров формы она будет автоматически перерисована. По умолчанию перерисовка не выполняется, и если на форме есть какое-либо изображение, результат изменения размеров формы может сильно озадачить.
В табл. 14.4 перечислена небольшая часть событий, определенных в классе Control.
Таблица 14.4. Некоторые события класса Control
Событие Описание
Click, DoubleClick, MouseEnter, MouseLeave, События от мыши MouseDown, MouselUp,
KeyPress, KeyUp, KeyDown События от клавиатуры
BackColorChanged, ContextMenuChanged, События изменения элемента
WinForms и клавиатура, довольно веселое сочетание, особенно когда пытаешься их заставить работать согласованно.
1. События Control.Key*
Любой контрол умеет реагировать на нажатия клавиш и для этого определены несколько событий: Control.KeyDown, Control.KeyPress, Control.KeyUp. Вроде бы все нормально, подписываемся на события и получаем реакцию на клавиши. Но тут есть один подвох - эти события срабатывают только когда контрол находится в фокусе. Кроме того, многие контролы уже имеют стандартные обработчики клавиш, многие реагируют на пробел как на клик, а TextBox и его родственники перехватывают почти всю клавиатуру.
2. Форма тоже контрол
Класс Form также наследуется от контрол, и умеет получать эти события. Вроде бы очевидно, переносим обработку клавиш в события формы и радуемся, она же вроде бы всегда в фокусе. Но и тут не все так просто. Если дочерний контрол настроен на обработку клавиш и находится в фокусе (а если на форме есть дочерние контролы, то один из них обязательно в фокусе), то форма просто игнорирует нажатия на клавиши.
Можно вспомнить о свойстве формы Form.KeyPreview, которое предназначено для перехвата событий, тогда события клавиатуры будут сначала передаваться в форму. Это вроде бы рабочий вариант, но если вы не хотите чтобы стандартный функционал контролов все еще работал, то придется не забыть выставить свойство KeyPressEventArgs.Handled = false; чтобы после обработки события клавиатуры на уровне формы, оно было передано в дочерние контролы. Честно говоря, это не самый лучший вариант, т.к. имеет свои ограничения и далеко не все задачи можно решить таким способом. Хотя он вроде для этого и задуман.
3. Нас спасет меню
Первый вариант решения проблемы относительно без шаманства - добавить на форму меню в лице MenuStrip. Меню сделано таким образом, что к каждому его элементу, можно привязать хоткей, а для их корректной работы меню перехватывает все события клавиатуры и отдает дальше только те, которые не связаны с нажатиями на заданные клавиши и сочетания. Способ всем хорош, кроме пары моментов: для всех нужных клавиш и сочетаний нужен пункт в меню и необходимо само меню на форме. Если первая проблема еще может быть решена применением скрытых элементов (лично не проверял), то вторая - реально проблема, т.к. не любая форма приложения допускает наличие на ней меню, а добавлять его только ради обработки клавиш. ну вы меня поняли.
4. Универсальное решение
Не торопитесь радоваться, все предыдущие пункты требовали только мастерского владения кликом мыши в интерфейс конструктора, а тут потребуется писать код.
В форме, как и любом контроле есть виртуальный метод ProcessCmdKey, который отвечает за дефолтную обработку событий клавиатуры, вот его-то и потребуется переопределить в нашей форме для получения ожидаемой и корректной работы с клавиатурой.
Вызов базового метода - не обязателен. За передачу события дочерним контролам отвечает результат работы метода, только логика немного наоборот: true - клавиша обработана, дальнейшая обработка не требуется; false - событие будет передано дочерним контролам, даже если вы выполнили какую-то предварительную обработку. Таким образом вы получаете полный контроль над обработкой событий клавиатуры на уровне формы или кастомного контрола.
5. Ну и как этим воспользоваться?
Если хватит энтузиазма, позже соберу в этом ответе ссылки на связанные вопросы с хорошими ответами. А пока первое что нашлось по теме без глубокого копания:
От переводчика: данная статья является десятой в цикле переводов официального руководства по библиотеке SFML. Прошлую статью можно найти тут. Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML — это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти тут. Начнем.
1. Приступая к работе
- Рисование 2D объектов
- Спрайты и текстуры
- Текст и шрифты
- Формы
- Проектирование ваших собственных объектов с помощью массивов вершин
- Позиция, вращение, масштаб: преобразование объектов
- Добавление специальных эффектов с шейдерами
- Контроль 2D камеры и вида
- Проигрывание звуков и музыки
- Запись аудио
- Пользовательские потоки аудио
- Спатиализация: звуки в 3D
Вступление
В этой статье приводится подробный список событий и объясняется, как эти события обрабатывать.
Тип sf::Event
До детального разбора обработки событий важно понять, что из себя представляет тип sf::Event, и как правильно использовать его. sf::Event состоит из объединения, хранящего в себе тип события, и вспомагательных функций и членов. Доступному члену объединения соответсвует один или несколько членов класса, например, event.key соответствует событию KeyPressed . Попытка обработки любых других членов приведет к неопределенному поведению. Никогда не пытайтесь обработать не произошедшее событие.
Экземпляр sf::Event можно инициализировать функцией pollEvent (или waitEvent ) класса sf::Window. Только эти две функции могут инициализировать экземпляр sf::Event.
Для ясности, вот как выглядит типичный цикл обработки событий:
Перечитайте параграф выше и убедитесь, что вы все поняли. Класс sf::Event вызывает много проблем у начинающих программистов.
Ладно, теперь мы знаем, как события представлены в SFML, настало время выяснить, что каждое событие означает.
Событие Closed
Событие sf::Event::Closed срабатывает, когда пользователь хочет закрыть окно, используя любой из методов, предоставляемых менеджером окон (кнопка закрытия, макросы клавиатуры и так далее). Это событие предоставляет информацию о том, что пользователь попытался закрыть окно; оно еще не закрыто.
Обычно, в ответ на это событие, код вызывает window.close() , чтобы закрыть окно. Однако, вы можете сделать еще что-то, например, сохранить текущее состояние приложения или спросить пользователя, что надо сделать. Если вы ничего не сделаете в ответ на это событие, окно будет оставаться открытым.
Член класса, ассоциируемый с этим событием, не существует.
Событие Resized
Событие sf::Event::Resized срабатывает, когда происходит изменение размера окна. Либо в результате действия пользователя, либо программно, после вызова window.setSize .
Вы можете использовать это событие, чтобы отрегулировать настройки отображения: область просмотра, если вы используете OpenGL напрямую, или текущую точку обзора, если вы используете sfml-graphics .
Член класса, ассоциируемый с этим событием, называется event.size и содержит новый размер окна.
События LostFocus и GainedFocus
События sf::Event::LostFocus и sf::Event::GainedFocus срабатывают, когда окно потеряло/приобрело фокус; это происходит, когда пользователь меняет текущее активное окно. Когда окно теряет фокус, оно не получает события клавиатуры.
Это событие можно использовать, например, для приостановки игры, когда окно неактивно.
Член класса, ассоциируемый с этим событием, не существует.
События TextEntered
Событие sf::Event::TextEntered срабатывает, когда происходит ввод символа. Это не событие KeyPressed : TextEntered срабатывает, когда пользователь вводит символ, который может быть выведен. Например, нажатие '^' и 'e' на французской клавиатуре приведет к двум событиям KeyPressed и только к одному TextEntered , содержащему символ 'ê'. Это работает для всех методов ввода, предоставленным операционной системой.
Это событие обычно используется для отлова пользовательского ввода в текстовое поле.
Член класса, ассоциируемый с этим событием, называется event.text и содержит номер символа Unicode введенного символа. Вы можете поместить это значение в sf::String, или привести его к типу char после того, как убедитесь, что этот символ лежит в диапазоне ASCII символов (0 — 127).
Многие программисты используют событие KeyPressed для обработки пользовательского ввода и применяют сумасшедшие алгоритмы для обработки пользовательского ввода, которые пытаются интерпретировать все возможные комбинации клавиш. Не делайте этого!
События KeyPressed и KeyReleased
События sf::Event::KeyPressed и sf::Event::KeyReleased срабативают, когда клавиша на клавиатуре нажата/отжата.
Если клавиша зажата, события KeyPressed будут генерироваться с определенным интервалов, заданным операционной системой (т.е. та же задержка, что применяется, когда вы вводите текст в редакторе). Чтобы отменить повторение событий KeyPressed , вы можете вызвать window.setKeyRepeatEnabled(false) . Очевидно, что событие KeyReleased никогда не повторяется.
Эти события можно использовать, если вы хотите вызвать какое-нибудь действие ровно один раз, когда клавиша нажата или отжата, например, чтобы заставить персонажа прыгнуть.
Иногда люди пытаются использовать событие KeyPressed для реализации плавного движения. Это не приводит к ожидаемому эффекту, потому что это событие генерируется с определенным интервалом. Чтобы реализовать плавное движение с помощью событий, вы должны использовать логическое значение, устанавливаемое KeyPressed и обнуляемое KeyReleased ; движение должно осуществляться, пока это логическое значение установлено.
Другие (более простые) пути реализации плавного движение, с использованием вода с клавиатуры с помощью sf::Keyboard (смотрите посвященную этому статью).
Член класса, ассоциируемый с этим событием, называется event.key и содержит код нажатого/отжатого символа, а также текущее состояние клавиш-модификаторов (alt, control, shift, system).
Помните, что некторые клавиши имеют специфичное значение для операционной системы, обработка этих клавиш приводит к неопределенному поведению. Например, клавиша F10 в Windows, которая меняет фокус, или клавиша F12, которая запуска дебагер при использовании Visual Studio. Эта проблема будет решена в будущих версиях SFML.
Событие MouseWheelMoved
Событие sf::Event::MouseWheelMoved устарело и было упразнено в SFML 2.3. Используйте MouseWheelScrolled .
Событие MouseWheelScrolled
Событие sf::Event::MouseWheelScrolled вызыватеся, когда колесо мыши двигается вверх, вниз или вбок (если это поддерживается мышью).
Член класса, ассоциируемый с этим событием, называется event.mouseWheelScroll и содержит число тиков, на которое сместилось колесо, ориентацию движения колеса и текущую позицию курсора мыши.
События MouseButtonPressed и MouseButtonReleased
События sf::Event::MouseButtonPressed и sf::Event::MouseButtonReleased срабатывают, когда кнопка мыши нажата/отпущена.
Член класса, ассоциируемый с этим событием, называется event.mouseButton и содержит код нажатой/отжатой кнопки, а также позицию курсора мыши.
Событие MouseMoved
Событие sf::Event::MouseMoved срабатывает, когда курсор мыши движется внутри окна.
Это событие срабатывает, даже если окно не в фокусе. Однако, срабатывание происходит только когда курсор мыши движется только в пределах внутренней области окна (во внутреннюю облась окна не входят заголов и границы),
Член класса, ассоциируемый с этим событием, называется event.mouseMove и содержит позицию курсора мыши относительно окна.
События MouseEntered и MouseLeft
События sf::Event::MouseEntered и sf::Event::MouseLeft срабатывают, когда курсор мыши входит в облась окна или покидает ее.
Член класса, ассоциируемый с этим событием, не существует.
События JoystickButtonPressed и JoystickButtonReleased
События sf::Event::JoystickButtonPressed и sf::Event::JoystickButtonReleased срабатывают, когда кнопка геймпада нажата/отжата.
SFML поддерживает 8 джойстиков и 32 кнопки.
Член класса, ассоциируемый с этим событием, называется event.joystickButton и содержит идентификатор джойстика и индекс нажатой/отжатой кнопки.
Событие JoystickMoved
Событие sf::Event::JoystickMoved срабатывает, когда стик геймпада движется.
Стики джойстика, как правило, очень чувствительны, именно поэтому SFML использует порог обнаружения, чтобы избежать постоянных срабатываний JoystickMoved . Это пороговое значение можно изменить с помощью вызова функции Window::setJoystickThreshold .
SFML поддерживает 8 стиков джойстика: X, Y, Z, R, U, V, POV X и POV Y. Как происходит взаимодействие с геймпадом зависит от драйвера этого геймпада.
Член класса, ассоциируемый с этим событием, называется event.joystickMove и содержит идентификатор джойстика, имя стика и его текущую позицию (в интервале [-100, 100]).
События JoystickConnected и JoystickDisconnected
События sf::Event::JoystickConnected и sf::Event::JoystickDisconnected срабатывают, когда джойстик присоединяется/отсоединяется.
Читайте также: