diff --git a/dlls/user32/button.c b/dlls/user32/button.c index f2097aa1d91..926563c98f2 100644 --- a/dlls/user32/button.c +++ b/dlls/user32/button.c @@ -446,6 +446,7 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, if (style & BS_NOTIFY) BUTTON_NOTIFY_PARENT(hWnd, BN_KILLFOCUS); + InvalidateRect( hWnd, NULL, FALSE ); break; case WM_SYSCOLORCHANGE: diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index bde52ca8b54..580582f58ad 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -1775,6 +1775,7 @@ static BOOL ignore_message( UINT message ) message == WM_GETICON || message == WM_GETOBJECT || message == WM_TIMECHANGE || + message == WM_DISPLAYCHANGE || message == WM_DEVICECHANGE); } @@ -1870,7 +1871,10 @@ static void add_message_(int line, const struct recvd_message *msg) di.u.lp = 0; di.u.item.type = dis->CtlType; di.u.item.ctl_id = dis->CtlID; - di.u.item.item_id = dis->itemID; + if (dis->CtlType == ODT_LISTBOX || + dis->CtlType == ODT_COMBOBOX || + dis->CtlType == ODT_MENU) + di.u.item.item_id = dis->itemID; di.u.item.action = dis->itemAction; di.u.item.state = dis->itemState; @@ -5088,6 +5092,8 @@ todo_wine { } /****************** button message test *************************/ +#define ID_BUTTON 0x000e + static const struct message WmSetFocusButtonSeq[] = { { HCBT_SETFOCUS, hook }, @@ -5095,7 +5101,9 @@ static const struct message WmSetFocusButtonSeq[] = { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam, 0 }, - { WM_CTLCOLORBTN, sent|defwinproc }, + { WM_CTLCOLORBTN, sent|parent }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, + { WM_APP, sent|wparam|lparam, 0, 0 }, { 0 } }; static const struct message WmKillFocusButtonSeq[] = @@ -5103,9 +5111,13 @@ static const struct message WmKillFocusButtonSeq[] = { HCBT_SETFOCUS, hook }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_KILLFOCUS, sent|wparam, 0 }, - { WM_CTLCOLORBTN, sent|defwinproc }, + { WM_CTLCOLORBTN, sent|parent }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_KILLFOCUS) }, { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 1 }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_CTLCOLORBTN, sent|parent }, { 0 } }; static const struct message WmSetFocusStaticSeq[] = @@ -5115,7 +5127,10 @@ static const struct message WmSetFocusStaticSeq[] = { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam, 0 }, - { WM_CTLCOLORSTATIC, sent|defwinproc }, + { WM_CTLCOLORSTATIC, sent|parent }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, + { WM_COMMAND, sent|wparam|parent|optional, MAKEWPARAM(ID_BUTTON, BN_CLICKED) }, /* radio button */ + { WM_APP, sent|wparam|lparam, 0, 0 }, { 0 } }; static const struct message WmKillFocusStaticSeq[] = @@ -5123,9 +5138,42 @@ static const struct message WmKillFocusStaticSeq[] = { HCBT_SETFOCUS, hook }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_KILLFOCUS, sent|wparam, 0 }, - { WM_CTLCOLORSTATIC, sent|defwinproc }, + { WM_CTLCOLORSTATIC, sent|parent }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_KILLFOCUS) }, { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 1 }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_CTLCOLORSTATIC, sent|parent }, + { 0 } +}; +static const struct message WmSetFocusOwnerdrawSeq[] = +{ + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, + { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam, 0 }, + { WM_CTLCOLORBTN, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x001040e4 }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { 0 } +}; +static const struct message WmKillFocusOwnerdrawSeq[] = +{ + { HCBT_SETFOCUS, hook }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_KILLFOCUS, sent|wparam, 0 }, + { WM_CTLCOLORBTN, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000040e4 }, + { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_KILLFOCUS) }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, + { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 1 }, + { WM_APP, sent|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_CTLCOLORBTN, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000010e4 }, { 0 } }; static const struct message WmLButtonDownSeq[] = @@ -5242,10 +5290,10 @@ static void test_button_messages(void) { BS_AUTORADIOBUTTON, DLGC_BUTTON | DLGC_RADIOBUTTON, WmSetFocusStaticSeq, WmKillFocusStaticSeq }, { BS_OWNERDRAW, DLGC_BUTTON, - WmSetFocusButtonSeq, WmKillFocusButtonSeq } + WmSetFocusOwnerdrawSeq, WmKillFocusOwnerdrawSeq } }; unsigned int i; - HWND hwnd; + HWND hwnd, parent; DWORD dlg_code; HFONT zfont; @@ -5262,30 +5310,58 @@ static void test_button_messages(void) subclass_button(); + parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok(parent != 0, "Failed to create parent window\n"); + for (i = 0; i < sizeof(button)/sizeof(button[0]); i++) { - hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_POPUP, - 0, 0, 50, 14, 0, 0, 0, NULL); + MSG msg; + DWORD style; + + hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_CHILD | BS_NOTIFY, + 0, 0, 50, 14, parent, (HMENU)ID_BUTTON, 0, NULL); ok(hwnd != 0, "Failed to create button window\n"); + style = GetWindowLongA(hwnd, GWL_STYLE); + style &= ~(WS_CHILD | BS_NOTIFY); + /* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */ + if (button[i].style == BS_USERBUTTON) + todo_wine ok(style == BS_PUSHBUTTON, "expected style BS_PUSHBUTTON got %x\n", style); + else + ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style); + dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0); ok(dlg_code == button[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); SetFocus(0); + flush_events(); flush_sequence(); + log_all_parent_messages++; + trace("button style %08x\n", button[i].style); + ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus()); SetFocus(hwnd); + SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */ + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg); ok_sequence(button[i].setfocus, "SetFocus(hwnd) on a button", FALSE); SetFocus(0); + SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */ + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg); ok_sequence(button[i].killfocus, "SetFocus(0) on a button", FALSE); + log_all_parent_messages--; + + ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus()); DestroyWindow(hwnd); } + DestroyWindow(parent); + hwnd = CreateWindowExA(0, "my_button_class", "test", BS_PUSHBUTTON | WS_POPUP | WS_VISIBLE, 0, 0, 50, 14, 0, 0, 0, NULL); ok(hwnd != 0, "Failed to create button window\n"); @@ -7169,7 +7245,7 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam message == WM_PARENTNOTIFY || message == WM_CANCELMODE || message == WM_SETFOCUS || message == WM_KILLFOCUS || message == WM_ENABLE || message == WM_ENTERIDLE || - message == WM_DRAWITEM || + message == WM_DRAWITEM || message == WM_COMMAND || message == WM_IME_SETCONTEXT) { switch (message)