开发者

c++ win32 dynamic menu - which menu item was selected

开发者 https://www.devze.com 2023-04-07 00:48 出处:网络
i have a win32 application (c++) that has a context menu bind to the right click on the notify icon. The menu/submenu items are dynamicly created and changed during runtime.

i have a win32 application (c++) that has a context menu bind to the right click on the notify icon. The menu/submenu items are dynamicly created and changed during runtime.

 InsertMenu(hSettings, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR) hDevices, L"Setting 1");
 InsertM开发者_开发知识库enu(hSettings, 1, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR) hChannels, L"Setting 2");

 InsertMenu(hMainMenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR) hSettings, L"Settings");
 InsertMenu(hMainMenu, 1, MF_BYPOSITION | MF_STRING, IDM_EXIT, L"Exit"); 

In the code above hDevices and hChannels are dynamicly generated sub menus. The dynamic menus are generated like this:

   InsertMenu(hDevices, i, style, IDM_DEVICE, L"Test 1");
   InsertMenu(hDevices, i, style, IDM_DEVICE, L"Test 2");
   InsertMenu(hDevices, i, style, IDM_DEVICE, L"Test 3");

Is there any way of knowing which item was clicked without having to define each submenu item it's own ID (IDM_DEVICE in the code above)? In would like to detect that user clicked on submenu IDM_DEVICE and that he clicked on the first item (Test 1) in this submenu.

I would like to achive something like this:

  case WM_COMMAND:
    wmId    = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    // Parse the menu selections:
    switch (wmId)
    {
        case IDM_DEVICE: // user clicked on Test 1 or Test 2 or Test 3 
            UINT index = getClickedMenuItem(); // get the index number of the clicked item (if you clicked on Test 1 it would be 0,..) 
                            // change the style of the menu item with that index 
            break;          
    }


Try the following:

MENUINFO mi;
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
mi.fMask = MIM_STYLE;
mi.dwStyle = MNS_NOTIFYBYPOS;
SetMenuInfo(hDevices, &mi);

Now you'll get the WM_MENUCOMMAND instead of WM_COMMAND. The menu index will be in wParam and the menu handle in lParam. Take care to eat up messages only for known menus and past the rest to DefWindowProc. The code will be similar to this:

case WM_MENUCOMMAND:
    HMENU menu = (HMENU)lParam;
    int idx = wParam;
    if (menu == hDevices)
    {
       //Do useful things with device #idx
    }
    else
        break; //Ensure that after that there is a DefWindowProc call


One can also use TrackPopupMenuEx() with the flags TPM_RETURNCMD | TPM_NONOTIFY and get the id of the selected menu item without having to go thru WM_MENUCOMMAND.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号