Листинг 5.5

while (GetMessage(&msg, NULL. 0. 0)) {

if (!TranslateAccelerator(msg.hwnd. hAccelTable. &msg)) {TransiateMessage(&msg); //Если приложению не требуется //обрабатывать сообщения WM_CHAR. то эту функцию можно опустить Di spatchMessageC&msg); }

}

Но при применении акселераторов исключена возможность проявления скрытых ошибок, вызванных повторным запуском оконной процедуры, не закончившей обработку предыдущего сообщения. При выполнении функции Transiate-Accelerator(msg.hwnd. hAccelTable. &msg) оконная процедура заведомо завершена. Оператор DispatchMessage(&msg) запустит оконную процедуру, но следующий после него оператор не получит управления, пока оконная процедура не завершится.

Создание и использование меню

Управление состоянием пунктов меню Взаимодействие приложения с меню осуществляется при помощи дескриптора меню, который хранится в переменной типа HMENU. Получить дескриптор меню, связанного с окном HWND hWnd, можно при помощи функции GetMenu(), чей синтаксис предельно прост:

HMENU hMenu - GetMenu(hWnd);

Каждое подменю устроено практически так же, как и все меню в целом, поэтому подменю тоже идентифицируется дескриптором типа HMENU. По полученному значению hMenu легко получить дескриптор подменю, являющегося пунктом номер nPos основного меню, как это показано ниже:

HMENU hSbMenu - GetSubMenu(hMenu. nPos):

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

Код, приведенный в листинге 5.6, показывает, как щелчком правой кнопки мыши можно изменить доступность пункта Load проекта MenuMin. Пункт Load с номером 1 располагается в подменю с нулевым номером.

Листинг 5.6

case WM_RBUTTONUP: {
HMENU menu - GetMenu(hWnd);.
HMENU menl - GetSubMenu(menu.O);
int flag - GetMenuState(menl.l.MFJYPOSITION):
if(flag &MF_GRAYED)
EnableMenuItem(menl.1.MF_BYP0SITI0N|MF_ENABLED); else
Enabl eMenuItem(menl.1.MF_BYP0SITI0N|MF_GRAYED);

⇐ Предыдущая| |Следующая ⇒