【问题标题】:Trying to checkmark Context Menu Item on app Tray Icon in C++ (WinAPI)尝试在 C++ 中的应用程序托盘图标上选中上下文菜单项(WinAPI)
【发布时间】:2020-07-03 11:36:01
【问题描述】:

我用 C++ 制作了一个小应用程序,我有两对菜单;一个用于主窗口,一个用于我放在那里的托盘图标。我正在尝试在托盘图标上下文菜单中的特定菜单项旁边打一个复选标记,但我无法让它工作。

if (!isCheckmarked)
{
    CheckMenuItem(cSubMenu, IDC_STARTWIN, MF_CHECKED);
    OutputDebugString(_T("Checkmarked!\n"));
    _RPT2(_CRT_WARN, "Menu Handles: %i, %i\n", cMenu, cSubMenu);

    isCheckmarked = TRUE;
}
else
{
    //CheckMenuItem(hMenu, IDC_STARTWIN, MF_UNCHECKED);
    OutputDebugString(_T("Uncheckmarked!\n"));
    //_RPT2(_CRT_WARN, "Menu Handles: %i, %i\n", cMenu, cSubMenu);

    isCheckmarked = FALSE;
}
break;

如果我使用主窗口的菜单句柄在其中一项上设置复选标记,它工作正常,但我无法让它在托盘图标上下文菜单上工作。

void ShowContextMenu(HWND hWnd, POINT pt)
{
    cMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDC_CONTEXT_MENU));
    if (cMenu)
    {
        cSubMenu = GetSubMenu(cMenu, 0);
        if (cSubMenu)
        {
            // our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away
            SetForegroundWindow(hWnd);

            // respect menu drop alignment
            UINT uFlags = TPM_RIGHTBUTTON;
            if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0)
            {
                uFlags |= TPM_RIGHTALIGN;
            }
            else
            {
                uFlags |= TPM_LEFTALIGN;
            }

            TrackPopupMenuEx(cSubMenu, uFlags, pt.x, pt.y, hWnd, NULL);
        }

        DestroyMenu(cMenu);
    }

【问题讨论】:

  • 我不清楚您所说的“托盘图标”是什么。您能否展示一些快照,例如您所拥有的和您所期望的?
  • @RitaHan-MSFT 我的应用程序使用 Shell_NotifyIcon() 图标化到系统托盘。这个图标化的图标有一个上下文菜单,在其中一个菜单项上,我想设置一个复选标记。 (我正在使用 NotificationIcon 示例(来自 Window 7 SDK 示例)。我在设置复选标记时遇到问题。(不显示)。
  • @RitaHan-MSFT 上下文菜单图像:link
  • ShowContextMenu 从不调用 CheckMenuItem,因此没有任何检查也就不足为奇了。
  • @KeesSpierings 这个答案对你有用吗?

标签: c++ winapi contextmenu trayicon


【解决方案1】:

基于官方NotificationIcon Sample 修改ShowContextMenu 功能如下为我工作。你可以试一试。

    BOOL mOptionsChecked = FALSE;
    
    void ShowContextMenu(HWND hwnd, POINT pt)
    {
        UINT menuItemId = 0;
    
        HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDC_CONTEXTMENU));
        if (hMenu)
        {
            HMENU hSubMenu = GetSubMenu(hMenu, 0);
            if (hSubMenu)
            {
                // our window must be foreground before calling TrackPopupMenu or the menu will not disappear when the user clicks away
                SetForegroundWindow(hwnd);
    
                // If the menu item has checked last time set its state to checked before the menu window shows up.
                if (mOptionsChecked)
                {
                    //CheckMenuItem(hSubMenu, IDM_OPTIONS, MF_BYCOMMAND | MF_CHECKED);

                    MENUITEMINFO mi = { 0 };
                    mi.cbSize = sizeof(MENUITEMINFO);
                    mi.fMask = MIIM_STATE;
                    mi.fState = MF_CHECKED;
                    SetMenuItemInfo(hSubMenu, IDM_OPTIONS, FALSE, &mi);
                }
    
                // respect menu drop alignment
                UINT uFlags = TPM_RIGHTBUTTON;
                if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0)
                {
                    uFlags |= TPM_RIGHTALIGN;
                }
                else
                {
                    uFlags |= TPM_LEFTALIGN;
                }
    
                // Use TPM_RETURNCMD flag let TrackPopupMenuEx function return the menu item identifier of the user's selection in the return value.
                uFlags |= TPM_RETURNCMD;
                menuItemId = TrackPopupMenuEx(hSubMenu, uFlags, pt.x, pt.y, hwnd, NULL);
    
                // Toggle the menu item state. 
                if (IDM_OPTIONS == menuItemId)
                {
                    if(mOptionsChecked)
                        mOptionsChecked = FALSE;
                    else
                        mOptionsChecked = TRUE;
                }
    
            }
            DestroyMenu(hMenu);
        }
    }

结果:

提示:

  1. 在菜单窗口出现之前设置菜单项状态。
  2. CheckMenuItem 可能会在后续版本中更改或不可用。请改用SetMenuItemInfo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多