You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:53:09