Win32 API. Быстрые клавиши

ОГЛАВЛЕНИЕ

В Microsoft Windows, ускоритель клавиатуры (keyboard accelerator) (или, просто, акселератор) - это нажатие клавиши или комбинация нажатий клавиш, которые генерирует для прикладной программы сообщение WM_COMMAND или WM_SYSCOMMAND.

 

Об ускорителях клавиатуры

Акселераторы тесно связаны с меню - оба обеспечивают пользователю доступ к набору команд управления прикладной программой. Как правило, пользователи полагаются на меню прикладной программы, чтобы изучить набор команд, а затем переключаются на использование акселераторов, поскольку становятся более опытными в обращении с приложением. Акселераторы предоставляют быстрее прямой доступ к большему количеству команд, чем это делает меню. Как минимум, прикладная программа должна предусмотреть акселераторы для наиболее часто используемых команд. Хотя акселераторы обычно генерируют команды, которые существуют, такие как пункты меню, они также могут создавать и команды, которые не имеют подобных эквивалентных пунктов меню. 


 

Таблицы клавиш-ускорителей

Таблица клавиш – ускорителей (accelerator table) состоит из массива структур ACCEL, каждая из которых определяет конкретный акселератор. Каждая структура ACCEL включает в себя следующую информацию:

  1. Комбинацию нажатия клавиши - ускорителя.
  2. Идентификатор акселератора.
  3. Различные флажки. Эти флажки включают в себя и тот, который определяет, должен ли Windows предоставлять визуальную обратную связь, когда акселератор использован, высвечивая соответствующий пункт меню, если он есть в наличии.

Чтобы обрабатывать нажатия клавиш - акселераторов для данного потока, разработчик должен вызвать функцию TranslateAccelerator в цикле сообщения, связанном с очередью сообщений потока. Функция TranslateAccelerator контролирует ввод с клавиатуры в очереди сообщений, проверяя комбинации клавиш, которые соответствуют элементу в таблицах клавиш - ускорителей. Когда TranslateAccelerator находит соответствие, она переводит ввод с клавиатуры (то есть сообщения WM_KEYUP и WM_KEYDOWN) в сообщение WM_COMMAND или WM_SYSCOMMAND, а затем отправляет сообщение оконной процедуре определяемого окна. 

Сообщение WM_COMMAND включает в себя идентификатор клавиши-ускорителя, которая заставила TranslateAccelerator сгенерировать сообщение. Оконная процедура проверяет идентификатор, чтобы определить источник сообщения, а затем соответственно обрабатывает сообщение.

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

Windows поддерживает также и таблицы клавиш – ускорителей для каждой прикладной программы. Приложение может определять любое число таблиц акселераторов для использования своими собственными окнами. Уникальный 32-разрядный дескриптор (HACCEL) идентифицирует каждую таблицу. Однако только одна таблица клавиш – ускорителей одновременно может быть активна для данного потока. Дескриптор таблицы клавиш - ускорителей, передаваемый в функцию TranslateAccelerator, определяет, какая таблица акселераторов является активной для потока. Активная таблица акселераторов может быть переопределена в любое время, при помощи передачи соответствующего дескриптора таблицы клавиш-ускорителей в TranslateAccelerator.

 

Создание таблиц клавиш ускорителей

Требуются несколько шагов, чтобы создать таблицу клавиш-ускорителей для прикладной программы. Сначала используется транслятор ресурса, чтобы создать ресурсы таблиц акселераторов и добавить их к исполняемому файлу приложения. Во время запуска программы, функция LoadAccelerators используется, чтобы загрузить таблицу клавиш-ускорителей в память и получить ее дескриптор. Этот дескриптор передается в функцию TranslateAccelerator, чтобы активизировать таблицу клавиш-ускорителей.

Таблица акселераторов также может быть создана для приложения и во время выполнения программы, при помощи передачи массива структур ACCEL в функцию CreateAcceleratorTable. Этот метод поддерживает определяемые пользователем акселераторы в прикладной программе. Подобно функции LoadAccelerators, CreateAcceleratorTable возвращает дескриптор таблицы клавиш-ускорителей, который может быть передан в TranslateAccelerator, чтобы привести в действие таблицу акселераторов.

Windows автоматически разрушает таблицы клавиш-ускорителей, загруженные LoadAccelerators. Таблица акселераторов, созданная CreateAcceleratorTable должна быть разрушена до того, как прикладная программа закроется; иначе, таблица продолжает существовать в памяти и после того, как приложение закрылась. Таблица клавиш-ускорителей разрушается, при помощи вызова функцию DestroyAcceleratorTable.

Существующая таблица клавиш-ускорителей может быть скопирована и модифицирована. Существующая таблица клавиш-ускорителей копируется, при помощи использования функции CopyAcceleratorTable. После того, как копия модифицирована, дескриптор новой таблицы акселераторов извлекается при помощи вызова CreateAcceleratorTable. В конечном итоге, дескриптор отправляется в TranslateAccelerator, чтобы активизировать новую таблицу.

 

Присваивание нажатий клавиш - ускорителей

Чтобы определить клавишу - ускоритель, может быть использован код символа ASCII или код виртуальной клавиши. Код символа ASCII делает клавишу - ускоритель чувствительной к регистру. Символ ASCII "C" может определять акселератор как ALT+c, а не ALT+C. Однако чувствительные к регистру клавиши - акселераторы могут быть сложными для использования. Например, клавиша - акселератор ALT+C будет сгенерирована, если клавиша CAPS LOCK или SHIFT - нажата, но не в случае, если нажаты обе.

Как правило, клавиши - ускорители не должны быть чувствительными к регистру, так как большинство прикладных программ используют не коды символов ASCII, а коды виртуальной клавиши для клавиш - ускорителей.

Избегайте клавиш - ускорителей, которые находятся в противоречии с мнемоникой меню прикладной программы, потому что клавиша - ускоритель отменяет мнемонический символ, что может запутать пользователя. Для получения дополнительной информации о меню, см. статью Меню.

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

  • ALT+ESC - Переключает в следующее приложение (для Windows версии 3.1). Переключает приложения на панели задач в Windows 95 и выше.
  • ALT+F4 - Закрывает приложение или окно.
  • ALT+HYPHEN - Открывает Системное меню для окна документа.
  • ALT+PRINT SCREEN - Копирует изображение активного окна в буфер обмена.
  • ALT+SPACEBAR - Открывает Системное меню для окна приложения.
  • ALT+TAB - Переключает в следующее приложение.
  • CTRL+ESC - Переключает список задач (для Windows версии 3.1) Эквивалентно нажатию кнопки Пуск (для Windows 95 и выше).
  • CTRL+F4 - Закрывает активную группу или окно документа.
  • F1 - Если у приложения имеется Справка (Help), запускает Справку.
  • PRINT SCREEN - Копирует изображения экрана в буфер обмена.
  • SHIFT+ALT+TAB - Переключает в предыдущее приложение. Пользователь должен нажать и удерживать нажатыми кнопки ALT+SHIFT до нажатия кнопки TAB.


Клавиши - ускорители и меню

