简体   繁体   中英

Trying to checkmark Context Menu Item on app Tray Icon in C++ (WinAPI)

I made a little app in C++ and I have two pairs of menus; one for the main window, and one for the tray icon I put there. I'm trying to put a checkmark next to a specific menu item in the tray icon context menu, but I can't get this to work.

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;

It works fine, if I use the menu handle of the main window to set a checkmark on one of those items, but I can't get it to work on the tray icon context menu.

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

Based on the official NotificationIcon Sample modify ShowContextMenu function as below work for me. You can have a try.

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

Result:

在此处输入图像描述

Tips:

  1. Set menu item state before the menu window shows up.
  2. CheckMenuItem may be altered or unavailable in subsequent versions. Instead, use SetMenuItemInfo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM