3

ポップアップ メニューにビットマップを追加しようとしています。

私が抱えている問題は、ICON からビットマップを動的に作成することであり、24 ビット カラー アイコンと 24 + アルファ (32 ビット) カラー アイコンに問題があります。

ビットマップは、32bpp (アルファ チャネルを含む) の場合にのみ常に正しく描画されるようです。

ここに私の(テスト)コードがあります:

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構造体のメンバーにHBITMAP渡される要件は何ですか???hbmpItem

そして、「作成された」ビットマップDrawIconExがこれらの要件を満たしていることを確認するにはどうすればよいですか?


ああ、嬉しいことに、32 ビットのアルファ ブレンド メニュー項目ビットマップが Windows XP では機能しないことを知りました (ここでは透明 = 黒)。(おそらく、一部の色を に置き換えることによってGetSysColor(COLOR_MENU)。)

4

0 に答える 0