将ICON转换为HBITMAP以显示在弹出菜单中?

时间:2013-06-13 14:35:42

标签: winapi visual-c++ mfc icons gdi

我正在尝试add bitmaps to a popup menu

我遇到的问题是我动态地从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);

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

传递给MENUITEMINFOSetMenuItemInfo结构的HBITMAP成员传递的hbmpItem有什么要求???

如何确保DrawIconEx“创建”的位图确实符合这些要求?


哦,我很高兴我刚刚了解到32位alpha混合菜单项位图在Windows XP下无法正常工作(透明=黑色),所以我必须以某种方式自己映射透明度。 (可能用GetSysColor(COLOR_MENU)替换某些颜色。)

0 个答案:

没有答案