Листинг 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);