WM_INITMENUPOPUP и ресурс POPUP - PullRequest
       31

WM_INITMENUPOPUP и ресурс POPUP

1 голос
/ 27 ноября 2011

Я пишу приложение для 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 ]

1 голос
/ 28 ноября 2011

Вы можете использовать 2 для восстановления идентификатора пункта меню через GetMenuItemID.

switch (GetMenuItemID(GetMenu(hwnd), LOWORD(lParam)))
{
case IDM_MIN_BATTERY_LEVEL: ...
}

Вам необходимо использовать MENUEX, чтобы дать подменю идентификатор.

0 голосов
/ 06 января 2015

Я знаю, что это старый вопрос, однако проблема заключается в небольшом непонимании того, как работает сообщение 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 «Минимальный уровень заряда батареи»), несколько сложнее.

...