18110

Клавиатурные сообщения

Доклад

Информатика, кибернетика и программирование

Клавиатурные сообщения От клавиатуры может поступать четыре сообщения WM_KEYDOWN WM_KEYUP WM_SYSKEYDOWN WM_SYSKEYUP. Когда вы нажимаете клавишу генерируется сообщение WM_KEYDOWN или WM_SYSKEYDOWN в зависимости от того какая была нажата клавиша и была ли эта клавиша нажата в комбинации с клавиш

Русский

2013-07-06

68.5 KB

2 чел.

Клавиатурные сообщения

От клавиатуры может поступать четыре сообщения - WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP. Когда вы нажимаете клавишу, генерируется сообщение WM_KEYDOWN или WM_SYSKEYDOWN, в зависимости от того, какая была нажата клавиша и была ли эта клавиша нажата в комбинации с клавишей <Alt>. При отпускании клавиши генерируется сообщение WM_KEYUP или WM_SYSKEYUP.

Клавиатурные сообщения с префиксом WM_SYS называются системными клавиатурными сообщениями. Сообщения WM_KEYDOWN и WM_KEYUP предназначены для приложения. Если приложение желает отреагировать на ту или иную клавишу или комбинацию клавиш, оно должно обработать соответствующее сообщение.

Параметры клавиатурных сообщений

Сообщения WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP передают информацию о нажатой клавише через параметры lParam и wParam.

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

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

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

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

Для определения состояния клавиш <Shift>, <Caps Lock>, <Control>, <Num Lock> сразу после получения сообщения функция окна должна вызвать функцию с именем GetKeyState, которая входит в программный интерфейс Windows. Приведем прототип этой функции:

int WINAPI GetKeyState(int vkey);

Параметр функции vkey должен указывать код виртуальной клавиши, для которой необходимо вернуть состояние.

Старший бит возвращаемого значения, установленный в 1, говорит о том, что указанная клавиша была нажата. Если этот бит равен 0, клавиша не была нажата.

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

int WINAPI GetAsyncKeyState (int vkey);

Параметр функции vkey должен указывать код виртуальной клавиши, для которой необходимо вернуть состояние.

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

Для определения состояния клавиш воспользуйтесь функцией GetKeyboardState:

void WINAPI GetKeyboardState (BYTE FAR* lpbKeyState);

Единственный параметр lpbKeyState этой функции - дальний указатель на массив из 256 байт. После вызова функции этот массив будет заполнен информацией о состоянии всех виртуальных клавиш в момент генерации клавиатурного сообщения. В этом смысле функция аналогична функции GetKeyState.

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

После вызова функции GetKeyboardState вы можете изменить содержимое массива и вызвать функцию SetKeyboardState, изменяющую состояние клавиатуры:

void WINAPI SetKeyboardState(BYTE FAR* lpbKeyState);

Функция GetKeyboardType позволит вам определить тип клавиатуры и количество имеющихся на ней функциональных клавиш:

int WINAPI GetKeyboardType(int fnKeybInfo);

В зависимости от значения параметра fnKeybInfo функция может возвращать различную информацию о клавиатуре.

Если задать значение параметра fnKeybInfo, равное 0, функция вернет код типа клавиатуры:

Если задать значение параметра, равное 1, функция вернет код подтипа клавиатуры.

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

Функция GetKeyNameText возвращает для заданного кода виртуальной клавиши название соответствующей клавиши в виде текстовой строки. Названия виртуальных клавиш определены в драйвере клавиатуры.

Прототип функции GetKeyNameText:

int WINAPI GetKeyNameText(LONG lParam,

  LPSTR lpszBuffer, int cbMaxKey);

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

Второй параметр - lpszBuffer является указателем на буфер, в который будет записано название клавиши.

Третий параметр - cbMaxKey должен быть равен длине буфера, уменьшенной на 1.

Функция wsprintf входит в ядро Windows и используется аналогично функции sprintf. Эта функция определена в файле windows.h следующим образом:

int FAR CDECL wsprintf(LPSTR lpszOut, LPCSTR lpszFmt, ...);

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