Использование клавиши – ускорителя является тем же самым действием, что и выбор пункта меню: оба действия заставляют Windows отправлять сообщение WM_COMMAND или WM_SYSCOMMAND в соответствующую оконную процедуру. Сообщение WM_COMMAND включает в себя идентификатор, который оконная процедура проверяет, чтобы определить источник сообщения. Если сообщение WM_COMMAND создал акселератор, то идентификатор – для этой клавиши - ускорителя. Точно так же, если сообщение WM_COMMAND создал пункт меню, то идентификатор - этого пункта меню. Поскольку акселератор предусматривает ярлык для выбора команды из меню, прикладная программа обычно присваивает тот же самый идентификатор и для клавиши - ускорителя и соответствующему пункту меню.

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

Идентификатор определяет, генерирует ли клавиша - ускоритель сообщение WM_SYSCOMMAND или WM_COMMAND. Если идентификатор имеет то же самое значение, что и пункт меню в Системном меню, акселератор создает сообщение WM_SYSCOMMAND. В противном случае, клавиша - ускоритель генерирует сообщение WM_COMMAND.

Если клавиша - ускоритель имеет тот же самый идентификатор, что и пункт меню, а пункт меню недоступен или заблокирован, акселератор блокируется и не генерирует сообщение WM_SYSCOMMAND или WM_COMMAND. Клавиша – ускоритель также не генерирует сообщение команды, если соответствующее окно свернуто.

Когда пользователь использует клавишу - ускоритель, которая соответствует пункту меню, оконная процедура принимает сообщения WM_INITMENU и WM_INITMENUPOPUP, как если бы пользователь выбрал пункт меню. За информацией относительно того, как обрабатывать эти сообщения, обратитесь к статье. Меню.

Клавиша - ускоритель, которая соответствует пункту меню, должна быть включена в текст пункта меню.


Использование клавиш-ускорителей клавиатуры

Использование ресурса таблицы клавиш-ускорителей
Использование таблицы клавиш-ускорителей, созданной во время прогона программы

 

Использование ресурса таблицы клавиш-ускорителей

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

  1. Создайте таблицу клавиш-ускорителей в файле определения ресурса. Компилируйте его и добавьте итоговый ресурс к исполняемому файлу вашей прикладной программы.
  2. Включите вызов функции LoadAccelerators, чтобы загрузить ресурс таблицы клавиш-ускорителей и примите дескриптор таблицы клавиш-ускорителей.
  3. Добавьте функцию TranslateAccelerator к циклу сообщения, связанному с таблицей клавиш-ускорителей.
  4. Организуйте обработку создаваемого сообщения WM_COMMAND, когда пользователь использует клавишу - ускоритель. 

Создание ресурса таблицы клавиш-ускорителей

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

Каждая клавиша - ускоритель, которую Вы определяете, требует отдельного элемента в таблице клавиш-ускорителей. В каждом элементе, Вы определяете нажатие клавиши (или код символа ASCII или код виртуальной клавиши), который создает клавишу - ускоритель и ее идентификатор. Вы должны также определить, должно ли нажатие клавиши быть использовано в некоторой комбинации с клавишами ALT, SHIFT или CTRL. Для получения дополнительной информации о виртуальных клавишах, см. статью Ввод с клавиатуры.

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

"A", ID_ACCEL1         ; SHIFT+A
65, ID_ACCEL2, ASCII ; SHIFT+A

Нажатие клавиши с виртуальным кодом определяется, по-другому и зависит от того, является ли нажатая клавиша алфавитно-цифровой клавишей или не алфавитно-цифровой. Для алфавитно-цифровой клавиши, символ клавиши или число, заключается в двойные кавычки, объединяется с флажком VIRTKEY. Для не алфавитно-цифровой клавиши, виртуальный Windows код для заданной клавиши объединяется с флажком VIRTKEY. Следующие примеры показывают, как определить клавиши - ускорители с кодом виртуальной клавиши.

"a",       ID_ACCEL3, VIRTKEY   ; A (клавиша заглавных букв вкл.) или a
VK_INSERT, ID_ACCEL4, VIRTKEY ; клавиша INSERT

Следующий пример показывает ресурс таблицы клавиш-ускорителей, который определяет клавиши - ускорители для операций с файлами. Название ресурса - FileAccel.

FileAccel ACCELERATORS
BEGIN
VK_F12, IDM_OPEN, CONTROL, VIRTKEY ; CTRL+F12
VK_F4, IDM_CLOSE, ALT, VIRTKEY ; ALT+F4
VK_F12, IDM_SAVE, SHIFT, VIRTKEY ; SHIFT+F12
VK_F12, IDM_SAVEAS, VIRTKEY ; F12
END

Если Вы хотите, чтобы пользователь нажимал клавиши ALT, SHIFT или CTRL в некоторой комбинации с нажатием клавиши - ускорителя, установите флажки ALT, SHIFT и CONTROL в определении клавиши - ускорителя. Ниже следуют - некоторые примеры.

"B",   ID_ACCEL5, ALT                   ; ALT_SHIFT+B
"I", ID_ACCEL6, CONTROL, VIRTKEY ; CTRL+I
VK_F5, ID_ACCEL7, CONTROL, ALT, VIRTKEY ; CTRL+ALT+F5

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

VK_DELETE, ID_ACCEL8, VIRTKEY, SHIFT, NOINVERT ;SHIFT+DELETE 

Чтобы определить клавиши - ускорители, которые соответствуют пунктам меню в вашей прикладной программе, клавиши - ускорители включают в текст пунктов меню. Следующий пример показывает, как включить клавиши - ускорители в текст пункта меню в файле определения ресурса.

FilePopup MENU
BEGIN
POPUP "&File"
BEGIN
  MENUITEM "&New..", IDM_NEW
  MENUITEM "&Open\tCtrl+F12", IDM_OPEN
  MENUITEM "&Close\tAlt+F4" IDM_CLOSE
  MENUITEM "&Save\tShift+F12", IDM_SAVE
  MENUITEM "Save &As...\tF12", IDM_SAVEAS
END
END

Загрузка ресурса таблицы клавиш-ускорителей

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

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

Вызов функции TranslateAccelerator

Чтобы обрабатывать клавиши - ускорители, цикл сообщения прикладной программы (или потока) должен содержать вызов функции TranslateAccelerator. TranslateAccelerator сравнивает нажатия клавиши с таблицей клавиш-ускорителей и, если она находит соответствие, переводит нажатия клавиш в сообщения WM_COMMAND (или WM_SYSCOMMAND). Затем функция отправляет сообщение оконной процедуре. Параметры функции TranslateAccelerator включают в себя дескриптор окна, которое должно принять сообщения WM_COMMAND, дескриптор таблицы клавиш-ускорителей, использованной трансляции клавиш - ускорителей и указатель на структуру MSG, содержащую сообщение из очереди. Следующий пример показывает, как вызвать TranslateAccelerator изнутри цикла сообщения.

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
/* Проверка нажатия клавиши-ускорителя. */

if (!TranslateAccelerator(
  hwndMain, /* дескриптор окна - приемника */
  haccel, /* дескриптор таблицы активной клавиши-ускорителя */
  &msg)) /* адрес данных сообщений */
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}
}


Обработка сообщений WM_COMMAND

Когда используется клавиша - ускоритель, окно, определенное в функции TranslateAccelerator принимает сообщение WM_SYSCOMMAND или WM_COMMAND. Младшее слово параметра wParam содержит идентификатор акселератора. Оконная процедура проверяет идентификатор, чтобы решить, какой источник посылает сообщение WM_COMMAND и соответственно обрабатывает сообщение.

