Таблицы ускорителей
Приложения часто определяют сочетания клавиш, например CTRL+O для команды "Открыть файл". Вы можете реализовать сочетания клавиш, обрабатывая отдельные сообщения WM_KEYDOWN , но таблицы ускорителей предоставляют лучшее решение, которое:
- Требует меньше кодирования.
- Объединяет все сочетания клавиш в один файл данных.
- Поддерживает локализацию на другие языки.
- Позволяет сочетаниям клавиш и командам меню использовать одну и ту же логику приложения.
Таблица ускорителей — это ресурс данных, который сопоставляет сочетания клавиш, например CTRL+O, с командами приложения. Прежде чем мы узнаем, как использовать таблицу ускорителей, нам потребуется краткое представление о ресурсах. Ресурс — это большой двоичный объект данных, встроенный в двоичный файл приложения (EXE или DLL). В ресурсах хранятся данные, необходимые приложению, такие как меню, курсоры, значки, изображения, текстовые строки или любые пользовательские данные приложения. Приложение загружает данные ресурса из двоичного файла во время выполнения. Чтобы включить ресурсы в двоичный файл, выполните следующие действия.
- Создайте файл определения ресурса (RC-файл). Этот файл определяет типы ресурсов и их идентификаторы. Файл определения ресурсов может содержать ссылки на другие файлы. Например, ресурс значка объявляется в RC-файле, но изображение значка хранится в отдельном файле.
- Используйте компилятор ресурсов Microsoft Windows (RC) для компиляции файла определения ресурсов в скомпилированный файл ресурсов (RES). Компилятор-кандидат предоставляется вместе с Visual Studio, а также windows SDK.
- Свяжите скомпилированный файл ресурсов с двоичным файлом.
Эти шаги примерно эквивалентны процессу компиляции и связывания для файлов кода. Visual Studio предоставляет набор редакторов ресурсов, упрощающих создание и изменение ресурсов. (Эти средства недоступны в выпусках Visual Studio Express.) Но RC-файл — это просто текстовый файл, синтаксис описан на сайте MSDN, поэтому rc-файл можно создать с помощью любого текстового редактора. Дополнительные сведения см. в разделе Сведения о файлах ресурсов.
Определение таблицы ускорителей
Таблица ускорителей — это таблица сочетаний клавиш. Каждый ярлык определяется следующим образом:
- Числовой идентификатор. Это число идентифицирует команду приложения, которая будет вызвана ярлыком.
- Символ ASCII или код виртуальной клавиши ярлыка.
- Необязательные клавиши-модификаторы: ALT, SHIFT или CTRL.
Сама таблица ускорителя имеет числовой идентификатор, который идентифицирует таблицу в списке ресурсов приложения. Давайте создадим таблицу ускорителей для простой программы рисования. Эта программа будет иметь два режима: режим рисования и режим выбора. В режиме рисования пользователь может рисовать фигуры. В режиме выбора пользователь может выбирать фигуры. Для этой программы мы хотели бы определить следующие сочетания клавиш.
Клавиша | Get-Help |
---|---|
CTRL+M | Переключение между режимами. |
F1 | Переключитесь в режим рисования. |
F2 | Переключитесь в режим выбора. |
Сначала определите числовые идентификаторы для таблицы и команд приложения. Эти значения являются произвольными. Вы можете назначить символьные константы для идентификаторов, определив их в файле заголовка. Пример:
#define IDR_ACCEL1 101
#define ID_TOGGLE_MODE 40002
#define ID_DRAW_MODE 40003
#define ID_SELECT_MODE 40004
В этом примере значение IDR_ACCEL1
определяет таблицу ускорителя, а следующие три константы определяют команды приложения. По соглашению файл заголовка, определяющий константы ресурсов, часто называется resource.h. В следующем списке показан файл определения ресурса.
#include "resource.h"
IDR_ACCEL1 ACCELERATORS
{
0x4D, ID_TOGGLE_MODE, VIRTKEY, CONTROL // ctrl-M
0x70, ID_DRAW_MODE, VIRTKEY // F1
0x71, ID_SELECT_MODE, VIRTKEY // F2
}
Сочетания клавиш для ускорителей определяются в фигурных скобках. Каждый ярлык содержит следующие записи.
- Код виртуального ключа или символ ASCII, который вызывает ярлык.
- Команда приложения. Обратите внимание, что в примере используются символьные константы. Файл определения ресурсов содержит файл resource.h, где определены эти константы.
- Ключевое слово VIRTKEY означает, что первая запись представляет собой код виртуального ключа. Другой вариант — использовать символы ASCII.
- Необязательные модификаторы: ALT, CONTROL или SHIFT.
Если для ярлыков используются символы ASCII, то символ нижнего регистра будет отличаться от символа верхнего регистра. (Например, при вводе "a" может быть вызвана команда, отличная от команды "A".) Это может сбить с толку пользователей, поэтому для сочетаний клавиш лучше использовать коды виртуальных ключей, а не символы ASCII.
Загрузка таблицы ускорителей
Ресурс для таблицы ускорителя должен быть загружен, прежде чем программа сможет его использовать. Чтобы загрузить таблицу ускорителей, вызовите функцию LoadAccelerators .
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCEL1));
Вызовите эту функцию перед вхощением в цикл сообщений. Первый параметр — дескриптор модуля. (Этот параметр передается в функцию WinMain . Дополнительные сведения см. в разделе WinMain: точка входа приложения.) Второй параметр — идентификатор ресурса. Функция возвращает дескриптор для ресурса. Помните, что дескриптор — это непрозрачный тип, который ссылается на объект, управляемый системой. Если функция завершается сбоем, она возвращает значение NULL.
Вы можете освободить таблицу ускорителей, вызвав DestroyAcceleratorTable. Однако система автоматически освобождает таблицу при завершении работы программы, поэтому эту функцию необходимо вызывать только при замене одной таблицы другой. Интересный пример приведен в разделе Создание редактируемых пользователем ускорителей.
Перевод ключевых росчерков в команды
Таблица ускорителя работает путем преобразования росчерков клавиш в WM_COMMAND сообщения. Параметр wParamWM_COMMAND содержит числовой идентификатор команды. Например, при использовании приведенной выше таблицы росчерк клавиш CTRL+M преобразуется в сообщение WM_COMMAND со значением ID_TOGGLE_MODE
. Чтобы это произошло, измените цикл сообщений следующим образом:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(win.Window(), hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Этот код добавляет вызов функции TranslateAccelerator внутри цикла сообщений. Функция TranslateAccelerator проверяет каждое сообщение окна и ищет сообщения вниз. Если пользователь нажимает одно из сочетаний клавиш, перечисленных в таблице ускорителей, TranslateAccelerator отправляет WM_COMMAND сообщение в окно. Функция отправляет WM_COMMAND , напрямую вызывая процедуру окна. Когда TranslateAccelerator успешно преобразует росчерк клавиши, функция возвращает ненулевое значение, что означает, что следует пропустить обычную обработку сообщения. В противном случае TranslateAccelerator возвращает ноль. В этом случае передайте сообщение окна в TranslateMessage и DispatchMessage, как обычно.
Вот как программа рисования может обрабатывать сообщение WM_COMMAND :
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_DRAW_MODE:
SetMode(DrawMode);
break;
case ID_SELECT_MODE:
SetMode(SelectMode);
break;
case ID_TOGGLE_MODE:
if (mode == DrawMode)
{
SetMode(SelectMode);
}
else
{
SetMode(DrawMode);
}
break;
}
return 0;
В этом коде предполагается, что является функцией, SetMode
определенной приложением для переключения между двумя режимами. Сведения о том, как вы будете обрабатывать каждую команду, очевидно, зависят от вашей программы.
Следующая