WM_INITMENUPOPUP и ресурс POPUP
Я пишу приложение для Windows Mobile 6 на C/C++. Как обычно, он имеет 2 софт-клавиши, одна из которых - меню. В этом меню есть всплывающее меню. Вот (раздетый) источник софт-клавиш от resources.rc
и мало кто определяет из resource.h
:
#define IDR_MAIN_MENU 130
#define IDM_LOCK 30006
#define IDM_MAIN_MENU 30007
IDR_MAIN_MENU RCDATA
{
IDR_MAIN_MENU,
2,
I_IMAGENONE, IDM_LOCK , TBSTATE_ENABLED, TBSTYLE_AUTOSIZE | TBSTYLE_BUTTON , IDS_LOCK, 0, NOMENU,
I_IMAGENONE, IDM_MAIN_MENU, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN, IDS_MENU, 0, 0,
}
IDR_MAIN_MENU MENU
{
POPUP "Menu"
{
MENUITEM "Keep display" IDM_KEEP_DISPLAY_TURNED_ON
MENUITEM "Keep backlight" IDM_KEEP_BACKLIGHT_TURNED_ON
POPUP "Min battery level"
{
MENUITEM "None" 0
MENUITEM SEPARATOR
MENUITEM "5%" 0
MENUITEM "10%" 0
...
}
MENUITEM "Exit" IDM_EXIT
}
}
Когда пользователь открывает меню, я хочу изменить его - проверить, снять флажок, включить, отключить элементы и т. Д. Поэтому я обрабатываю WM_INITMENUPOPUP
сообщение в WndProc()
:
case WM_INITMENUPOPUP:
switch (LOWORD(lParam))
{
case IDM_MAIN_MENU:
OnMainMenuInit(reinterpret_cast<HMENU>(wParam));
break;
}
break;
Теперь, когда пользователь открывает главное меню, вызывается OnMainMenuInit(). Это отлично работает.
Теперь о проблеме. Я бы хотел обработать открытие подменю "Минимальный уровень заряда батареи" отдельно. я получил WM_INITMENUPOPUP
При открытии подменю я также получаю дескриптор меню (например, 0x0A5B0B74 для главного меню, 0x0A5BA924 для подменю), но подменю "Минимальный уровень заряда батареи" не имеет "идентификатора команды", который можно использовать для его идентификации. я получил 2
как LOWORD(lParam)
, которая является позицией пункта "Минимальный уровень заряда батареи" в главном меню, но мне не нравится идея жесткого кодирования этого 2
для определения подменю "Минимальный уровень заряда батареи", потому что добавление пунктов меню будет означать, что я должен изменить это жестко 2
также.
Любые советы о том, как определить подменю "Минимальный уровень заряда батареи" в WM_INITMENUPOPUP
? Под "определить" я подразумеваю "как узнать, что это меню предназначено для минимального уровня заряда батареи" (а не "что такое ручка подменю минимального уровня заряда батареи").
2 ответа
Вы можете использовать 2 для восстановления идентификатора пункта меню через GetMenuItemID
,
switch (GetMenuItemID(GetMenu(hwnd), LOWORD(lParam)))
{
case IDM_MIN_BATTERY_LEVEL: ...
}
Вам нужно использовать MENUEX
чтобы дать подменю идентификатор.
Я знаю, что это старый вопрос, однако проблема заключается в небольшом недопонимании того, как работает сообщение WM_INITMENUPOPUP.
Значение LOWORD(lParam) является индексным значением 0 для пунктов главного меню, поэтому в обычном приложении файловое меню имеет значение 0, следующее справа, это может быть меню редактирования, имеющее значение 1, и скоро.
Значения HIWORD(lParam) для системного меню, такие как восстановление, свертывание и закрытие меню.
Так вот мое решение проблемы
case WM_INITMENUPOPUP:
switch (lParam)
{
case 0: // The Menu item
OnMainMenuInit(reinterpret_cast<HMENU>(wParam));
break;
}
break;
Определить номер индекса во всплывающих меню верхнего уровня, таких как меню "Файл" или "Редактировать", достаточно просто, а всплывающие меню второго уровня, такие как в этом вопросе (POPUP "Минимальный уровень заряда батареи"), несколько сложнее.