- •Вопрос 1. Вывод текста. Шрифты. Параметры шрифтов ………………………3
- •Вопрос 2. Обработка сообщений от мыши и клавиатуры. Понятие
- •Вопрос 1. Вывод текста. Шрифты. Параметры шрифтов.
- •Типы шрифтов
- •Отображение на экране
- •1.3.1. Создание новых шрифтов
- •1.3.2. Функции для работы со шрифтами
- •Вопрос 2. Обработка сообщений от мыши и клавиатуры. Понятие фокуса ввода.
- •2. Клавиатура
- •2.1. Клавиатурные сообщения
- •2.2. Параметры клавиатурных сообщений
- •2.3. Символьные клавиатурные сообщения
- •3. Мышь
- •3.1. Сообщения, поступающие от мыши
2. Клавиатура
Когда вы нажимаете клавиши, клавиатура генерирует аппаратное прерывание. Обработчик клавиатурного прерывания находится внутри драйвера клавиатуры. Драйвер клавиатуры является составной частью ОС Windows. Его задача - генерация на основе аппаратных прерываний клавиатурных сообщений и запись этих сообщений во внутреннюю системную очередь сообщений Windows. Когда вы нажимаете на клавишу и затем отпускаете её, в системную очередь записывается несколько сообщений.
Сообщения, генерируемые драйвером клавиатуры, являются сообщениями низкого уровня. Они несут в себе такую информацию, как, например, скан-код нажатой клавиши. Приложения не пользуются такими сообщениями. ОС Windows выполняет преобразование клавиатурных сообщений низкого уровня в сообщения, которые содержат коды виртуальных клавиш (virtual-key code).
Код виртуальной клавиши соответствуют не расположению клавиши на клавиатуре, а действию, которое выполняет эта клавиша. Приложение обрабатывает коды виртуальных клавиш, а соответствие виртуальных и физических клавиш обеспечивается драйвером клавиатуры.
2.1. Клавиатурные сообщения
От клавиатуры может поступать четыре сообщения: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP. Когда вы нажимаете клавишу, генерируется сообщение WM_KEYDOWN или WM_SYSKEYDOWN, в зависимости от того, какая была нажата клавиша и была ли эта клавиша нажата в комбинации с клавишей <Alt>. При отпускании клавиши генерируется сообщение WM_KEYUP или WM_SYSKEYUP.
Клавиатурные сообщения с префиксом WM_SYS называются системными клавиатурными сообщениями. Приложение редко обрабатывает системные сообщения от клавиатуры, передавая их в неизменном виде функции DefWindowProc. Обработка системных клавиатурных сообщений обычно сводится к выбору элементов меню, переключения на другое окно или другое приложение. Системные сообщения предназначены для Windows.
Сообщения WM_KEYDOWN и WM_KEYUP, напротив, предназначены для приложения. Если приложение желает отреагировать на ту или иную клавишу или комбинацию клавиш, оно должно обработать соответствующее сообщение.
Когда окно сворачивается в пиктограмму, его тоже можно сделать активным. При этом надпись, расположенная около пиктограммы, выделяется изменением цвета фона. Ни одно окно в свернутом приложении не получает фокус ввода, поэтому все сообщения от клавиатуры транслируются в системные сообщения. Вы, однако, можете перехватить любое системное сообщение и определить для него собственный обработчик.
2.2. Параметры клавиатурных сообщений
Сообщения WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP передают информацию о нажатой клавише через параметры lParam и wParam.
Параметр lParam для этих сообщений содержит информацию низкого уровня, такую, как скан-код, счётчик повторов, флаг предыдущего состояния клавиши и т. п. Эта информация редко используется приложениями Windows.
Параметр wParam содержит код виртуальной клавиши, соответствующей нажатой физической клавише. Именно этот параметр используется приложениями для идентификации нажатой клавиши.
Если нажать клавишу и оставить ее в нажатом состоянии, функция окна может получить подряд несколько сообщений WM_KEYDOWN, прежде чем придет сообщение WM_KEYUP. В этом случае бит предыдущего состояния клавиши (бит 30) можно использовать для обнаружения сообщений, возникших в результате включения автоповтора клавиатуры. Приложение может игнорировать такие сообщения, исключая эффект накопления, когда приложение не может обрабатывать сообщения с такой скоростью, с какой они поступают. Например, если вы будете долго держать клавишу пролистывания страниц в текстовом редакторе, то после того, как вы ее отпустите, текстовый редактор будет еще долго листать ваш документ.
Для сообщений WM_KEYDOWN и WM_KEYUP значение кода контекста (бит 29) и флага изменения состояния (бит 31) всегда равно 0.
Для сообщений WM_SYSKEYUP и WM_SYSKEYDOWN бит 31 равен 1. Но есть два исключения.
Во-первых, если активное окно свернуто в пиктограмму, все сообщения от клавиатуры преобразовываются в системные и, если клавиша <Alt> не нажата, код контекста равен 0.
Во-вторых, на некоторых клавиатурах для ввода символов национального языка могут использоваться комбинации с участием клавиш <Alt>, <Control>, <Shift> и т. п. В этом случае код контекста может быть равен 1, хотя сообщение не является системным.
Обработчик клавиатурного сообщения должен возвратить значение 0 для всех перехваченных сообщений.
Как сказано выше, параметр wParam содержит код виртуальной клавиши, соответствующей нажатой физической клавише. Код виртуальной клавиши не зависит от аппаратной реализации клавиатуры.
Многие коды виртуальных клавиш имеют символьное обозначение, определенное в файле windows.h. Приведем полный список кодов виртуальных клавиш. Те из них, которые определены в файле windows.h, имеют префикс VK_ (от слов Virtual Key).
Для определения состояния клавиш <Shift>, <Caps Lock>, <Control>, <Num Lock> сразу после получения сообщения функция окна должна вызвать функцию с именем GetKeyState, которая входит в программный интерфейс Windows. Приведем прототип этой функции:
int WINAPI GetKeyState(int vkey);
Параметр функции vkey должен указывать код виртуальной клавиши, для которой необходимо вернуть состояние.
Старший бит возвращаемого значения, установленный в 1, говорит о том, что указанная клавиша была нажата. Если этот бит равен 0, клавиша не была нажата.
Младший бит возвращаемого значения указывает состояние переключения. Если он равен 1, клавиша (такая, как <Caps Lock> или <Num Lock>) находится во включенном состоянии, то есть она была нажата нечетное число раз после включения компьютера. Следует учитывать, что при помощи программы установки параметров компьютера SETUP, расположенной в BIOS, можно задать произвольное состояние переключающих клавиш после запуска системы.
Функция GetKeyState возвращает состояние клавиши на момент извлечения сообщения из очереди приложения функцией GetMessage.
Для того чтобы узнать состояние клавиш в любой произвольный момент времени, можно воспользоваться функцией GetAsyncKeyState:
int WINAPI GetAsyncKeyState (int vkey);
Параметр функции vkey должен указывать код виртуальной клавиши, для которой необходимо вернуть состояние.
Старший бит возвращаемого значения, установленный в 1, говорит о том, что указанная клавиша была нажата в момент вызова функции. Если этот бит равен 0, клавиша не была нажата.
Младший бит возвращаемого значения установлен в 1, если указанная клавиша была нажата с момента последнего вызова функции GetAsyncKeyState.
Если для функции в качестве параметра задать значения VK_LBUTTON или VK_RBUTTON, можно узнать состояние клавиш, расположенных на корпусе мыши.
Есть возможность определить и изменить состояние для всех клавиш одновременно.
Для определения состояния клавиш воспользуйтесь функцией GetKeyboardState:
void WINAPI GetKeyboardState (BYTE FAR* lpbKeyState);
Единственный параметр lpbKeyState этой функции - дальний указатель на массив из 256 байт. После вызова функции этот массив будет заполнен информацией о состоянии всех виртуальных клавиш в момент генерации клавиатурного сообщения. В этом смысле функция аналогична функции GetKeyState.
Для любого байта массива установленный в 1 старший бит означает, что соответствующая клавиша была нажата. Если этот бит равен 0, клавиша не была нажата. Младший бит, установленный в 1, означает, что клавиша была переключена. Если младший бит равен 0, клавиша не была переключена.
После вызова функции GetKeyboardState вы можете изменить содержимое массива и вызвать функцию SetKeyboardState, изменяющую состояние клавиатуры:
void WINAPI SetKeyboardState(BYTE FAR* lpbKeyState);
Интересна также функция GetKeyNameText, возвращающая для заданного кода виртуальной клавиши название соответствующей клавиши в виде текстовой строки. Названия виртуальных клавиш определены в драйвере клавиатуры.
Приведем прототип функции GetKeyNameText:
int WINAPI GetKeyNameText(LONG lParam,
LPSTR lpszBuffer, int cbMaxKey);
Первый параметр функции lParam должен определять клавишу в формате компоненты lParam клавиатурного сообщения. Вы можете использовать в качестве этого параметра значение lParam, полученное функцией окна вместе с любым клавиатурным сообщением, таким, как WM_KEYDOWN или WM_SYSKEYDOWN.
Второй параметр - lpszBuffer является указателем на буфер, в который будет записано название клавиши.
Третий параметр - cbMaxKey должен быть равен длине буфера, уменьшенной на 1.
