当ownerdraw按钮存在时处理默认按钮

时间:2017-07-23 16:44:13

标签: c++ winapi mfc

我的ownerdraw类没有正确分配默认按钮。

在下面的示例中,有一个标准的默认按钮和一个ownerdraw按钮。对话框启动时,默认按钮会突出显示。当我单击ownerdraw按钮时,ownerdraw会突出显示,但默认按钮不会失去高亮显示。

单击ownerdraw按钮后立即拍摄的屏幕:
Dialog, ownerdraw, default button

当我再次单击按钮时,它工作正常。然后它只显示一个默认按钮。

如果我覆盖WM_PAINT而不是WM_DRAWITEM,它可以正常工作。如果没有编辑控件,它可以正常工作。

但是,当对话框启动时,下面的代码无法正确处理高亮显示。

#include <Windows.h>
#include <Uxtheme.h>
#include <vssym32.h>
#include "Resource.h"

#pragma comment(lib, "Uxtheme.lib")
#pragma comment(lib, "ComCtl32.lib")

LRESULT CALLBACK ButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubClass, DWORD_PTR)
{
    switch(msg)
    {
    case WM_NCDESTROY:
        RemoveWindowSubclass(hwnd, ButtonProc, uIdSubClass);
        break;
    }
    return DefSubclassProc(hwnd, msg, wParam, lParam);
}

BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    if(msg == WM_INITDIALOG)
    {
        CreateWindow(L"EDIT", L"", 
            WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER | ES_WANTRETURN, 
            5, 5, 200, 40, hwnd, HMENU(100), 0, 0);

        HWND bn1 = CreateWindow(L"BUTTON", L"Standard/Default",
            WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
            5, 55 * 1, 200, 50, hwnd, HMENU(101), 0, 0);

        HWND bn2 = CreateWindow(L"BUTTON", L"OwnerDraw",
            WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW,
            5, 55 * 2, 200, 50, hwnd, HMENU(102), 0, 0);

        HFONT hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
        SendMessage(bn1, WM_SETFONT, (WPARAM)hfont, 0);
        SendMessage(bn2, WM_SETFONT, (WPARAM)hfont, 0);
        SetWindowSubclass(bn2, ButtonProc, 101, 0);
        return 0;
    }

    if(msg == WM_DRAWITEM)
    {
        LPDRAWITEMSTRUCT di = (LPDRAWITEMSTRUCT)lp;
        HTHEME htheme = OpenThemeData(di->hwndItem, L"BUTTON");
        if(htheme)
        {
            UINT bm_getstate = (UINT)SendMessage(di->hwndItem, BM_GETSTATE, 0, 0);

            int state_id = PBS_NORMAL;

            if(!IsWindowEnabled(di->hwndItem))  
                state_id = PBS_DISABLED;

            if(bm_getstate & BST_PUSHED)
                state_id = PBS_PRESSED;

            if(bm_getstate & BST_FOCUS)
                state_id = PBS_DEFAULTED;

            RECT rc = di->rcItem;
            DrawThemeBackground(htheme, di->hDC, BP_PUSHBUTTON, state_id, &rc, NULL);
            DrawThemeText(htheme, di->hDC, BP_PUSHBUTTON, state_id, L"<OwnerDraw>", -1,
                DT_CENTER | DT_SINGLELINE | DT_VCENTER, 0, &rc);

            if(bm_getstate & BST_FOCUS && !(di->itemState & ODS_NOFOCUSRECT))
            {
                MARGINS margins;
                GetThemeMargins(htheme, di->hDC, BP_PUSHBUTTON, PBS_DEFAULTED,
                    TMT_CONTENTMARGINS, &rc, &margins);
                InflateRect(&rc, -margins.cxLeftWidth, -margins.cyTopHeight);
                DrawFocusRect(di->hDC, &rc);
            }

            CloseThemeData(htheme);
        }
    }

    if(msg == WM_COMMAND && wp == IDCANCEL)
        EndDialog(hwnd, wp);

    return FALSE;
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int)
{
    return (int)DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, (DLGPROC)DlgProc);
}

0 个答案:

没有答案