1

部分的に透明な小さな画像が中央に配置された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;
}
4

0 に答える 0