Второй параметр - указатель на строку формата, определяющую формат строки, которая будет записана в буфер.

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

size = wsprintf(szBuf,

 "Клавиатура %s,\nподтип %d,\n",

 (LPSTR)apszKbTypes[type-1], subtype);

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

Символьные клавиатурные сообщения

Распознавание регистра можно выполнить с помощью функции TranslateMessage, которая включается в цикл обработки сообщений:

while(GetMessage(&msg, 0, 0, 0))

{

TranslateMessage(&msg);

 DispatchMessage(&msg);

}

Функция TranslateMessage преобразует клавиатурные сообщения WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN и WM_SYSKEYUP в символьные сообщения WM_CHAR, WM_DEADCHAR, WM_SYSCHAR, WM_SYSDEADCHAR. Образованные символьные сообщения помещаются в очередь сообщений приложения, причем оригинальные клавиатурные сообщения из этой очереди не удаляются.

Параметр lParam для символьного сообщения равен параметру lParam клавиатурного сообщения, из которого первое было образовано, то есть в процессе преобразования значение lParam не изменяется.

Параметр wParam содержит код символа, соответствующего нажатой клавише в так называемом стандарте ANSI, принятом в Windows для представления символов.

Стандарты кодов символов

Для перекодировки строки символов, закрытой двоичным нулем, из набора ANSI в набор OEM предназначена функция AnsiToOem:

void WINAPI AnsiToOem(const char _huge* hpszWindowsStr,

   char _huge* hpszOemStr);

Первый параметр (hpszWindowsStr) представляет собой указатель типа _huge на преобразуемую строку, второй (hpszOemStr) - на буфер для записи результата преобразования.

Похожая по назначению функция AnsiToOemBuff выполняет преобразование буфера заданного размера:

void WINAPI AnsiToOemBuff(LPCSTR lpszWindowsStr,

  LPSTR lpszOemStr, UINT cbWindowsStr);

Первый параметр этой функции (lpszWindowsStr) является дальним указателем на буфер, содержащий преобразуемые данные, второй (lpszOemStr) - на буфер для записи результата. Третий параметр (cbWindowsStr) определяет размер входного буфера, причем нулевой размер соответствует буферу длиной 64 Кбайт (65536 байт).

Обратное преобразование выполняется функциями OemToAnsi и OemToAnsiBuff:

void WINAPI OemToAnsi(const char _huge* hpszOemStr,

  char _huge* lpszWindowsStr);

void WINAPI OemToAnsiBuff(LPCSTR lpszOemStr,

  LPSTR lpszWindowsStr, UINT cbOemStr);

Назначение параметров этих функций аналогично назначению параметров функций AnsiToOem и AnsiToOemBuff.

Для преобразований символов в строчные или прописные приложение Windows должно пользоваться функциями AnsiLower, AnsiLowerBuff, AnsiUpper, AnsiUpperBuff.

Функция AnsiLower преобразует закрытую двоичным нулем текстовую строку в строчные буквы:

LPSTR WINAPI AnsiLower(LPSTR lpsz);

Единственный параметр функции - дальний указатель на преобразуемую строку.

Функция AnsiUpper преобразует закрытую двоичным нулем текстовую строку в прописные буквы:

LPSTR WINAPI AnsiUpper(LPSTR lpsz);

Параметр функции lpsz - дальний указатель на преобразуемую строку.

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

Функция AnsiLowerBuff позволяет преобразовать в строчные буквы заданное количество символов:

UINT WINAPI AnsiLowerBuff(LPSTR lpszString, UINT cbString);

Первый параметр функции (lpszString) является указателем на буфер, содержащий преобразуемые символы, второй (cbString) определяет количество преобразуемых символов (размер буфера). Нулевой размер соответствует буферу длиной 64 Кбайт (65536 байт).

Функция возвращает количество преобразованных символов.

Функция AnsiUpperBuff позволяет преобразовать в прописные буквы заданное количество символов:

UINT WINAPI AnsiUpperBuff(LPSTR lpszString, UINT cbString);

