ポップアップ メニューにビットマップを追加しようとしています。
私が抱えている問題は、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)
。)