mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 11:26:10 +00:00
Button should do ReleaseCapture() on WM_KILLFOCUS if it's in a pressed
state. Add a comprehensive test case for capture behaviour.
This commit is contained in:
parent
93dd39a37c
commit
58fe866d01
2 changed files with 169 additions and 1 deletions
|
@ -363,7 +363,11 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
set_button_state( hWnd, get_button_state(hWnd) & ~BUTTON_HASFOCUS );
|
||||
state = get_button_state( hWnd );
|
||||
if ((state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
|
||||
ReleaseCapture();
|
||||
|
||||
set_button_state( hWnd, state & ~BUTTON_HASFOCUS );
|
||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||
break;
|
||||
|
||||
|
|
|
@ -1814,6 +1814,166 @@ static void test_SetActiveWindow(HWND hwnd)
|
|||
ok( GetActiveWindow() != hwnd2, "Window %p is still active\n", hwnd2 );
|
||||
}
|
||||
|
||||
static void check_wnd_state(HWND active, HWND foreground, HWND focus, HWND capture)
|
||||
{
|
||||
ok(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
|
||||
if (foreground)
|
||||
ok(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
|
||||
ok(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
|
||||
ok(capture == GetCapture(), "GetCapture() = %p\n", GetCapture());
|
||||
}
|
||||
|
||||
static WNDPROC old_button_proc;
|
||||
|
||||
static LRESULT WINAPI button_hook_proc(HWND button, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
LRESULT ret;
|
||||
USHORT key_state;
|
||||
|
||||
key_state = GetKeyState(VK_LBUTTON);
|
||||
ok(!(key_state & 0x8000), "VK_LBUTTON should not be pressed, state %04x\n", key_state);
|
||||
|
||||
ret = CallWindowProcA(old_button_proc, button, msg, wparam, lparam);
|
||||
|
||||
if (msg == WM_LBUTTONDOWN)
|
||||
{
|
||||
HWND hwnd, capture;
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
trace("hwnd %p\n", hwnd);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
trace("hwnd %p\n", hwnd);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
/* button wnd proc should release capture on WM_KILLFOCUS if it does
|
||||
* match internal button state.
|
||||
*/
|
||||
SendMessage(button, WM_KILLFOCUS, 0, 0);
|
||||
check_wnd_state(button, button, button, 0);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
check_wnd_state(hwnd, hwnd, hwnd, 0);
|
||||
|
||||
capture = SetCapture(hwnd);
|
||||
ok(capture == 0, "SetCapture() = %p\n", capture);
|
||||
|
||||
check_wnd_state(hwnd, hwnd, hwnd, hwnd);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
check_wnd_state(button, 0, button, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void test_capture_1(void)
|
||||
{
|
||||
HWND button, capture;
|
||||
|
||||
capture = GetCapture();
|
||||
ok(capture == 0, "GetCapture() = %p\n", capture);
|
||||
|
||||
button = CreateWindowExA(0, "button", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(button);
|
||||
trace("button %p\n", button);
|
||||
|
||||
old_button_proc = (WNDPROC)SetWindowLongPtrA(button, GWLP_WNDPROC, (LONG_PTR)button_hook_proc);
|
||||
|
||||
SendMessageA(button, WM_LBUTTONDOWN, 0, 0);
|
||||
|
||||
DestroyWindow(button);
|
||||
}
|
||||
|
||||
static void test_capture_2(void)
|
||||
{
|
||||
HWND button, hwnd, capture;
|
||||
|
||||
check_wnd_state(0, 0, 0, 0);
|
||||
|
||||
button = CreateWindowExA(0, "button", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(button);
|
||||
trace("button %p\n", button);
|
||||
|
||||
check_wnd_state(button, button, button, 0);
|
||||
|
||||
capture = SetCapture(button);
|
||||
ok(capture == 0, "SetCapture() = %p\n", capture);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
/* button wnd proc should ignore WM_KILLFOCUS if it doesn't match
|
||||
* internal button state.
|
||||
*/
|
||||
SendMessage(button, WM_KILLFOCUS, 0, 0);
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
trace("hwnd %p\n", hwnd);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
trace("hwnd %p\n", hwnd);
|
||||
|
||||
check_wnd_state(button, button, button, button);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
|
||||
check_wnd_state(hwnd, hwnd, hwnd, button);
|
||||
|
||||
capture = SetCapture(hwnd);
|
||||
ok(capture == button, "SetCapture() = %p\n", capture);
|
||||
|
||||
check_wnd_state(hwnd, hwnd, hwnd, hwnd);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
check_wnd_state(button, button, button, 0);
|
||||
|
||||
DestroyWindow(button);
|
||||
check_wnd_state(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void test_capture_3(HWND hwnd1, HWND hwnd2)
|
||||
{
|
||||
ShowWindow(hwnd1, SW_HIDE);
|
||||
ShowWindow(hwnd2, SW_HIDE);
|
||||
|
||||
ok(!IsWindowVisible(hwnd1), "%p should be invisible\n", hwnd1);
|
||||
ok(!IsWindowVisible(hwnd2), "%p should be invisible\n", hwnd2);
|
||||
|
||||
SetCapture(hwnd1);
|
||||
check_wnd_state(0, 0, 0, hwnd1);
|
||||
|
||||
SetCapture(hwnd2);
|
||||
check_wnd_state(0, 0, 0, hwnd2);
|
||||
|
||||
ShowWindow(hwnd1, SW_SHOW);
|
||||
check_wnd_state(hwnd1, hwnd1, hwnd1, hwnd2);
|
||||
}
|
||||
|
||||
START_TEST(win)
|
||||
{
|
||||
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
|
||||
|
@ -1852,6 +2012,10 @@ START_TEST(win)
|
|||
assert( hwndMain );
|
||||
assert( hwndMain2 );
|
||||
|
||||
test_capture_1();
|
||||
test_capture_2();
|
||||
test_capture_3(hwndMain, hwndMain2);
|
||||
|
||||
test_parent_owner();
|
||||
test_shell_window();
|
||||
|
||||
|
|
Loading…
Reference in a new issue