c++ win32动态菜单-选择了哪个菜单项

发布于 2024-12-06 17:42:27 字数 1345 浏览 0 评论 0原文

我有一个 win32 应用程序(c++),它有一个上下文菜单绑定到右键单击通知图标。菜单/子菜单项在运行时动态创建和更改。

 InsertMenu(hSettings, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR) hDevices, L"Setting 1");
 InsertMenu(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"); 

在上面的代码中,hDevices 和 hChannels 是动态生成的子菜单。 动态菜单是这样生成的:

   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");

有没有办法知道哪个项目被单击,而不必定义每个子菜单项它自己的 ID(上面代码中的 IDM_DEVICE)?想要检测用户单击了子菜单 IDM_DEVICE 并且单击了该子菜单中的第一项(测试 1)。

我想实现这样的目标:

  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;          
    }

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");
 InsertMenu(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;          
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

起风了 2024-12-13 17:42:27

请尝试以下操作:

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

现在您将获得 WM_MENUCOMMAND 而不是 WM_COMMAND。菜单索引位于 wParam 中,菜单句柄位于 lParam 中。请注意仅消耗已知菜单的消息,并将其余消息传递给 DefWindowProc。代码将类似于:

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

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
暮年 2024-12-13 17:42:27

还可以将 TrackPopupMenuEx() 与标志 TPM_RETURNCMD | TPM_NONOTIFY 并获取所选菜单项的 id,而无需通过 WM_MENUCOMMAND

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文