3

我正在尝试将位图添加到弹出菜单

我遇到的问题是我从 ICON 动态创建位图,并且我遇到了 24 位颜色图标与 24+alpha(32 位)颜色图标的问题。

位图似乎只有在 32bpp(包括 alpha 通道)时才能正确绘制。

这是我的(测试)代码:

void ConvertIconToBitmap(CBitmap& bmpObj, HICON hIcon, int cx, int cy, BOOL useDIB) {
    CClientDC screenDC(NULL);
    CBitmap bmpTmp;
    HANDLE_API_FAILURE( bmpTmp.CreateCompatibleBitmap(&screenDC, cx, cy) );
    CDC memDC;
    HANDLE_API_FAILURE( memDC.CreateCompatibleDC(&screenDC) );
    CBitmap* pOldBmp = memDC.SelectObject(&bmpTmp);
    HANDLE_API_FAILURE( ::DrawIconEx( memDC.GetSafeHdc(), 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL) );
    memDC.SelectObject( pOldBmp );

    HBITMAP hDibBmp = (HBITMAP)::CopyImage((HANDLE)(HBITMAP)bmpTmp, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);

    HANDLE_API_FAILURE( hDibBmp );
    if (useDIB) {
        HANDLE_API_FAILURE( bmpObj.Attach(hDibBmp) ); // works for 32bit/transparanecy
    } else {
        HANDLE_API_FAILURE( bmpObj.Attach(bmpTmp.Detach()) ); // works for 24bit
    }
}

...
    CMenu menu;
    menu.LoadMenu(IDR_POPUPMENU);
    CMenu* pMenu = menu.GetSubMenu(0);

    int cx, cy;
    cx = cy = GetSystemMetrics(SM_CYMENU);
    MENUITEMINFO mii;
    mii.cbSize = sizeof mii;
    mii.fMask = MIIM_BITMAP;

    HICON pwdIco = ExtractIcon(NULL/*=current instance*/, L"path/to/file.exe", 0);

    // If icon is 32bit-alpha this works, but doesn't work with 24bit icon
    CBitmap bmpTop;
    ConvertIconToBitmap(bmpTop, pwdIco, cx, cy, TRUE);
    mii.hbmpItem = bmpTop;
    pMenu->SetMenuItemInfo(ID_MENU_TOP, &mii, FALSE);

    // If icon is 32bit-alpha transparent areas are shown in black, but 24bit icon is also displayed correctly
    CBitmap bmpApp;
    ConvertIconToBitmap(bmpApp, pwdIco, cx, cy, FALSE);
    HBITMAP bmpTransp = bmpApp;
    mii.hbmpItem = bmpTransp;
    pMenu->SetMenuItemInfo(ID_MENU_TEST, &mii, FALSE);


    this->ClientToScreen(&point);
    pMenu->TrackPopupMenu(nFlags, point.x, point.y, this);

因为我需要从现有文件的图标中动态填充菜单条目图像,所以我不能只是静态地整理出位图并使用这些而不是图标。

传递给SetMenuItemInfo的MENUITEMINFO结构HBITMAPhbmpItem成员有什么要求???

以及如何确保“创建”的位图DrawIconEx满足这些要求?


哦,令我非常高兴的是,我刚刚了解到 32 位 alpha 混合菜单项位图在 Windows XP 下不起作用(那里是透明的=黑色),所以我必须以某种方式自己映射透明度。(可能通过用 替换一些颜色GetSysColor(COLOR_MENU)。)

4

0 回答 0