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


 

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

77001. Административное расследование. Основания для проведения, процессуальное оформление, сроки расследования 27.67 KB
  Составлению протокола об административном правонарушении может предшествовать административное расследовании на основании определения вынесенного должностным лицом уполномоченным составлять такой протокол за предусмотренные КоАП РФ административные правонарушения: монопольного валютного законодательства законодательства о защите прав потребителей охраны окружающей среды пожарной безопасности дорожного движения и на транспорте и др. Административное расследование проводится если осуществляются экспертиза или иные процессуальные...
77002. Место и порядок подготовки дела об административном правонарушении к рассмотрению, разрешаемые вопросы и процессуальное оформление принятого решения 27.19 KB
  Место и порядок подготовки дела об административном правонарушении к рассмотрению разрешаемые вопросы и процессуальное оформление принятого решения. Рассмотрение дела по существу начинается с момента получения субъектом административной юрисдикции протокола об административном правонарушении за которым следует подготовка дела к рассмотрению. Субъекты юрисдикции в порядке подготовки к рассмотрению дела выясняют: относится ли к их компетенции рассмотрение дела; имеются ли обстоятельства исключающие рассмотрение ими дела; правильно ли...
77003. Порядок рассмотрения и разрешения дела об административном правонарушении, сроки рассмотрения, решения, принимаемые по результатам рассмотрения дела 26.52 KB
  Порядок рассмотрения и разрешения дела об административном правонарушении сроки рассмотрения решения принимаемые по результатам рассмотрения дела. Подготовка к рассмотрению дела об административном правонарушении Судья орган должностное лицо при подготовке к рассмотрению дела об административном правонарушении выясняют следующие вопросы: 1 относится ли к их компетенции рассмотрение данного дела; 2 имеются ли обстоятельства исключающие возможность рассмотрения данного дела судьей членом коллегиального органа должностным лицом; 3...
77004. Содержание постановлений и определений, принятых по результатам рассмотрения дела об административном правонарушении 27.61 KB
  Содержание постановлений и определений принятых по результатам рассмотрения дела об административном правонарушении. По результатам рассмотрения дела об административном правонарушении может быть вынесено постановление. В постановлении по делу об административном правонарушении должны быть указаны: должность фамилия имя отчество судьи должностного лица наименование и состав коллегиального органа вынесших постановление; дата и место рассмотрения дела; сведения о лице в отношении которого рассмотрено дело; обстоятельства...
77005. Обжалование и опротестование постановления по делу об административном правонарушении. Порядок и сроки обжалования (опротестования). Виды принимаемых решений 27.86 KB
  Обжалование и опротестование постановления по делу об административном правонарушении. Пересмотр постановлений и решений по делам об административных правонарушениях Правом на обжалование постановлений по административному делу обладают: лицо в отношении которого ведется административное дело; потерпевший; законный представитель физического лица; законный представитель юридического лица; защитник и представитель Постановление по делу об административном правонарушении может быть обжаловано: вынесенное судьей в вышестоящий суд;...
77006. Порядок вступления в силу вынесенного постановления. Основные положения исполнения постановления по делу об административном правонарушении 27.28 KB
  Основные положения исполнения постановления по делу об административном правонарушении. На стадии исполнения завершается производство исполняются принятые по делам постановления решения осуществляется карательное воздействие. Поэтому на стадии исполнения появляется много новых участников производства действуют особые принципы специфичны и содержание деятельности субъектов власти и статус наказанного. Отношения возникающие на стадии исполнения постановлений о привлечении виновных юридических и физических лиц к административной...
77007. Особенности исполнения отдельных видов административных наказаний 27.01 KB
  Постановление о назначении административного наказания в виде предупреждения исполняется судьей органом должностным лицом вынесшими постановление путем вручения или направления копии постановления Исполнение постановления о наложении административного штрафа. Административный штраф должен быть уплачен лицом привлеченным к административной ответственности не позднее тридцати дней со дня вступления постановления о наложении административного штрафа в законную силу либо со дня истечения срока отсрочки или срока рассрочки. Сумма...
77008. Отсрочка и рассрочка исполнения постановления по делу об административном правонарушении Случаи прекращения исполнения постановления о назначении административного наказания 26.04 KB
  Отсрочка и рассрочка исполнения постановления по делу об административном правонарушении Случаи прекращения исполнения постановления о назначении административного наказания. При наличии обстоятельств вследствие которых исполнение постановления о назначении административного наказания в виде административного ареста лишения специального права или в виде административного штрафа невозможно в установленные сроки судья орган должностное лицо вынесшие постановление могут отсрочить исполнение постановления на срок до одного месяца....
77009. Законность и дисциплина в сфере государственного управления: понятие, сущность. Виды способов обеспечения законности и дисциплины в управленческой деятельности 27.02 KB
  Виды контрольной деятельности: 1 по субъектам: контроль осуществляемый Счетной палатой Федерального Собрания РФ; контроль Министерства по налогам и сборам РФ; контроль Министерства финансов РФ; судебный контроль; 2 по методам: контроль документов издаваемых участниками управленческой деятельности; проверка непосредственно самой деятельности; 3 по времени осуществления: предварительные проверки осуществляемые до реализации субъектов административных правоотношений своих прав и обязанностей; текущие проверки в процессе...