Первый параметр функции lpszString(lpszString) является указателем на буфер, содержащий преобразуемые символы, второй (cbString) определяет количество преобразуемых символов (размер буфера). Нулевой размер соответствует буферу длиной 64 Кбайт (65536 байт).

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

Функция VkKeyScan используется для преобразования кода символа ANSI в код и состояние виртуальной клавиши:

UINT WINAPI VkKeyScan(UINT uChar);

Параметр функции определяет символ ANSI, который будет преобразован в код виртуальной клавиши.

Младший байт возвращаемого значения содержит код виртуальной клавиши, старший - состояние клавиш сдвига (<Shift>, <Alt>, <Control>):

Функция OemKeyScan преобразует символ OEM в скан-код и состояние для набора OEM:

DWORD WINAPI OemKeyScan(UINT uOemChar);

Параметр функции определяет символ OEM, который будет преобразован в скан-код.

Младшее слово возвращаемого значения содержит OEM скан-код для указанного символа.

Старшее слово указывает состояние клавиш сдвига для заданного символа. Если в этом слове установлен бит 1, нажата клавиша <Shift>, если бит 2 - клавиша <Control>.

Если преобразуемое значение не принадлежит к набору OEM, возвращается значение -1 (и в старшем, и в младшем слове).

Текстовый курсор

Если ваше приложение создает свой собственный текстовый редактор (не пользуясь стандартным, который доступен всем приложениям Windows), вы должны сами создать текстовый курсор и заботиться о его внешнем виде, отображении и перемещении.

Заметим, что в операционной системе Windows используются два курсора. Один курсор называется cursor и означает курсор мыши. Второй курсор называется caret (знак вставки) и означает текстовый курсор.

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

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

Для создания текстового курсора обработчик сообщения WM_SETFOCUS должен вызвать функцию CreateCaret, входящую в программный интерфейс Windows:

void WINAPI CreateCaret(HWND hwnd, HBITMAP hbmp,

 int nWidth, int nHeight);

Первый параметр функции (hwnd) - идентификатор окна, создающего текстовый курсор.

Второй параметр (hbmp) может принимать значения NULL, 1 или он может быть идентификатором битового изображения курсора (bitmap). Если этот параметр равен NULL, текстовый курсор представляет собой вертикальную черту черного цвета. Если этот параметр равен 1, текстовый курсор изображается серым цветом. Третий параметр (nWidth) определяет ширину курсора в логических единицах. Четвертый параметр (nHeight) функции CreateCaret определяет высоту текстового курсора в логических единицах.

Когда функция окна получает сообщение WM_KILLFOCUS, она должна уничтожить текстовый курсор, вызвав функцию DestroyCaret:

void WINAPI DestroyCaret(void);

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

void WINAPI ShowCaret (HWND hwnd);

В качестве параметра этой функции передается идентификатор окна hwnd, создавшего текстовый курсор.

Перед тем как перерисовывать окно, приложение должно выключить (скрыть) текстовый курсор. Так как курсор постоянно мигает, если его не выключить во время перерисовки окна, изображение курсора может "размножаться" на экране. Функция BeginPaint самостоятельно скрывает курсор, но, если вы перерисовываете окно во время обработки других сообщений, курсор необходимо выключить (но не уничтожить!), вызвав функцию HideCaret:

void WINAPI HideCaret(HWND hwnd);

В качестве параметра этой функции передается идентификатор окна hwnd, создавшего текстовый курсор.

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

void WINAPI SetCaretPos(int x, int y);

Первый параметр этой функции определяет горизонтальную X-координату курсора, второй - вертикальную Y-координату курсора.

Для получения текущих координат текстового курсора следует воспользоваться функцией GetCaretPos:

void WINAPI GetCaretPos(POINT FAR* lppt);

Единственный параметр этой функции lppt указывает на структуру типа POINT, в которую будет записана информация о расположении курсора. Тип POINT описан в файле windows.h:

typedef struct tagPOINT {

  int x;

  int y;

} POINT;

После возврата из функции GetCaretPos поля x и y структуры будут содержать соответственно X- и Y-координаты текстового курсора.

