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, в которую будут записаны координаты области ограничения.


 

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

54249. Своеобразие индийской культуры 15.18 KB
  Индийская культура является одной из самых оригинальных и уникальных. Ее самобытность заключается прежде всего в богатстве и многообразии религиозно-философских учений.
54250. МАТЕМАТИЧНА СКРИНЬКА 109.5 KB
  Хто перший назве число 100? Грають двоє. Один називає будь-яке число від 1 до 9 включно. Другий додає до названого числа будь-яке ціле число від 1 до 9 включно на свій вибір і називає суму. До цієї суми перший знову додає будь-яке ціле число від 1 до 9 включно на свій вибір і називає суму, і так далі… Виграє той, хто назве число 100.
54251. Определение квадратного уравнения. Неполные квадратные уравнения и их решения 2.57 MB
  Неполные квадратные уравнения и их решения. Цель: Ввести понятия квадратного уравнения неполного квадратного уравнения. Сформировать умения различать квадратные уравнения определять коэффициенты квадратного уравнения и по ним определять вид квадратного уравнения.
54252. Математика – це цікаво! Математика – це потрібно! 59 KB
  Математика – це цікаво Математика – це потрібно Важко обійтися сьогодні без математики Усім – і дрослим і дітям – потрібна її допомога у повсякденному житті. Колись в Америці було обіцяно велику премію тому хто напише книжку під назвою Як людина жила без математикиâ€. За більше ніж 30 років викладання математики в школі я переконалася що одним із шляхів удосконалення навчання учнів такому складному предмету є нетрадиційність у його репрезентації школярам.
54253. Властивості степеня з цілим показником 795 KB
  Властивості степеня з цілим показником. Сформувати прикладну необхідність вивчення властивостей степеня з натуральним показником. Які операції ви вмієте виконувати над числами Прочитати число; записати; порівняти; додати; відняти; помножити; поділити; піднести до степеня. Які саме вирази ми зараз вивчаємо Вирази зі степенями То які операції нам потрібно вміти виконувати над виразами зі степенями Прочитати вирази зі степенями; записати; порівняти; додати; відняти; помножити; поділити; піднести до степеня.
54254. Функціональна залежність в системі прикладних задач шкільного курсу математики 631.08 KB
  Стаття містить приклад класифікації прикладних задач та аналіз способу їх розв’язання, узагальнений алгоритм розв’язування задач прикладного характеру. Основне її завдання спонукати використання прикладних задач при вивченні функціональної лінії шкільного курсу математики.
54255. Письмове додавання трицифрових чисел із переходом через розряд 716 KB
  Ознайомити учнів із прийомом письмового додавання трицифрових чисел з переходом через розряд; формувати навички письмового додавання і віднімання трицифрових чисел; виховувати почуття взаємодопомоги, вміння працювати в команді, аргументовано відстоюючи власну думку; розвивати охайність при виконанні робіт.
54256. Відсоткові розрахунки, Один день праці на підприємстві 102.5 KB
  Мета уроку: Формування в учнів вмінь самостійно визначати тип задачі на відсотки та навичок обчислень відсотка від числа, числа за його відсотком та відсоткового відношення двох чисел; розкрити практичну необхідність вивчення теми «Відсотки» в шкільному курсі; розвивати інтерес до математики, прагнення до самовдосконалення; виховувати почуття колективізму та відповідальності перед колективом.