Прочитать на английском

Поделиться через


Таблицы акселераторов

Приложения часто определяют сочетания клавиш, такие как CTRL+O для команды "Открыть файл". Вы можете реализовать сочетания клавиш, обрабатывая отдельные сообщения WM_KEYDOWN, но таблицы ускорителей обеспечивают лучшее решение:

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

Таблица акселератора — это ресурс данных, который сопоставляет сочетания клавиш, например CTRL+O, с командами приложений. Прежде чем мы узнаем, как использовать таблицу акселератора, нам потребуется краткое введение в ресурсы. ресурса — это большой двоичный объект данных, встроенный в двоичный файл приложения (EXE или DLL). Ресурсы хранят данные, необходимые приложению, например меню, курсоры, значки, изображения, текстовые строки или любые пользовательские данные приложения. Приложение загружает данные ресурса из двоичного файла во время выполнения. Чтобы включить ресурсы в двоичный файл, сделайте следующее:

  1. Создайте файл определения ресурса (RC). Этот файл определяет типы ресурсов и их идентификаторы. Файл определения ресурса может содержать ссылки на другие файлы. Например, ресурс значка объявлен в RC-файле, но изображение значка хранится в отдельном файле.
  2. Используйте компилятор ресурсов Microsoft Windows (RC) для компиляции файла определения ресурса в скомпилированный файл ресурса (RES). Компилятор RC предоставляется в Visual Studio, а также в пакете SDK для Windows.
  3. Свяжите скомпилированный файл ресурсов с двоичным файлом.

Эти шаги примерно эквивалентны процессу компиляции и ссылки для файлов кода. Visual Studio предоставляет набор редакторов ресурсов, которые упрощают создание и изменение ресурсов. (Эти средства недоступны в выпусках Express Visual Studio.) Но RC-файл — это просто текстовый файл, и синтаксис документируется в MSDN, поэтому можно создать RC-файл с помощью любого текстового редактора. Дополнительные сведения см. в о файлах ресурсов.

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

Таблица акселератора — это таблица сочетаний клавиш. Каждое сочетание клавиш определяется следующим образом:

  • Числовой идентификатор. Это число определяет команду приложения, которая будет вызвана ярлыком.
  • Символ ASCII или код виртуального ключа ярлыка.
  • Необязательные клавиши модификатора: ALT, SHIFT или CTRL.

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

Ярлык Команда
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 для сочетаний клавиш.

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

Ресурс для таблицы акселератора необходимо загрузить, прежде чем программа сможет использовать ее. Чтобы загрузить таблицу акселераторов, вызовите функциюloadAccelerator.

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

Следующий

настройка изображения курсора