Функция GetCaretBlinkTime возвращает период мигания текстового курсора в миллисекундах:

UINT WINAPI GetCaretBlinkTime(void);

С помощью функции SetCaretBlinkTime вы можете установить новое значение периода мигания курсора, указав его в качестве параметра функции (также в миллисекундах):

void WINAPI SetCaretBlinkTime(UINT uMSeconds);

Курсор мыши

В отличие от текстового курсора курсор мыши можно перемещать не только с помощью специальных функций, но и вручную.

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

При регистрации класса окна мы задавали форму курсора следующим способом:

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

Второй параметр функции LoadCursor в нашем случае выбирает одну из предопределенных форм курсора, а именно стандартный курсор в виде стрелки.

Возможные значения для выбора предопределенных форм курсора

Символическое имя

Описание

IDC_ARROW

Стандартный курсор в виде стрелки

IDC_CROSS

Курсор в виде перекрещивающихся линий

IDC_IBEAM

Текстовый курсор в виде буквы "I"

IDC_ICON

Пустая пиктограмма

IDC_SIZE

Курсор в виде четырех стрелок, указывающих в разных направлениях

IDC_SIZENESW

Двойная стрелка, указывающая в северо-восточном и юго-западном направлении

IDC_SIZENS

Двойная стрелка, указывающая в севером и южном направлении

IDC_SIZENWSE

Двойная стрелка, указывающая в северо-западном и юго-восточном направлении

IDC_SIZEWE

Двойная стрелка, указывающая в восточном и западном направлении

IDC_UPARROW

Вертикальная стрелка

IDC_WAIT

Курсор в виде песочных часов

Для того чтобы можно было изменить форму курсора, прежде всего надо загрузить новый курсор при помощи функции LoadCursor, которая входит в программный интерфейс Windows:

HCURSOR WINAPI LoadCursor(HINSTANCE hinst,

     LPCSTR lpszCursor);

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

Если же в качестве первого параметра указать значение NULL, для загрузки курсора можно использовать перечисленные выше символические имена с префиксом IDC_.

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

Функция LoadCursor возвращает идентификатор загруженного курсора или NULL при ошибке.

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

HCURSOR WINAPI SetCursor(HCURSOR hcur);

Параметр hcur функции SetCursor должен указывать идентификатор нового курсора, подготовленный при помощи функции LoadCursor. Если указать параметр как NULL, изображение курсора исчезнет с экрана.

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

int WINAPI ShowCursor(BOOL fShow);

Для включения курсора в качестве параметра fShow функции следует передать значение TRUE, для выключения - FALSE.

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

void WINAPI SetCursorPos(int x, int y);

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

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

void WINAPI GetCursorPos(POINT FAR* lppt);

Эта функция записывает в поля x и y структуры типа POINT соответственно горизонтальную и вертикальную координату курсора мыши.

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

void WINAPI ClipCursor(const RECT FAR* lprc);

В качестве параметра lprc функции передается указатель на структуру типа RECT, в которой указываются координаты области ограничения. Как только необходимость в ограничении пропадет, следует освободить движение мыши, вызвав функцию ClipCursor с параметром NULL.

Программный интерфейс Windows содержит функцию GetClipCursor, с помощью которой можно определить расположение и размер области, ограничивающей движение курсора:

void WINAPI GetClipCursor(RECT FAR* lprc);

В качестве параметра lprc функции передается указатель на структуру типа RECT, в которую будут записаны координаты области ограничения.


 

А также другие работы, которые могут Вас заинтересовать

75746. Действие электрического тока на организм человека. Скрытая опасность поражения. Внешнее (местное) поражение, электрический удар (внутреннее поражение). Факторы, от которых зависит степень поражения 19.76 KB
  Действие электрического тока на организм человека. Сила тока в участке цепи прямо пропорциональна разности потенциалов то есть напряжению на концах участка и обратно пропорциональна сопротивлению участка цепи. Действие электрического тока на живую ткань носит разносторонний характер. При термическом действии происходит перегрев и функциональное расстройство органов на пути прохождения тока.