Как правило, если клавиша - ускоритель соответствует пункту меню в прикладной программе, ей и пункту меню назначается один и тот же идентификатор. Если Вам нужно знать, было ли данное сообщение WM_COMMAND создано акселератором или пунктом меню, Вы можете проверить старшее слово параметра wParam. Если сообщение генерировала клавиша - ускоритель, старшее слово равно 1; если сообщение создал пункт меню, старшее слово - 0.


Уничтожение ресурса таблицы клавиш-ускорителей

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


Создание клавиш - ускорителей для атрибутов шрифта

Пример в этом разделе показывает, как исполнить следующие задачи:

  1. Создать ресурс таблицы клавиш-ускорителей.
  2. Загрузить таблицу акселераторов во время прогона программы.
  3. Преобразовать клавиши - ускорители в цикле сообщений.
  4. Обработать сообщения WM_COMMAND, сгенерированные акселераторами.

Эти задачи демонстрируются применительно к прикладной программе, которая включает в себя меню Символ (Character) и соответствующие клавиши - ускорители, которые позволяют пользователю выбирать атрибуты текущего шрифта.

Нижеследующая часть файла определения ресурса определяет меню Character и связанную с ним таблицу клавиш-ускорителей.

Обратите внимание!, что пункты меню показывают нажатие клавиши - ускорителя и то, что каждый акселератор имеет тот же самый идентификатор, что и связанный с ним пункт меню.

#include <windows.h>
#include "acc.h"

MainMenu MENU
BEGIN
POPUP "&Character"
BEGIN
  MENUITEM "&Regular\tF5", IDM_REGULAR
  MENUITEM "&Bold\tCtrl+B", IDM_BOLD
  MENUITEM "&Italic\tCtrl+I", IDM_ITALIC
  MENUITEM "&Underline\tCtrl+U", IDM_ULINE
END
END

FontAccel ACCELERATORS
BEGIN
VK_F5, IDM_REGULAR, VIRTKEY
"B", IDM_BOLD, CONTROL, VIRTKEY
"I", IDM_ITALIC, CONTROL, VIRTKEY
"U", IDM_ULINE, CONTROL, VIRTKEY
END

Следующий раздел исходного файла приложения показывает как реализовать акселератор:

HWND hwndMain; /* дескриптор главного окна */
HANDLE hinstAcc; /*дескриптор экземпляра приложения */

int WINAPI WinMain(hinst, hinstPrev, lpCmdLine, nCmdShow)
HINSTANCE hinst;
HINSTANCE hinstPrev;
LPSTR lpCmdLine;
int nCmdShow;
{
MSG msg; /* сообщения прикладной программы */
HACCEL haccel; /* дескриптор таблицы клавиш-ускорителей */


.
. /* Исполнение процедуры инициализации */
.

/* создание главного окна для этого экземпляра приложения. */

hwndMain = CreateWindowEx(0L, "MainWindowClass",
  "Sample Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
  hinst, NULL );

/* Если окно невозможно создать возвращается значение "failure." -неудача. */

if (!hwndMain) return FALSE;

/* Сделаем окно видимым и обновим его рабочую область. */

ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);

/* Загрузим таблицу клавиш-ускорителей. */

haccel = LoadAccelerators(hinstAcc, "FontAccel");
if (haccel == NULL)
  HandleAccelErr(ERR_LOADING); /* заданное приложение */

/*
* Получим и отправим по назначению сообщения, пока не принято сообщение WM_QUIT.
* .
*/


while (GetMessage(&msg, NULL, NULL, NULL)) {
  /* Проверка нажата ли клавиша-ускоритель. */
  if (!TranslateAccelerator(
   hwndMain, /* дескриптор окна-приемника */
   haccel, /* дескриптор таблицы активного акселератора */
   &msg)) { /* адрес данных для сообщений */
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
}
return msg.wParam;
}

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
BYTE fbFontAttrib; /* массив флажков атрибутов шрифта */
static HMENU hmenu; /* дескриптор главного меню */

switch (uMsg) {

  case WM_CREATE:
   /*
   * Прибавим галочку к пункту меню Regular, чтобы указать, что это - значение по
   *. умолчанию.
   */


   hmenu = GetMenu(hwndMain);
   CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND | MF_CHECKED);
   return 0;

  case WM_COMMAND:
   switch (LOWORD(wParam)) {
    /* Обработаем клавишу - ускоритель и команды меню

    case IDM_REGULAR:
    case IDM_BOLD:
    case IDM_ITALIC:
    case IDM_ULINE:

    /*
    * GetFontAttributes - это функция, определяемая программой
    * функция, которая выставляет метки пунктам меню
    * и возвращает атрибуты шрифта, выбранные пользователем.
    */

     fbFontAttrib = GetFontAttributes(
     (BYTE) LOWORD(wParam), hmenu);


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


     SetFontAttributes(fbFontAttrib);
     break;

    default:
     break;
   }
   break;

   .
   . /* Обработка других сообщений. */
   .


  default:
   return DefWindowProc(hwndMain, uMsg, wParam, lParam);
}
return NULL;
}


Использование таблицы клавиш-ускорителей, созданной во время прогона программы

Win32 прикладной программный интерфейс (API) позволяет Вам создавать таблицы клавиш-ускорителей во время прогона программы. Шаги, включенные в создание и использование таблицы акселераторов во время прогона программы следующие:

Определение клавиш - ускорителей при помощи заполнения массива структур ACCEL, а затем создание таблицы клавиш-ускорителей, посредством передачи массива в функцию CreateAcceleratorTable.

Активизация таблицы клавиш-ускорителей и обработка сообщений WM_COMMAND, сгенерированных акселераторами.

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

Создание таблицы клавиш-ускорителей

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

typedef struct tagACCEL {	// accl
BYTE fVirt;
WORD key;
WORD cmd;
} ACCEL;

Вы определяете нажатие клавиши - ускорителя, при помощи установки кода буквы ASCII или кода виртуальной клавиши в члене key структуры ACCEL. Если Вы определяете код виртуальной клавиши, Вы должны сначала включить флажок FVIRTKEY в члене fVirt; иначе, Windows поймет код как код буквы ASCII. Вы можете включить флажок FCONTROL, FALT или FSHIFT, или все три, чтобы комбинировать с нажатиями клавиш клавиши CTRL, ALT или SHIFT.

Чтобы создать таблицу клавиш-ускорителей, пошлите адрес массива структур ACCEL в функцию CreateAcceleratorTable. CreateAcceleratorTable создает таблицу клавиш-ускорителей и возвращает ее дескриптор.

Обработка клавиш-ускорителей

Процесс загрузки и вызова клавиш - ускорителей, предусмотренных их таблицей, созданной во время прогона программы, аналогичен обработке этих клавиш, предусмотренных ресурсом таблицы клавиш-ускорителей. Для получения дополнительной информации, см. со статьи Загрузка ресурса таблицы клавиш-ускорителей до статьи Обработка сообщения WM_COMMAND.

Разрушение таблицы клавиш-ускорителей

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


 

Создание доступных для редактирования пользователем клавиш - ускорителей

Этот пример показывает, как создать диалоговое окно, которое позволяет пользователю изменять клавишу - ускоритель, связанную с пунктом меню. Диалоговое окно состоит из комбинированного блока содержащего пункты меню, комбинированного блока, содержащего названия клавиш и окошек для флажка "галочка" для выбора клавиш CTRL, ALT и SHIFT

