部分的に透明な小さな画像が中央に配置された5つの「非表示」ボタンを備えたランチャーウィンドウを作成しようとしています。ユーザーがボタンにカーソルを合わせているかどうかによって、内部の画像が変化します。この例では、画像はリソースIDB_Website1とIDB_Website2です。
画像は.png形式です。GDI +を使用しており、http://www.codeproject.com/Articles/3537/Loading-JPG-PNG-resources-using-GDIを使用してリソースからPNGファイルを読み込んでいます。
ボタンのグラフィックを処理するためにBS_OWNERDRAWを使用しました。問題は、「リソースからのPNG」コードを親のWM_DRAWITEMにリンクする方法がわからないことです。私がコードを実行した現在の方法では、HBITMAPを通過することによって.pngの透明性が失われます。
グローバル変数:
HBITMAP globalpic;
メインwndproc:
case WM_CREATE:
{
HWND hwndButton = CreateWindow(TEXT("button"), NULL,
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
190, 230, 260, 50, // <- the larger rect size
hWnd, (HMENU) HT_BUTTON1, hInst, NULL);
HTButton = (WNDPROC) SetWindowLong(hwndButton, GWL_WNDPROC, (LONG) ButtonProc);
}
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* lpDrawItem = (DRAWITEMSTRUCT*)lParam;
HBITMAP hBmp;
HDC hdc = CreateCompatibleDC(NULL);
if (hovering) // <- mousehover detection, not included
{
gdi.CreateBM(IDB_Website2, _T("PNG"), hInst, hdc, 62, 100, 200, 40);
} else {
gdi.CreateBM(IDB_Website1, _T("PNG"), hInst, hdc, 62, 100, 200, 40);
}
hBmp = globalpic; // get the global var gdi.CreateBM created
DeleteDC(hdc);
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
HDC hMemDC = CreateCompatibleDC(NULL);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
StretchBlt (lpDrawItem->hDC,
lpDrawItem->rcItem.left + 30,
lpDrawItem->rcItem.top + 5,
200, <- the width of image
40, <- the height of image
hMemDC,
0, 0,
bm.bmWidth,
bm.bmHeight,
SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
DeleteObject(hBmp);
break;
}
クラスGDIのメソッドCreateBM。
現在、より良い方法がわからないため、HBITMAPをグローバル変数globalpicに送信します。問題は、これを行うことによって、私が透明性を失うことです。
void CreateBM(UINT menuid, LPCTSTR pType, HMODULE hInst, HDC hdc, int x, int y, int w, int h)
{
CGdiPlusBitmapResource m_pBitmap;
m_pBitmap.Load(menuid, pType, hInst);
m_pBitmap.m_pBitmap->GetHBITMAP(RGB(255, 255, 0), &globalpic);
//m_pBitmap.m_pBitmap->GetHBITMAP(GetBkColor(hdc), &globalpic); // <- no-go either
}
これをもっと直接行う方法はありますか?HBITMAPルートを通過することは完全に不要だと感じていますが、私は一生の間、それをどのように行うべきかを理解することができませんでした。
繰り返しになりますが、HBITMAPの方法を使用しても問題がない場合は、現在の実装で色(RGB(255、255、0)...?)を透明にする方法についての指針はありますか?
ハンスへの回答:
このようなGDIメソッドもありますが、描画後に画像を削除できなかったため、現時点では使用されていません(ホバーすると画像が変更される場合に必要です)。
void Create(UINT menuid, LPCTSTR pType, HMODULE hInst, HDC hdc, int x, int y, int w, int h)
{
Graphics grpx(hdc);
ht_img = new CGdiPlusBitmapResource();
ht_img -> Load(menuid, pType, hInst);
grpx.DrawImage(*ht_img, x, y, w, h);
delete ht_img;
}