75747. Физиологическое воздействие электрического тока на организм человека и его последствия. Сопротивление организма человека прохождению электрического тока 18.05 KB
  Сопротивление организма человека прохождению электрического тока. Проходя через тело ток действует двояко: во-первых встречая сопротивление тканей он превращается в тепло которое тем больше чем больше сопротивление. Наиболее велико сопротивление кожи вследствие чего возникают её ожоги от незначительных местных изменений до тяжёлых ожогов вплоть до обугливания отдельных участков тела; во-вторых ток приводит мышцы в частности дыхательные и сердечные в состояние длительного сокращения что может вызвать остановку дыхания и прекращение...
75748. Условия поражения человека электрическим током 14.92 KB
  Условия поражения человека электрическим током Возникновение электро-травмы в результате воздействия электрического тока и электрической дуги может быть связано: с однофазным однополюсным прикосновением не изолированного от земли основания человека к неизолированным токоведущим частям электроустановок находящихся под напряжением...
75749. Защитные мероприятия от поражения людей электрическим током 18.15 KB
  Электробезопасность обеспечивается: конструкцией электроустановок; техническими способами и средствами защиты; организационными и техническими мероприятиями. Технические способы и средства защиты. Для обеспечения электробезопасности применяют отдельно или в сочетании друг с другом следующие технические средства и способы: защитное заземление; зануление; выравнивание потенциалов; малое напряжение; электрическое разделение сетей; защитное отключение; изоляцию токоведущих частей рабочая дополнительная усиленная двойная; компенсацию токов...
75750. Виды производственных помещений по степени опасности поражения людей электрическим током 14.95 KB
  Виды производственных помещений по степени опасности поражения людей электрическим током. Определяют в отношении опасности поражения людей электрическим током следующие классы помещений: Помещения без повышенной опасности в которых отсутствуют условия создающие повышенную или особую опасность. Особо опасные помещения характеризующиеся наличием одного из следующих условий создающих особую опасность: особой сырости; химически активной или органической среды; одновременно двух или более условий повышенной опасности. В отношении...
75751. Понятие защитного заземления и принцип его действия. Виды заземляющих устройств 12.29 KB
  Понятие защитного заземления и принцип его действия. Назначение заземления устранение опасности поражения электротоком в случае соприкосновения к корпусу. Расчет заземления производится по допустимым напряжениям прикосновения и шага или допустимому сопротивлению растекания тока заземлителя. Расчет заземления имеет целью установить главные параметры заземления число вертикальных заземлителей и их размеров порядок размещения заземлителей длины заземляющих проводников и их сечения.
75752. Средства индивидуальной защиты при обслуживании потребителей электрической энергии 12.54 KB
  Средства индивидуальной защиты при обслуживании потребителей электрической энергии. Электротехническими средствами индивидуальной защиты называют приборы аппараты приспособления и устройства служащие для защиты персонала от поражения электрическим током воздействия электромагнитного поля ожогов электрической дугой. Основными называют такие средства защиты изоляция которых надежно выдерживает рабочее напряжение электроустановок. Основными средствами индивидуальной защиты служат: а в установках 1000 В и ниже клещи токоизмерительные...
75753. Организация пожарной охраны в городах, промышленности и сельской местности 17.31 KB
  Организация пожарной охраны в городах промышленности и сельской местности. Рекомендации основываются на Федеральном законе О пожарной безопасности постановлениях Правительства Российской Федерации принятых во исполнение Федерального закона О пожарной безопасности соглашениях о взаимодействии между МВД России и федеральными органами службами а также министерствами ведомствами и департаментами. При организации пожаротушения в сельской местности следует также руководствоваться другими утвержденными в установленном порядке нормативными...
75754. Химический процесс горения. Факторы, обеспечивающие процесс горения. Основные принципы тушения возгораний 14.17 KB
  Химический процесс горения. Факторы обеспечивающие процесс горения. Для протекания процесса горения требуется наличие трех факторов: горючего вещества окислителя и источника зажигания. Полное при избытке кислорода продукты горения не способны к дальнейшему окислению.