Следующий пример показывает, как диалоговое окно определяется в файле определения ресурса.

EdAccelBox DIALOG 5, 17, 193, 114
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Edit Accelerators"
BEGIN
COMBOBOX  IDD_MENUITEMS, 10, 22, 52, 53,
     CBS_SIMPLE | CBS_SORT | WS_VSCROLL |
     WS_TABSTOP
CONTROL   "Control", IDD_CNTRL, "Button",
      BS_AUTOCHECKBOX | WS_TABSTOP,
      76, 35, 40, 10
CONTROL   "Alt", IDD_ALT, "Button",
      BS_AUTOCHECKBOX | WS_TABSTOP,
      76, 48, 40, 10
CONTROL   "Shift", IDD_SHIFT, "Button",
      BS_AUTOCHECKBOX | WS_TABSTOP,
      76, 61, 40, 10
COMBOBOX  IDD_KEYSTROKES, 124, 22, 58, 58,
     CBS_SIMPLE | CBS_SORT | WS_VSCROLL |
     WS_TABSTOP
PUSHBUTTON "Ok", IDOK, 43, 92, 40, 14
PUSHBUTTON "Cancel", IDCANCEL, 103, 92, 40, 14
LTEXT   "Select Item:", 101, 10, 12, 43, 8
LTEXT   "Select Keystroke:", 102, 123, 12,
     60, 8
END

Диалоговое окно использует массив определяемых программой структур VKEY, каждая из которых содержит текстовую строку о нажатии клавиши и текстовую строку о клавише - ускорителе. Когда диалоговое окно создается, оно анализирует массив и добавляет текстовую строку о каждом нажатии клавиши в комбинированный блок Выбор Нажатия клавиши (Select Keystroke). Когда пользователь щелкает по кнопке Ok, блок диалога ищет текстовую строку о выбранном нажатии клавиши и извлекает данные соответствующие текстовой строке о клавише - ускорителе. Диалоговое окно приобщает текстовую строку о клавише - ускорителе к тексту пункта меню, который выбрал пользователь. Следующий пример показывает массив структур VKEY:

/* Настройка поиска VKey */

#define MAXKEYS 26

typedef struct _VKEYS {
char *pKeyName;
char *pKeyString;
} VKEYS;

VKEYS vkeys[MAXKEYS] = {
"BkSp", "Back Space",
"PgUp", "Page Up",
"PgDn", "Page Down",
"End", "End",
"Home", "Home",
"Lft", "Left",
"Up", "Up",
"Rgt", "Right",
"Dn", "Down",
"Ins", "Insert",
"Del", "Delete",
"Mult", "Multiply",
"Add", "Add",
"Sub", "Subtract",
"DecPt", "Decimal Point",
"Div", "Divide",
"F2", "F2",
"F3", "F3",
"F5", "F5",
"F6", "F6",
"F7", "F7",
"F8", "F8",
"F9", "F9",
"F11", "F11",
"F12", "F12"
};

Процедура инициализации диалогового окна заполняет комбинированные блоки Элемент Выбора (Select Item) и Выбор Нажатия клавиши (Select Keystroke). После того, как пользователь выберет пункт меню и связанную клавишу - ускоритель, блок диалога проверяет элементы управления в диалоговом окне, чтобы получить пользовательский выбор, модифицирует текст пункта меню, а затем создает новую таблицу клавиш-ускорителей , которая содержит определенную пользователем новую клавишу - ускоритель. Следующий пример показывает эту процедуру диалогового окна.

/* Глобальные переменные */

HWND hwndMain; /* дескриптор главного окна */
HANDLE hinstAcc; /* дескриптор экземпляра приложения */
HACCEL haccel; /* дескриптор таблицы клавиши-ускорителя */

.
.

/* Процедура диалогового окна */


LRESULT CALLBACK EdAccelProc(hwndDlg, uMsg, wParam, lParam)
HWND hwndDlg;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
int nCurSel;  /* Индекс элемента окна списка */
UINT idItem;  /* Идентификатор пункта меню */
UINT uItemPos;  /* Позиция пункта меню */
UINT i, j = 0;  /* Счетчики цикла */
static UINT cItems; /* Номер элемента в меню */
char szTemp[32]; i>/* Временный буфер */
char szAccelText[32]; /* Буфер для текста клавиши-ускорителя */
char szKeyStroke[16]; /* Буфер для текста нажатой клавиши */
static char szItem[32]; /* Буфер для текста пункта меню */
HWND hwndCtl;  /* Дескриптор окна управления */
static HMENU hmenu; /* Дескриптор меню "Character" */
PCHAR pch, pch2;  /* Указатели на копируемую строку */
WORD wVKCode;  /* Код виртуальной клавиши - ускорителя */
BYTE fAccelFlags;  /* Флажки fVirt для структуры ACCEL */
LPACCEL lpaccelNew; /* Адрес новой таблицы клавишей ускорителей */
HACCEL haccelOld;  /* Адрес старой таблицы клавишей ускорителей */
int cAccelerators;  /* Число клавиш-ускорителей в таблице */
static BOOL fItemSelected = FALSE; /* Флажок выбора элемента */
static BOOL fKeySelected = FALSE; /* Флажок выбора клавиши */

