Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Операционная система Microsoft Windows 3.1 для программиста

© Александр Фролов, Григорий Фролов
Том 13, М.: Диалог-МИФИ, 1993, 284 стр.

[Назад] [Содеожание] [Дальше]

1.10. Акселераторы

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

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

Например, вы можете определить, что комбинации клавиш <Control+Insert> соответствует значение wParam, равное CM_EDITCUT. В этом случае если нажать указанную выше комбинацию клавиш, в функцию окна попадет сообщение WM_COMMAND с параметром wParam, равным CM_EDITCUT.

Обычно комбинации клавиш, используемые для ускоренного выбора (или просто акселераторы) обозначаются в правом столбце меню (рис. 1.17).

Рис. 1.17. Акселераторы в меню "Edit"

Однако такое обозначение, сделанное при помощи символа \t в шаблоне меню не распознается Windows, а служит лишь для удобства пользователя. Для того чтобы комбинация клавиш стала работать как акселератор, она должна быть описана в таблице акселераторов. Кроме этого, приложение должно загрузить таблицу акселераторов из ресурсов приложения и изменить цикл обработки сообщений.

Описание таблицы акселераторов

Таблица акселераторов определяется в файле описания ресурсов приложения в следующем виде:

<Id> ACCELERATORS 
BEGIN
.......
.......
.......
END

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

Между операторами BEGIN и END располагаются строки описания акселераторов. Они имеют следующий формат (в квадратных скобках указаны необязательные параметры):

Key, AccId, [KeyType[,]] [NOINVERT] [ALT] [SHIFT] [CONTROL]

Поле Key определяет клавишу, которая будет использована для создания акселератора. Вы можете использовать символ в коде ASCII, заключенный в двойные кавычки (например, "F"), комбинацию символа ASCII со знаком ^ (например, "^S", что соответствует комбинации клавиш <Control+S>), ASCII-код клавиши в виде целого значения, или виртуальный код клавиши (в символьном или цифровом виде).

Поле AccId соответствует значению параметра wParam сообщения WM_COMMAND, которое попадет в функцию окна при использовании акселератора.

Поле KeyTab может принимать значения ASCII или VIRTKEY. В первом случае поле Key определяет клавишу с использованием кода ASCII, во втором - с использованием кода виртуальной клавиши. По умолчанию используется значение ASCII.

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

Если поле KeyTab содержит значение VIRTKEY, можно указывать параметры ALT, SHIFT или CONTROL. В этом случае для акселератора используется комбинация клавиши, указанной параметром Key, и клавиши ALT, SHIFT или CONTROL, соответственно.

Приведем пример описания таблицы акселераторов из приложения SMARTPAD:

APP_ACCELERATORS ACCELERATORS 
BEGIN
  "N", CM_FILENEW,         VIRTKEY, CONTROL
  "S", CM_FILESAVE,        VIRTKEY, CONTROL
  "O", CM_FILEOPEN,        VIRTKEY, CONTROL
  "Z", CM_EDITUNDO,        VIRTKEY, CONTROL
  "X", CM_EDITCUT,         VIRTKEY, CONTROL
  "C", CM_EDITCOPY,        VIRTKEY, CONTROL
  "V", CM_EDITPASTE,       VIRTKEY, CONTROL
  VK_DELETE, CM_EDITCLEAR, VIRTKEY, CONTROL
  VK_F1, CM_HELPINDEX,     VIRTKEY
END

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

Для того чтобы акселератор, состоящий из комбинации символьной клавиши (такой, как "N") и клавиши <Control>, работал вне зависимости от состояния клавиши <Caps Lock>, мы использовали виртуальные коды. Если бы мы использовали коды ASCII, наш акселератор активизировался бы только при использовании заглавных букв (мы могли бы указать строчные буквы, например, "n", в этом случае для активизации акселератора следовало бы использовать строчные буквы).

Из-за того что клавиша <Caps Lock> может находиться в любом состоянии, лучше работать с виртуальными кодами клавиш, не зависящих от того, являются буквы строчными или прописными.

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

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

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

HACCEL WINAPI LoadAccelerators(HINSTANCE hInst, 
  LPCSTR lpszTableName);

Параметр hInst определяет идентификатор копии приложения, из ресурсов которого будет загружена таблица акселераторов.

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

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

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

Приложение SMARTPAD работает с таблицей акселераторов и загружает ее следующим образом:

haccel = LoadAccelerators(hInstance, "APP_ACCELERATORS");

Изменения в цикле обработки сообщений

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

while(GetMessage(&msg, 0, 0, 0))
{
  if(!haccel || !TranslateAccelerator(hwnd, haccel, &msg))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}

В этом фрагменте кода переменная haccel содержит идентификатор загруженной таблицы акселераторов. Если идентификатор не равен NULL, вызывается функция TranslateAccelerator . Эта функция ищет в очереди сообщений сообщения от клавиатуры, соответствующие определенным в ресурсах приложения акселераторам, преобразуя такие сообщения в сообщения WM_COMMAND и WM_SYSCOMMAND (если сообщение соответствует системному меню), передаваемые непосредственно в функцию окна, минуя очередь сообщений приложения .

Содержимое параметра wParam в последних двух сообщениях равно идентификатору, указанному в таблице акселераторов для данной комбинации клавиш.

Старшее слово параметр lParam содержит 1 для сообщений, которые пришли от акселераторов и 0 для сообщений, которые пришли от меню.

Приведем прототип функции TranslateAccelerator:

int WINAPI TranslateAccelerator(HWND hwnd, HACCEL haccel,
   MSG FAR* lpmsg);

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

Параметр haccel должен содержать идентификатор загруженной при помощи функции LoadAccelerators таблицы акселераторов.

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

Если функция TranslateAccelerator выполнила преобразование сообщения, она возвращает ненулевое значение. В противном случае возвращается 0. Обработанное сообщение не следует передавать функциям TranslateMessage и DispatchMessage.

[Назад] [Содеожание] [Дальше]