Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций Часть II.doc
Скачиваний:
14
Добавлен:
20.11.2018
Размер:
1.48 Mб
Скачать

П. 4.4. Акселераторы

Для быстрого доступа к командам используют акселераторы. Их ино­гда называют "клавишами быстрого вызова" команд меню. В действи­тельности же акселераторы могут быть связаны с любыми командами.

При поступлении сообщения WM_COMMAND от акселератора младшее слово параметра wParam содержит идентификатор связанной с аксе­лератором команды, а старшее слово wParam равно 1.

Операционная система широко использует акселераторы. Например, стандартное системное меню практически любого окна содержит строку "Закрыть Aft+F4" и команда этой строки связана с акселератором Alt+F4. То есть одновременное нажатие клавиш Alt и F4 равноценно выбору строки "Закрыть Alt+F4" системного меню активного окна.

Приложение все используемые акселераторы должно записать в одну таблицу и работать с дескриптором этой таблицы. Для работы с табли­цей существует несколько функций.

Функция CreateAcceleratorTabte создает таблицу акселераторов:

HACCEL CreateAcceleratorTable( LPACCEL lpacd, int cEntries);

Здесь lpaccl - указатель на массив структур типа ACCEL, который со­держит описания акселераторов, a cEntries - количество структур в мас­сиве lpaccl. В случае успешного создания функция возвращает дескрип­тор созданной таблицы, иначе - NULL.

Каждую созданную функцией CreateAcceleratorTable таблицу нужно разрушать до завершения работы приложения. Для этого вызывают функцию DestroyAcceleratorTabIe.

Структура ACCEL задает данные одного акселератора и описана сле­дующим образом:

typedef struct

{ BYTE fVirt;

WORD key;

WORD cmd;

} ACCEL;

Назначение полей структуры ACCEL:

1. fVirt задает флажки акселератора и может быть комбинацией сле­дующих значений:

Значение

Пояснение

FALT

Клавишу key нажимают при нажатой клавише Alt

FCONTROL

Клавишу key нажимают при нажатой клавише Ctrl

FNOINVERT

Определяет, что никакой верхнего уровня пункт меню не высвечен, когда акселератор используется. Если этот флажок не определен; верхнего уровня пункт ме­ню будет высвечен, если возможно, когда акселератор используется

FSHIFT

Клавиша key нажимают при нажатой клавише Shift

FVIRTKEY

Поле key содержит код виртуальной клавиши, Дели флажок FVIRTKEY не установлен, то предполагается, что поле key содержит код символа ASCII

2. key задает акселератор и может быть кодом виртуальной клавиши или символа ASCII. Список допустимых значений кода приведен в табл..

3. cmd - идентификатор команды. Если нажать определяемую акселе­ратором комбинацию клавиш, то функция окна получит сообщение WM_COMMAND или WM_SYSCOMMAND. При этом младшее слово параметра wParam будет содержать значение cmd.

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

int TranslateAccelerator( HWND hwnd, HACCEL hAccTable, LPMSG lpMsg);

Эта функция транслирует сообщение WM_KEYDOWN или WM_SYSKEYDOWN в сообщение вида к WM_COMMAND или WM_SYSCOMMAND и затем посылает сообщение WM_COMMAND или WM_SYSCOMMAND непосредственно функции окна hwnd. Она за­вершает работу только после обработки сообщения. В случае успешного выполнения функция возвращает ненулевое значение.

Параметры:

1. hwnd - дескриптор окна.

2. hAccTable - дескриптор таблицы акселераторов. Эта таблица должна быть или загружена вызовом функции LoadAccelerators или создана функцией CreateAcceleratorTable.

3. lpMsg - указатель на структуру типа MSG, выбранный из очереди сообщений функцией GetMessage или PeekMessage.

Для отличения сообщения функции TranslateAccelerator от сообще­ний других источников (например, от меню) операционная система в старшее слово параметра wParam сообщения WM_COMMAND или WM_SYSCOMMAND записывает 1.

Сообщения акселераторов, дублирующих строки системного меню, транслируют в сообщение WM_SYSCOMMAND. Сообщения других ак­селераторов транслируют в сообщение WM_COMMAND.

Если функция TranslateAccelerator вернула ненулевое значение, это означает, что сообщение обработано функцией указанного окна. И это сообщение не нужно передавать функции TranslateMessage или DispatchMessage.

Перечислим сходства и отличия использования акселератора от процесса выбора строки меню:

1. Если команда акселератора соответствует команде элемента меню, то при нажатии акселератора функция окна получает сообщения WM_INITMENU и WM_INITMENUPOPUP так же, как и при выборе строки меню с помощью мыши.

2. При нажатии акселератора функция окна не получит сообщений WM_INITMENU и WM_INITMENUPOPUP в следующих случаях:

• окно заблокировано;

• элемент меню заблокирован;

• акселератор не соответствует элементу системного меню и это окно свернуто;

• поступают сообщения от мыши.

3. Если указанное в вызове функции TranslateAccelerator окно актив­но и другие окна не имеют фокуса ввода (это может быть, если указан­ное окно свернуто), то TranslateAccelerator вместо WM_KEYUP или WM_KEYDOWN транслирует сообщение WM_SYSKEYUP или WM_SYSKEYDOWN.

4. Если указанное функции TranslateAccelerator окно свернуто, то она посылает сообщение WM_COMMAND, только если нажатый акселера­тор не связан с командой ни одного из элементов меню указанного окна.

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

HACCEL hAccel=CreateAccelTableO;

while (GetMessage(&msg, 0,0,0))

{

if (!hAccel || !TranslateAccelerator(hwnd, hAccel, &msg))

{

TranslateMessage(&msg);DispatchMessage(&msg);

} }

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

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