switch (uMsg) {
  case WM_INITDIALOG:

  /* Получим дескриптор пункта меню комбинированного блока */
   hwndCtl = GetDlgItem(hwndDlg, IDD_MENUITEMS);

  /*
  * Строка меню прикладной программы содержит подменю "Character",
  * пункты которого присоединяют клавиши - ускорители к ним.
  * Получим дескриптор подменю "Character" "
  * (его позиция в пределах главного меню и 2),
  * и подсчет числа пунктов, которые в нем есть.
  */


   hmenu = GetSubMenu(GetMenu(hwndMain), 2);
   cItems = GetMenuItemCount(hmenu);

  /* Получим текст каждого пункта,
  * полоску из '&' и текста клавиши - ускорителя
  * и добавим текст в пункт меню комбинированный блока
  *


   for (i = 0; i < cItems; i++) {
    if (!(GetMenuString(hmenu, i, szTemp,
     sizeof(szTemp), MF_BYPOSITION)))
     continue;
    for (pch = szTemp, pch2 = szItem;
     *pch != '\0'; )
    {
     if (*pch != '&')
     {
      if (*pch == '\t')
      {
       *pch = '\0';
       *pch2 = '\0';
      } else *pch2++ = *pch++;
     } else pch++;
    }
    SendMessage(hwndCtl, CB_ADDSTRING, 0,
     (LONG) (LPSTR) szItem);
   }

   /* Теперь заполним комбинированный блок нажатия клавиши
   * списком нажатий клавиши, которые будут позволяться для клавиш - ускорителей.
   * Список нажатий клавиши находится в определяемой программой
   * структуре, называемой "vkeys".
   */


   hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);
   for (i = 0; i < MAXKEYS; i++)
    SendMessage(hwndCtl, CB_ADDSTRING, 0,
     (LONG) (LPSTR) vkeys[i].pKeyString);

   return TRUE;

  case WM_COMMAND:
   switch (LOWORD(wParam))
   {
    case IDD_MENUITEMS:

     /* Пользователь должен выбрать элемент
     * из пункта меню - комбинированного блока.
     * Этот флажок проверяется в ходе обработки IDOK,
     * чтобы убедиться, что выбор был сделан.
     */


     fItemSelected = TRUE;
     return 0;

    case IDD_KEYSTROKES:

     /*
     * Пользователь должен выбрать элемент из пунктов меню
     * комбинированного блока. Этот флажок проверяется в ходе
     * обработки IDOK, чтобы гарантировать, что выбор был сделан.
     */



     fKeySelected = TRUE;

     return 0;

    case IDOK:

     /*
     * Если пользователь не выбрал пункт меню
     * и нажал клавишу, на экране появится напоминание
     * в окне сообщений.
     */


   if (!fItemSelected || !fKeySelected)
   {
     MessageBox(hwndDlg,
     "Item or key not selected.", NULL,
      MB_OK);
      return 0;
   }

     /*
     * Определим, выбраны ли клавиши CTRL, ALT и SHIFT.
     * Свяжем соответствующие строки клавиши - ускорителя
     * с буферной памятью для хранения текста и установим
     * соответствующие флажки клавиши - ускорителя.
     */


     szAccelText[0] = '\0';

     hwndCtl = GetDlgItem(hwndDlg, IDD_CNTRL);
     if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1)
     {
      lstrcat(szAccelText, "Ctl+");
      fAccelFlags |= FCONTROL;
     }
     hwndCtl = GetDlgItem(hwndDlg, IDD_ALT);
     if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) {
      lstrcat(szAccelText, "Alt+");

      fAccelFlags |= FALT;
     }
     hwndCtl = GetDlgItem(hwndDlg, IDD_SHIFT);
     if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) {
      lstrcat(szAccelText, "Shft+");
      fAccelFlags |= FSHIFT;
     }

     /*
     * Получим выбранное нажатие клавиши и найдем
     * текст клавиши-ускорителя, и код виртуальной клавиши
     * для нажатия клавиши в структуре vkeys.
     */


     hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);
     nCurSel = (int) SendMessage(hwndCtl,
      CB_GETCURSEL, 0, 0);
     SendMessage(hwndCtl, CB_GETLBTEXT,
      nCurSel, (LONG) (LPSTR) szKeyStroke);
     for (i = 0; i < MAXKEYS; i++) {
      if(lstrcmp(vkeys[i].pKeyString,
        szKeyStroke) == 0)
      {
       lstrcpy(szKeyStroke,
        vkeys[i].pKeyName);
       break;
      }
     }

     /*
     * Свяжем текст нажатия клавиши со строкой " Ctl + ", " Alt + " или " Shft + ".
     *
     */


     lstrcat(szAccelText, szKeyStroke);


     /*
     * Установим позицию в меню
     * выбранного пункта меню. Пункты меню в
     * меню "Character" имеют позиции 0,2,3 и 4.
     */


     if (lstrcmp(szItem, "Regular") == 0)
      uItemPos = 0;
     else if (lstrcmp(szItem, "Bold") == 0)
      uItemPos = 2;
     else if (lstrcmp(szItem, "Italic") == 0)
      uItemPos = 3;
     else if (lstrcmp(szItem, "Underline") == 0)
      uItemPos = 4;

     /*
     * Получим строку символов, которая соответствует выбранному элементу.
     */


     GetMenuString(hmenu, uItemPos, szItem,
      sizeof(szItem), MF_BYPOSITION);

     /*
     * Приобщим новый текст клавиши - ускорителя к
     * тексту пункта меню.
     */


     for (pch = szItem; *pch != '\t'; pch++);
     ++pch;

     for (pch2 = szAccelText; *pch2 != '\0';
       pch2++)
      *pch++ = *pch2;
     *pch = '\0';

     /*
     * Изменим пункт меню, чтобы отразить новый
     * текст клавиши-ускорителя.
     */


     idItem = GetMenuItemID(hmenu, uItemPos);
     ModifyMenu(hmenu, idItem, MF_BYCOMMAND |
      MF_STRING, idItem, szItem);

     /* Сбросим выбранные флажки. */

     fItemSelected = FALSE;
     fKeySelected = FALSE;

     /* Сохраняем текущую таблицу клавиш ускорителей. */

     haccelOld = haccel;

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


     cAccelerators = CopyAcceleratorTable(haccelOld, NULL, 0);
     lpaccelNew = (LPACCEL) LocalAlloc(LPTR, cAccelerators * sizeof(ACCEL));

     if (lpaccelNew != NULL) CopyAcceleratorTable(haccel, lpaccelNew,cAccelerators);

     /*
     * Найдем клавишу - ускоритель, которую пользователь модифицировал
     * и изменим ее флажки и код виртуальной клавиши
     * в соответствии с этим.
     */


     for (i = 0; (lpaccelNew[i].cmd ==
        (WORD) idItem)
       && (i < (UINT) cAccelerators); i++) {

      lpaccelNew[i].fVirt = fAccelFlags;
      lpaccelNew[i].key = wVKCode;
     }

     /*
     * Создадим новую таблицу клавиш-ускорителей, а
     * старую разрушим.
     */


     DestroyAcceleratorTable(haccelOld);
     haccel = CreateAcceleratorTable(lpaccelNew,cAccelerators);

     /* Разрушим диалоговое окно. */


     EndDialog(hwndDlg, TRUE);
     return 0;

    case IDCANCEL:
     EndDialog(hwndDlg, TRUE);
     return TRUE;

    default:
     break;
   }
  default:
   break;
}
return FALSE;
}


Справочник по ускорителям клавиатуры

Следующие функции, структуры и сообщения связаны с ускорителями клавиатуры. 

Функции ускорителей клавиатуры

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

  • CopyAcceleratorTable
  • CreateAcceleratorTable
  • DestroyAcceleratorTable
  • LoadAccelerators
  • TranslateAccelerator

 

Фунция CopyAcceleratorTable

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

Синтаксис

int CopyAcceleratorTable
(
HACCEL hAccelSrc, // дескриптор копируемой таблицы клавиш-ускорителей
LPACCEL lpAccelDst, // указатель на структуру принимающую копию
int cAccelEntries // число вводов в копируемую таблицу
);

Параметры

hAccelSrc
Идентифицирует таблицу клавиш-ускорителей, которая копируется.
lpAccelDst
Указывает на массив структур ACCEL, куда информация о таблице клавиш-ускорителей должна быть скопирована.
cAccelEntries
Определяет число структур ACCEL для копирования в буфер, указанный параметром lpAccelDst.

Возвращаемые значения

Если lpAccelDst имеет значение ПУСТО (NULL), величина возвращаемого значения определяет число введенных таблиц клавиш-ускорителей в первоначальную таблицу. Иначе, он определяет число введенных таблиц клавиш-ускорителей, которые были скопированы.

Смотри также

ACCEL, CreateAcceleratorTable, DestroyAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость CopyAcceleratorTable

Windows NT  	Да 
Win95    Да
Win32s    Нет
Импортируемая библиотека  user32.lib
Заголовочный файл   winuser.h
Unicode    WinNT
Замечания по платформе  Не имеется

 

Функция CreateAcceleratorTable

Функция CreateAcceleratorTable создает таблицу клавиш-ускорителей.

Синтаксис

HACCEL CreateAcceleratorTable
(
LPACCEL lpaccl, // указатель на массив структур с данными клавиши - ускорителя
int cEntries // число структур в массиве
);

