0

Windows C API を使用して、Windows 8 スタイルのカスタム ボタンを作成しようとしています。ただし、ボタンを再描画した後にボタンにテキストを描画しようとすると、何も表示されません! ボタンの子として静的ウィンドウを作成し、ボタンを再描画するときにWS_ERASEBKGNDメッセージを送信しようとしましたが、ボタンを初めて再描画するとすぐに消えます! カスタム ボタンのウィンドウ プロシージャは次のとおりです。

LRESULT CALLBACK ButtonWindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    //static HWND static_text_handle;
    HDC hdc;
    PAINTSTRUCT ps;
    DWORD color;
    HFONT font,holdFont;
    static RECT rect;
    wchar_t test[] = L"test";
    TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,HOVER_DEFAULT};
    /*static*/ HBRUSH brush = CreateSolidBrush(RGB(20,30,40));
    /*static*/ HBRUSH clicked_brush = CreateSolidBrush(RGB(40,50,60));
    /*static*/ HBRUSH hover_brush = CreateSolidBrush(RGB(70,80,90));
    //TrackMouseEvent(&tme);
    switch(msg)
    {
    case WM_CREATE:
        //static_text_handle = CreateWindowW(L"Static",L"test",WS_CHILD | WS_VISIBLE,0,0,20,20,hwnd,NULL,NULL,NULL);
        //brush = ((struct custom_button_colors*)(lParam))->default_color;
        //clicked_brush = ((struct custom_button_colors*)(lParam))->push_color;
        //hover_brush = ((struct custom_button_colors*)(lParam))->hover_color;
        break;
    case WM_LBUTTONDOWN:
            SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_DOWN);
            break;
    case WM_LBUTTONUP:
        SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_UP);
        break;
    case WM_MOUSEMOVE:
        //Beep(1000,1000);
        TrackMouseEvent(&tme);
        if (GetAsyncKeyState(VK_LBUTTON))
        {
            SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_L_DOWN);
        }
        else
        {
            SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)LPARAM_MOUSEHOVER);
        }
        break;
    case WM_MOUSELEAVE:
        SendMessage(hwnd,WM_ERASEBKGND,(WPARAM)GetDC(hwnd),(LPARAM)-1);
        break;
    case WM_ERASEBKGND:
        GetClientRect(hwnd,&rect);
        if (lParam == LPARAM_L_DOWN)
        {
            FillRect((HDC)wParam,&rect,clicked_brush);
        }
        else if (lParam == LPARAM_MOUSEHOVER)
        {
            FillRect((HDC)wParam,&rect,hover_brush);
            break;
        }
        else
        {
            POINT mousepos;
            GetCursorPos(&mousepos);
            if (WindowFromPoint(mousepos) == hwnd)
            {
                FillRect((HDC)wParam,&rect,hover_brush);
            }
            else
            {
                FillRect((HDC)wParam,&rect,brush);
            }
        }
        hdc = BeginPaint(hwnd,&ps);
        color = GetSysColor(COLOR_BTNFACE);
        SetBkColor(hdc,color);
        font = CreateFontW(25, 0, 0, 0, FW_MEDIUM, 0, 0, 0, 0,0, 0, ANTIALIASED_QUALITY, 0, L"Tahoma");
        holdFont = SelectObject(hdc, font);
        TextOutW(hdc,200,200,test,lstrlenW(test));
        SelectObject(hdc,holdFont);
        DeleteObject(font);
        EndPaint(hwnd,&ps);
        break;
    default:
        return DefWindowProc(hwnd,msg,wParam,lParam);
    }
    return 0;
}

私はWindowsプログラミングの初心者なので、質問が些細なことでしたら申し訳ありません。

4

1 に答える 1

1

1) WM_ERASEBKGND で BeginPaint/EndPaint を使用しないでください。そのコードを WM_PAINT ハンドラに移動します。

2) SetWindowLong と GWL_USERDATA インデックスを使用してボタンの状態 (UP または DOWN) を保存し、GetWindowLong を使用して現在の状態を取得します。

3) SetCapture を使用して、WM_LBUTTONDOWN で始まるマウスをキャプチャします。マウスの位置に応じてボタンの状態 (UP または DOWN) を更新します

4) 描画が必要な場合は RedrawWindow を使用します

于 2013-06-27T16:47:09.047 に答える