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:
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.