Параметры

lpaccl
Указывает на массив структур ACCEL, который описывает таблицу клавиш-ускорителей.
cEntries
Определяет число структур ACCEL в массиве.

Возвращаемые значения

Если функция завершается успешно, величина возвращаемого значения - дескриптор к созданной таблице клавиш-ускорителей; иначе, это значение ПУСТО (NULL).

Замечания

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

Смотри также

ACCEL, CopyAcceleratorTable, DestroyAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость CreateAcceleratorTable

Windows NT    Да 
Win95     Да
Win32s     Нет
Импортируемая библиотека   user32.lib
Заголовочный файл    winuser.h
Unicode     WinNT
Замечания по платформе   Не имеется


Функция DestroyAcceleratorTable

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

Синтаксис

BOOL DestroyAcceleratorTable
(
HACCEL hAccel // дескриптор таблицы клавиш-ускорителей
);

Параметры

hAccel
Идентифицирует таблицу клавиш-ускорителей, которая уничтожается. Этот дескриптор, должен быть создан при помощи вызова функции CreateAcceleratorTable.

Возвращаемые значения

Если функция завершается успешно, величина возвращаемого значения отличная от нуля.
Если функция не выполняет задачу, величина возвращаемого значения нулевая. Чтобы получить подробные данные об ошибке, вызовите GetLastError.

Смотри также

CopyAcceleratorTable, CreateAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость DestroyAcceleratorTable

Windows NT  	Да 
Win95    Да
Win32s    Нет
Импортируемая библиотека  user32.lib
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Функция LoadAccelerators

Функция LoadAccelerators загружает заданную таблицу клавиш-ускорителей.

Синтаксис

HACCEL LoadAccelerators
(
HINSTANCE hInstance, // дескриптор экземпляра приложения
LPCTSTR lpTableName // адрес строки с названием таблицы
);

Параметры

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

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

Возвращаемые значения

Если функция завершается успешно, величина возвращаемого значения - дескриптор загруженной таблицы клавиш-ускорителей.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL).

Замечания

Если таблица клавиш-ускорителей еще не была загружена, загружают ее из заданного исполняемого файла.
Таблицы клавиш-ускорителей, загруженные из ресурсов, освобождаются автоматически, когда прикладная программа заканчивает свою работу.

Смотри также

CopyAcceleratorTable, CreateAcceleratorTable, DestroyAcceleratorTable, MAKEINTRESOURCE

Размещение и совместимость LoadAccelerators

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  user32.lib
Заголовочный файл   winuser.h
Unicode    WinNT
Замечания по платформе  Не имеется


Функция TranslateAccelerator

Функция TranslateAccelerator обрабатывает клавиши - ускорители для команд меню. Функция транслирует сообщение WM_KEYDOWN или WM_SYSKEYDOWN в сообщение WM_COMMAND или WM_SYSCOMMAND (если имеется элемент для клавиши в заданной таблице клавиш-ускорителей), а затем передает сообщение WM_COMMAND или WM_SYSCOMMAND непосредственно соответствующей оконной процедуре. TranslateAccelerator не возвращает значения до тех пор, пока оконная процедура не обработает сообщение.

Синтаксис

int TranslateAccelerator
(
HWND hWnd, // дескриптор окна назначения
HACCEL hAccTable, // дескриптор таблицы клавиш-ускорителей
LPMSG lpMsg // адрес структуры с сообщением
);

Параметры

hWnd
Идентифицирует окно, сообщения которого должны быть оттранслированы.
hAccTable
Идентифицирует таблицу клавиш-ускорителей. Таблица должна быть загружена при помощи вызова функции LoadAccelerators или создана вызовом функции CreateAcceleratorTable.
lpMsg
Указывает на структуру MSG, которая содержит информацию сообщения, извлеченного из очереди сообщений вызывающего потока при помощи использования функции GetMessage или PeekMessage.

Возвращаемые значения

Если функция завершается успешно, величина возвращаемого значения - ИСТИНА (TRUE).
Если функция не выполняет задачу, величина возвращаемого значения - ЛОЖЬ(FALSE). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Замечания

Чтобы отличить сообщение, которые эта функция посылает, от сообщений, отправленных меню или элементами управления, старшее слово параметра wParam сообщения WM_COMMAND или WM_SYSCOMMAND, содержит значение 1.

Комбинации клавиш - ускорителей, используемые для выбра пунктов из меню окна, транслируются в сообщение WM_SYSCOMMAND; все другие комбинации клавиш - ускорителей транслируются в сообщения WM_COMMAND.

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

Клавише - ускорителю не обязательно надо соответствовать команде меню.

Если команда клавиши - ускорителя соответствует пункту меню, прикладная программа посылает сообщения WM_INITMENU и WM_INITMENUPOPUP, как будто пользователь попытался показать меню. Однако, эти сообщения не посылаются, если встречается какое-либо из следующих условий:

  • Окно заблокировано.
  • Пункт меню заблокирован.
  • Комбинация клавиши - ускорителя не соответствует элементу в меню окна и окно свернуто.

Фактически был произведен захват мыши. За информацией о захвате мыши, обратитесь в функцию SetCapture.

Если определяемое окно - активное окно, и никакое другое окно не имеет фокус клавиатуры (это обычно является случаем, если окно свернуто), TranslateAccelerator транслирует сообщения WM_SYSKEYUP и WM_SYSKEYDOWN вместо сообщений WM_KEYDOWN и WM_KEYUP.

Если происходит нажатие клавиши - ускорителя, которое соответствует пункту меню, когда окно, которое владеет меню, свернуто, TranslateAccelerator не отправляет сообщение WM_COMMAND. Однако, если происходит нажатие клавиши - ускорителя, которое не соответствует никакому из пунктов меню или меню окна, функция отправляет сообщение WM_COMMAND, даже если окно свернуто.

Смотри также

CreateAcceleratorTable, GetMessage, LoadAccelerators, MSG, PeekMessage, SetCapture, TranslateMessage, WM_COMMAND, WM_INITMENU, WM_INITMENUPOPUP, WM_KEYDOWN, WM_SYSKEYDOWN, WM_SYSCOMMAND

Размещение и совместимость TranslateAccelerator

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  user32.lib
Заголовочный файл   winuser.h
Unicode    WinNT
Замечания по платформе  Не имеется


Структуры ускорителя клавиатуры

Ниже следующая структура используется с клавишами - ускорителями.
ACCEL


 

Структура ACCEL

Структура ACCEL определяет клавишу - ускоритель, использованную в таблице клавиш-ускорителей.

Синтаксис

typedef struct tagACCEL { // accl
BYTE fVirt;
WORD key;
WORD cmd;
} ACCEL;

Члены структуры
fVirt
Устанавливает флажки клавиши - ускорителя. Этот член может быть комбинацией следующих значений:

  • FALT - Клавиша ALT должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FCONTROL - Клавиша CTRL должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FNOINVERT - Определяет, что никакой другой пункт меню верхнего уровня не выделяется, когда используется клавиша - ускоритель. Если этот флажок не установлен, пункт меню верхнего уровня будет выделен, если возможно, когда используется акселератор.
  • FSHIFT - Клавиша SHIFT должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FVIRTKEY - Член структуры key определяет код виртуальной клавиши. Если этот флажок не установлен, key воспринимает его, как определение кода буквы ASCII.

key
Определяет клавишу - ускоритель. Этот член может быть или код виртуальной клавиши или код буквы ASCII.
cmd
Определяет идентификатор клавиши - ускорителя. Это значение помещается в младшем слове параметра wParam сообщения WM_COMMAND или WM_SYSCOMMAND, когда нажимается клавиша - ускоритель.

Смотри также

WM_COMMAND, WM_SYSCOMMAND

Размещение и совместимость ACCEL

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется

 

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

Нижеследующие сообщения, используются с клавишами - ускорителями.
WM_COMMAND
WM_INITMENU
WM_INITMENUPOPUP
WM_MENUCHAR
WM_MENUSELECT
WM_SYSCHAR
WM_SYSCOMMAND

 

Сообщение WM_COMMAND

Сообщение WM_COMMAND отправляется тогда, когда пользователь выбирает командный элемент из меню, когда орган управления отправляет уведомительное сообщение в свое родительское окно, или когда транслируется нажатие клавиши - ускорителя.

Синтаксис

WM_COMMAND
wNotifyCode = HIWORD(wParam); // код уведомления
wID = LOWORD(wParam);  // идентификатор элемента меню, управления или
    // клавиши ускорителя
hwndCtl = (HWND) lParam;  // дескриптор элемента управления

Параметры

wNotifyCode
Значение старшего слова wParam. Определяет код уведомления, если сообщение из органа управления. Если сообщение от клавиши - ускорителя, этот параметр равен 1. Если сообщение от меню, этот параметр - 0.
wID
Значение младшего слова wParam. Определяет идентификатор пункта меню, органа управления или клавиши - ускорителя.
hwndCtl
Значение lParam. Идентифицирует орган управления, отправляющий сообщение, если сообщение от элемента управления. Иначе, этот параметр имеет значение ПУСТО (NULL).

Возвращаемые значения

Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечание
Нажатия клавиш - ускорителей, которые выбирают пункты меню окна, транслируются в сообщения WM_SYSCOMMAND.
Если происходит нажатие клавиши - ускорителя, которое соответствует пункту меню, когда окно, которое владеет меню, свернуто, сообщение WM_COMMAND не отправляется. Однако, если происходит нажатие клавиши - ускорителя, которое не соответствует какому-либо из пунктов меню или меню окна, сообщение WM_COMMAND отправляется, даже если окно свернуто.
Если прикладная программа включает разделитель меню, система отправляет сообщение WM_COMMAND с младшим словом параметра wParam установленным в нуль, когда пользователь выбирает разделитель.

Смотри также

WM_SYSCOMMAND

Размещение и совместимость WM_COMMAND

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_INITMENU

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

Синтаксис

WM_INITMENU
hmenuInit = (HMENU) wParam; // дескриптор меню, которое инициализируется

Параметры

hmenuInit
Значение wParam. Идентифицирует меню, которое будет инициализировано.

Возвращаемые значения

Если приложение обрабатывает это сообщение, оно возвращает нуль.

Замечания

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

Смотри также

WM_INITMENUPOPUP

Размещение и совместимость WM_INITMENU

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_INITMENUPOPUP

Сообщение WM_INITMENUPOPUP отправляется тогда, когда выскакивающее меню или подменю собирается стать активным. Это позволяет прикладной программе модифицировать меню перед его показом на экране без изменения меню полностью.

Синтаксис

WM_INITMENUPOPUP
hmenuPopup = (HMENU) wParam; // дескриптор подменю
uPos = (UINT) LOWORD(lParam); // позиция пункта подменю
fSystemMenu = (BOOL) HIWORD(lParam); // флажок окна меню

Параметры

hmenuPopup
Значение wParam. Идентифицирует выскакивающее меню или подменю.
uPos
Значение младшего слова lParam. Определяет отсчитываемое от нуля взаимное положение пункта меню, который открывает выскакивающее меню или подменю.
fSystemMenu
Значение старшего слова lParam. Определяет, является ли выскакивающее меню меню окна (также известное как Системное меню или меню Control (Управления)). Если это меню - меню окна, этот параметр - ИСТИНА (TRUE); иначе, он имеет значение ЛОЖЬ(FALSE).

Возвращаемые значения

Если приложение обрабатывает это сообщение, оно возвращает нуль.

Смотри также

WM_INITMENU

Размещение и совместимость WM_INITMENUPOPUP

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_MENUCHAR

Сообщение WM_MENUCHAR отправляется тогда, когда меню активизируется, а пользователь, нажимает клавишу, которая не соответствует какому-либо символу или клавише - ускорителю. Это сообщение отправляется окну, которое владеет меню.

Синтаксис

WM_MENUCHAR
chUser = (char) LOWORD(wParam); // символ ASCII
fuFlag = (UINT) HIWORD(wParam); // флажок меню
hmenu = (HMENU) lParam;  // дескриптор меню

Параметры

chUser
Значение младшего слова wParam. Определяет символ ASCII, который соответствует клавише, нажатой пользователем.
fuFlag
Значение старшего слова wParam. Определяет тип активного меню. Этот параметр может быть одним из следующих значений:

 

  • MF_POPUP - Выскакивающее меню, подменю или контекстное меню
  • MF_SYSMENU - Меню окна (системное меню (System Menu) или меню Управления (Control menu)

hmenu
Значение lParam. Идентифицирует активное меню.

Возвращаемые значения

Прикладная программа, которая обрабатывает это сообщение, должна возвратить одно из следующих величин в старшем слове возвращаемого значения:
  • 0 - Сообщает Windows, что оперативная система должна сбросить символ нажатый пользователем и создать короткий гудок в системном динамике.
  • 1 - Сообщает Windows, что оперативная система должна закрыть активное меню.
  • 2 - Сообщает Windows, что младшее слово величины возвращаемого значения устанавливает отсчитываемое от нуля взаимное положение пункта меню. Этот элемент выбирается Windows.

Замечания

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

Размещение и совместимость WM_MENUCHAR

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_MENUSELECT

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

Синтаксис

WM_MENUSELECT
uItem = (UINT) LOWORD(wParam); // пункт меню или индекс подменю
fuFlags = (UINT) HIWORD(wParam); // флажки меню
hmenu = (HMENU) lParam;  // дескриптор меню, по которому щелкнули мышью

Параметры

uItem
Значение младшего слова wParam. Если выбранный пункт - командный пункт, этот параметр содержит идентификатор пункта меню. Если выбранный пункт открывает выпрыгивающее меню или подменю, этот параметр содержит индекс меню выпрыгивающего меню или подменю, в главном меню, а параметр hMenu тогда содержит дескриптор главного (по которому щелкнули) меню; используйте функцию GetSubMenu, чтобы получить дескриптор меню выпрыгивающего меню или подменю.
fuFlags
Значение старшего слова wParam. Определяет один или несколько флажков меню. Этот параметр может быть комбинацией следующих значений:
  • MF_BITMAP - Пункт отображает точечный рисунок.
  • MF_CHECKED - Пункт проверяется.
  • MF_DISABLED - Пункт блокируется.
  • MF_GRAYED - Пункт становится недоступным.
  • MF_HILITE - Пункт выделяется.
  • MF_MOUSESELECT - Пункт выбирается при помощи мыши.
  • MF_OWNERDRAW - Пункт нарисованный пользователем.
  • MF_POPUP - Пункт открывает выскакивающее меню или подменю.
  • MF_SYSMENU - Пункт содержится в меню окна (известное также как Системное или Управляющее меню). Параметр hmenu идентифицирует меню окна, связанное с сообщением.

hmenu
Значение lParam. Идентифицирует меню, по которому щелкнули мышью.

Возвращаемые значения

Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечания

Если параметр fuFlags содержит 0xFFFF, а параметр hmenu содержит ПУСТО (NULL), значит Windows закрыла меню.
Не используйте для fuFlags значение –(минус)1. Это не делается потому, что fuFlags определяется как (UINT) HIWORD (wParam). Если бы HIWORD (wParam) было 0xFFFF, fuFlags (из-за приведения UINT) станет 0x0000FFFF, а не –(минус)1.

Смотри также

GetSubMenu

Размещение и совместимость WM_MENUSELECT

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_SYSCHAR

Сообщение WM_SYSCHAR посылается окну с фокусом клавиатуры, когда транслируется сообщение WM_SYSKEYDOWN функцией TranslateMessage. Оно определяет код символа системы буквенных клавиш - то есть символ клавиши, которая была нажата, в то время, когда была нажата клавиша ALT.

Синтаксис

WM_SYSCHAR
chCharCode = (TCHAR) wParam; // код символа
lKeyData = lParam;  // данные на клавишу

Параметры

chCharCode
Значение wParam. Определяет код символа клавиши меню окна.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующей таблице:
  • 0-15 - Определяет счет повторений. Значение - число раз повторных нажатий клавиши в результате того, что пользователь удерживал клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появились на усовершенствованных 101- или 102-клавишных клавиатурах. Значение равно 1, если это - клавиша расширения, иначе, это - 0.
  • 25-28 - Зарезервировано, не используется.
  • 29 - Определяет контекстный код. Значение 1, если клавиша ALT удерживалась нажатой, в то время когда нажималась клавиша; иначе, это значение 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение 1, если клавиша внизу перед отправкой сообщения, или это - 0, если клавиша -не нажата.
  • 31 - Определяет переходное состояние. Значение 1, если клавишу освобождают, или это - 0, если клавишу нажимают.

Возвращаемые значения

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

Замечания

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

Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются клавиши ALT и CTRL справа на главном разделе клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; клавиша PRINT SCRN; клавиша BREAK; клавиша NUMLOCK; а также клавиши делитель (/) и ENTER в цифровой клавиатуре. Другие клавиатуры могут поддерживать бит дополнительных клавиш в параметре lKeyData.

Смотри также

TranslateAccelerator, TranslateMessage, WM_SYSKEYDOWN

Размещение и совместимость WM_SYSCHAR

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется


Сообщение WM_SYSCOMMAND

Окно получает это сообщение, когда пользователь выбирает команду из меню окна (известное также как Системное меню или Меню управления) или когда пользователь выбирает кнопку Развернуть (Maximize) или кнопку Свернуть (Minimize).

Синтаксис

WM_SYSCOMMAND
uCmdType = wParam;   // затребованный тип системной команды
xPos = LOWORD(lParam);   // горизонтальная позиция, в экранных координатах
yPos = HIWORD(lParam);   // вертикальная позиция, в экранных координатах

Параметры

uCmdType
Определяет тип запрошенной системной команды. Он может быть одним из этих значений:
  • SC_CLOSE - Закрывает окно.
  • SC_CONTEXTHELP - Изменяет курсор на указатель с вопросительным знаком. Если пользователь затем щелкает кнопкой мыши по органу управления в диалоговом окне, элемент управления получает сообщение WM_HELP.
  • SC_DEFAULT - Выбирает заданный по умолчанию пункт; пользователь дважды щелкнул мышью по меню окна.
  • SC_HOTKEY - Активизирует окно, связанное с определяемой прикладной программой последовательностью клавиш-ускорителей "hot key". Младшее слово lParam идентифицирует окно, которое активизируется.
  • SC_HSCROLL - Прокрутка содержимого окна по горизонтали.
  • SC_KEYMENU - Извлекает данные о меню окна в результате нажатия клавиши.
  • SC_MAXIMIZE (или SC_ZOOM) - Развертывает окно.
  • SC_MINIMIZE (или SC_ICON) - Свертывает окно.
  • SC_MONITORPOWER - Только для Windows 95: Устанавливает состояние дисплея. Эта команда поддерживает устройства, которые имеют энергосберегающие функции, типа персонального компьютера с батарейным питанием.
  • SC_MOUSEMENU - Извлекает данные о меню окна в результате щелчка клавиши мыши.
  • SC_MOVE - Перемещает окно.
  • SC_NEXTWINDOW - Перемещает в следующее окно.
  • SC_PREVWINDOW - Перемещает в предыдущее окно.
  • SC_RESTORE - Восстанавливает окно в обычной позиции и размере.
  • SC_SCREENSAVE - Запускает программу-заставку приложения, определяемую в разделе [boot] (начальной загрузки) файла SYSTEM.INI.
  • SC_SIZE - Изменяет размеры окна.
  • SC_TASKLIST - Запускает или активизирует Windows Task Manager (Диспетчер задач).
  • SC_VSCROLL - Прокрутка содержимого окна по вертикали.

xPos
Определяет горизонтальную позицию курсора, в экранной системе координат, если команда меню окна выбрана при помощи мыши. Иначе, xPos параметр не используется.
yPos
Определяет вертикальную позицию курсора, в экранной системе координат, если команда меню окна выбрана при помощи мыши. Этот параметр является – (минус) 1, если команда выбрана, с использованием клавиши - ускорителя системы, или нуль, если использовалась мнемоника.

Возвращаемые значения

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

Замечания

 

Функция DefWindowProc завершает запрос меню окна о предопределенных действиях, перечисленных в предыдущей таблице.
В сообщениях WM_SYSCOMMAND, четыре младших бита параметра uCmdType используются для внутренних потребностей Windows. Чтобы получить правильный результат при проверке значения uCmdType, прикладная программа должна объединить значение 0xFFF0 со значением uCmdType при помощи использования побитового оператора AND.

Пункты в меню окна могут быть изменены при помощи использования функций GetSystemMenu, AppendMenu, InsertMenu, ModifyMenu, InsertMenuItem и SetMenuItem. Прикладные программы, которые изменяют меню окна, должны обрабатывать сообщения WM_SYSCOMMAND.

Прикладная программа может выполнить любую команду системы в любое время, передавая сообщение WM_SYSCOMMAND в DefWindowProc. Любые сообщения WM_SYSCOMMAND, не обработанные программой должны быть переданы в DefWindowProc. Любые значения команд, добавленные приложением, должны быть обработаны прикладной программой и не могут быть переданы в DefWindowProc.
Клавиши-ускорители, которые определены для выбора пунктов из меню окна, транслируются в сообщения WM_SYSCOMMAND; все другие нажатия клавиш - ускорителей транслируются в сообщения WM_COMMAND.

Смотри также

AppendMenu, DefWindowProc, GetSystemMenu, InsertMenu, ModifyMenu, WM_COMMAND

Размещение и совместимость WM_SYSCOMMAND

Windows NT  	Да 
Win95    Да
Win32s    Да
Импортируемая библиотека  -
Заголовочный файл   winuser.h
Unicode    Нет
Замечания по платформе  Не имеется