Win32 API菜单项图标不显示求助:如何为菜单添加图标?
修复Win32上下文菜单项图标不显示的问题
修复后的代码
1. 修改上下文菜单创建函数
HMENU createContextMenu(HWND hwnd, HINSTANCE hInstance) { HMENU hMenu = CreatePopupMenu(); if (hMenu) { // 设置菜单支持位图显示的风格 SetMenuInfo(hMenu, &(MENUINFO){ sizeof(MENUINFO), MIM_STYLE, MNS_CHECKORBMP // 允许菜单项显示位图 }); AppendMenu(hMenu, MF_STRING, IDM_APP_ABOUT, "&About"); AppendMenu(hMenu, MF_SEPARATOR, (UINT_PTR)-1, NULL); AppendMenu(hMenu, MF_STRING, IDM_APP_EXIT, "&Exit"); // 加载指定大小的图标(菜单通常用16x16) HICON hIconExit = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(ICON_MENU_EXIT), IMAGE_ICON, 16, 16, // 指定菜单图标的尺寸 LR_DEFAULTCOLOR); if (hIconExit) { // 将图标转换为位图 HDC hdc = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hBmp = CreateCompatibleBitmap(hdc, 16, 16); HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem, hBmp); // 绘制图标到位图 DrawIconEx(hdcMem, 0, 0, hIconExit, 16, 16, 0, NULL, DI_NORMAL); SelectObject(hdcMem, hOldBmp); DeleteDC(hdcMem); ReleaseDC(NULL, hdc); // 设置菜单项位图 MENUITEMINFO menuItemInfo = { sizeof(MENUITEMINFO) }; menuItemInfo.fMask = MIIM_BITMAP | MIIM_FTYPE; menuItemInfo.fType = MFT_BITMAP; // 指定菜单项显示位图 menuItemInfo.hbmpItem = hBmp; if (!SetMenuItemInfo(hMenu, IDM_APP_EXIT, FALSE, &menuItemInfo)) { // 设置失败,手动销毁位图 DeleteObject(hBmp); } DestroyIcon(hIconExit); } } return hMenu; }
2. 托盘消息处理部分(保持原逻辑)
case WM_USER_TRAYICON: if (lParam == WM_LBUTTONDBLCLK) { ShowWindow(hwnd, SW_SHOW); } else if (lParam == WM_RBUTTONUP) { POINT trayPos; GetCursorPos(&trayPos); HMENU hMenu = createContextMenu(hwnd, hInstance); SetForegroundWindow(hwnd); UINT clicked = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_NONOTIFY, trayPos.x, trayPos.y, 0, hwnd, NULL); if (clicked == IDM_APP_EXIT) { PostQuitMessage(0); } DestroyMenu(hMenu); } break;
关键问题分析与修复点
- 菜单风格缺失:默认弹出菜单不支持显示位图,必须通过
SetMenuInfo设置MNS_CHECKORBMP风格,告知系统菜单可处理位图类型的菜单项。 - 图标到位图转换错误:原代码用
CopyImage以IMAGE_ICON类型转换,返回的仍是HICON句柄,强制转为HBITMAP无效。改用DrawIconEx将图标绘制到兼容DC生成的位图,才能得到有效HBITMAP。 - 图标加载尺寸不匹配:
LoadIcon仅能加载系统默认大小的图标,可能与菜单所需的16x16尺寸不符。改用LoadImage明确指定图标尺寸,确保适配菜单显示。 - 菜单项类型未指定:设置
MENUITEMINFO时需同时指定MIIM_FTYPE和MFT_BITMAP,明确告知系统该菜单项需显示位图(文本会保留,位图作为左侧图标)。
内容的提问来源于stack exchange,提问作者Viole Grace
相关产品推荐
相关产品推荐

