0

私の友人がアプリケーションをリリースしようとしていて、そのためのランチャーを作成するように頼まれました。最終的にWinAPIを研究するのは良い言い訳だと思い、比較的短い時間枠でも簡単なランチャーを簡単に実行できると思いました。

私は間違っていた。

さまざまなことを開始する5つのボタンを備えたランチャーウィンドウを作成しようとしています。目標は、内部に小さな画像がある透明なボタン(まだ作成されていません)を用意することです。画像は、ユーザーが大きなボタン領域にカーソルを合わせたときにのみ表示されます。

画像は.png形式です。GDI +を使用しており、http://www.codeproject.com/Articles/3537/Loading-JPG-PNG-resources-using-GDIを使用してリソースからPNGファイルを読み込んでいます。

私はMouseTrackEventsを使用してマウスを追跡しており、ボタンもサブクラス化しています。問題は、WM_MOUSELEAVEメッセージをどのように処理すべきかわからないことです。描いた画像を消す方法がわかりません。ht_imgを変数として保存し、後で参照する必要がある場合、方法がわかりません。

これが私がこれまでに持っているものです。この例では、リソースIDB_Website2から.pngをロードします。画像の表示は機能します(現在、何度も何度もレンダリングされ続けていますが):

WndProc:

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
GDI gdi;

switch (Msg)
{
    case WM_CREATE:
    {
        HWND hwndButton = CreateWindow(TEXT("button"), NULL,
                          WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
                          80, 10, 100, 50,
                          hWnd, (HMENU) HT_BUTTON1, NULL, NULL);
        HTButton = (WNDPROC) SetWindowLong(hwndButton, GWL_WNDPROC, (LONG) ButtonProc);
    }
...

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        gdi.InitList(hInst, hdc);
        EndPaint(hWnd, &ps);
        break;

Buttonproc(サブクラス化されたボタン):

LRESULT CALLBACK ButtonProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
MouseTrackEvents MouseTrack;
GDI gdi;

HDC odc = GetDC(GetParent(hWnd));

switch(Msg)
{
    case WM_MOUSEMOVE:
        MouseTrack.OnMouseMove(hWnd);
        break;

    case WM_MOUSEHOVER:
        gdi.Create(IDB_Website2, _T("PNG"), hInst, odc, 62, 347, 200, 40, true);
        MouseTrack.Reset(hWnd);
        break;

    case WM_MOUSELEAVE:
        MouseTrack.Reset(hWnd);
        break;
}

return CallWindowProc (HTButton, hWnd, Msg, wParam, lParam);
}

クラス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;
}

これはこれまでのところかなりの挑戦でした!時々少し涙が出ますが、楽しかったです。:-)私がどのように進めるべきかについてのアドバイスに感謝します。


編集:エイドリアンに答える

Buttonprocを変更しようとしましたが、画像がレンダリングされていないようです。これが私がしたことです:

LRESULT CALLBACK ButtonProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    MouseTrackEvents MouseTrack;
    GDI gdi;
    HDC odc = GetDC(GetParent(hWnd));
    PAINTSTRUCT ps;

    int result;

    switch(Msg)
    {
    case WM_MOUSEMOVE:
        MouseTrack.OnMouseMove(hWnd);
        break;

    case WM_MOUSEHOVER:
        hovering = true;
        break;

    case WM_MOUSELEAVE:
        hovering = false;
        MouseTrack.Reset(hWnd);
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        result = CallWindowProc(HTButton, hWnd, Msg, wParam, lParam);
        if (hovering == true) {
            gdi.Create(IDB_Play2, _T("PNG"), hInst, hdc, 62, 100, 200, 40);
        }
        EndPaint(hWnd, &ps);
        return result;
    }
    return CallWindowProc (HTButton, hWnd, Msg, wParam, lParam);
}
4

1 に答える 1

1

マウスイベントの処理で直接ペイントを実行したくない場合があります。基になる実装を呼び出し、ホバー状態に基づいて拡張することにより、ボタンプロシージャでWM_PAINTを処理することをお勧めします。次に、マウスの処理は、状態変数を反転してボタンを無効にすることに対応します(これによりボタンが再描画されます)。

case WM_PAINT:
    // start with the standard rendering
    int result = CallWindowProc (HTButton, hWnd, Msg, wParam, lParam);
    // then overdraw our embellishments
    if (my_state_variable == hovering) {
         DrawOverlayImage();
    }
    return result;  // don't just break here, or you'll call CallWindowProc again
于 2012-08-31T16:35:50.820 に答える