Author: akhaldi Date: Thu Feb 26 09:05:15 2015 New Revision: 66465
URL: http://svn.reactos.org/svn/reactos?rev=66465&view=rev Log: [USER32_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246
Modified: trunk/rostests/winetests/user32/class.c trunk/rostests/winetests/user32/dce.c trunk/rostests/winetests/user32/dde.c trunk/rostests/winetests/user32/input.c trunk/rostests/winetests/user32/menu.c trunk/rostests/winetests/user32/msg.c trunk/rostests/winetests/user32/win.c trunk/rostests/winetests/user32/winstation.c
Modified: trunk/rostests/winetests/user32/class.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/class.c?r... ============================================================================== --- trunk/rostests/winetests/user32/class.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/class.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -1101,6 +1101,52 @@ } }
+static void test_IME(void) +{ + static const WCHAR ime_classW[] = {'I','M','E',0}; + + char module_name[MAX_PATH], *ptr; + MEMORY_BASIC_INFORMATION mbi; + WNDCLASSW wnd_classw; + WNDCLASSA wnd_class; + SIZE_T size; + BOOL ret; + + if (!GetProcAddress(GetModuleHandleA("user32.dll"), "BroadcastSystemMessageExA")) + { + win_skip("BroadcastSystemMessageExA not available, skipping IME class test\n"); + return; + } + + ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n"); + + ret = GetClassInfoA(NULL, "IME", &wnd_class); + ok(ret, "GetClassInfo failed: %d\n", GetLastError()); + + size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi)); + ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size); + if (size == sizeof(mbi)) { + size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name)); + ok(size, "GetModuleFileName failed\n"); + for (ptr = module_name+size-1; ptr > module_name; ptr--) + if (*ptr == '\' || *ptr == '/') break; + if (*ptr == '\' || *ptr=='/') ptr++; + ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr); + } + + ret = GetClassInfoW(NULL, ime_classW, &wnd_classw); + ok(ret, "GetClassInfo failed: %d\n", GetLastError()); + + size = VirtualQuery(wnd_classw.lpfnWndProc, &mbi, sizeof(mbi)); + ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size); + size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name)); + ok(size, "GetModuleFileName failed\n"); + for (ptr = module_name+size-1; ptr > module_name; ptr--) + if (*ptr == '\' || *ptr == '/') break; + if (*ptr == '\' || *ptr=='/') ptr++; + ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr); +} + START_TEST(class) { char **argv; @@ -1113,6 +1159,7 @@ return; }
+ test_IME(); test_GetClassInfo(); test_extra_values();
Modified: trunk/rostests/winetests/user32/dce.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/dce.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/dce.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/dce.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -33,7 +33,7 @@ #define DCX_USESTYLE 0x00010000 #endif
-static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2; +static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2, hwnd_parent, hwnd_parentdc;
/* test behavior of DC attributes with various GetDC/ReleaseDC combinations */ static void test_dc_attributes(void) @@ -190,7 +190,7 @@ { HDC old_hdc, hdc; HRGN hrgn, hrgn2; - RECT rect; + RECT rect, parent_rect;
/* cache DC */
@@ -325,6 +325,20 @@ ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30), "clip box must have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); ReleaseDC( hwnd_classdc2, hdc ); + + /* parent DC */ + hdc = GetDC( hwnd_parentdc ); + GetClipBox( hdc, &rect ); + ReleaseDC( hwnd_parentdc, hdc ); + + hdc = GetDC( hwnd_parent ); + GetClipBox( hdc, &parent_rect ); + ReleaseDC( hwnd_parent, hdc ); + + ok( rect.left == parent_rect.left, "rect.left = %d, expected %d\n", rect.left, parent_rect.left ); + ok( rect.top == parent_rect.top, "rect.top = %d, expected %d\n", rect.top, parent_rect.top ); + ok( rect.right == parent_rect.right, "rect.right = %d, expected %d\n", rect.right, parent_rect.right ); + ok( rect.bottom == parent_rect.bottom, "rect.bottom = %d, expected %d\n", rect.bottom, parent_rect.bottom ); }
@@ -332,8 +346,9 @@ static void test_begin_paint(void) { HDC old_hdc, hdc; - RECT rect; + RECT rect, parent_rect; PAINTSTRUCT ps; + COLORREF cr;
/* cache DC */
@@ -405,6 +420,27 @@ GetClipBox( hdc, &rect ); ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20), "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); + ReleaseDC( hwnd_classdc2, hdc ); + EndPaint( hwnd_classdc, &ps ); + + /* parent DC */ + RedrawWindow( hwnd_parent, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE ); + RedrawWindow( hwnd_parentdc, NULL, 0, RDW_INVALIDATE ); + hdc = BeginPaint( hwnd_parentdc, &ps ); + GetClipBox( hdc, &rect ); + cr = SetPixel( hdc, 10, 10, RGB(255, 0, 0) ); + ok( cr != -1, "error drawing outside of window client area\n" ); + EndPaint( hwnd_parentdc, &ps ); + GetClientRect( hwnd_parent, &parent_rect ); + + ok( rect.left == parent_rect.left, "rect.left = %d, expected %d\n", rect.left, parent_rect.left ); + ok( rect.top == parent_rect.top, "rect.top = %d, expected %d\n", rect.top, parent_rect.top ); + todo_wine ok( rect.right == parent_rect.right, "rect.right = %d, expected %d\n", rect.right, parent_rect.right ); + todo_wine ok( rect.bottom == parent_rect.bottom, "rect.bottom = %d, expected %d\n", rect.bottom, parent_rect.bottom ); + + hdc = GetDC( hwnd_parent ); + todo_wine ok( GetPixel( hdc, 10, 10 ) == cr, "error drawing outside of window client area\n" ); + ReleaseDC( hwnd_parent, hdc ); }
/* test ScrollWindow with window DCs */ @@ -593,6 +629,9 @@ cls.style = CS_DBLCLKS | CS_CLASSDC; cls.lpszClassName = "classdc_class"; RegisterClassA(&cls); + cls.style = CS_PARENTDC; + cls.lpszClassName = "parentdc_class"; + RegisterClassA(&cls);
hwnd_cache = CreateWindowA("cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE, 0, 0, 100, 100, @@ -606,6 +645,11 @@ hwnd_classdc2 = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE, 200, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL ); + hwnd_parent = CreateWindowA("static", NULL, WS_OVERLAPPED | WS_VISIBLE, + 400, 0, 100, 100, 0, 0, 0, NULL ); + hwnd_parentdc = CreateWindowA("parentdc_class", NULL, WS_CHILD | WS_VISIBLE, + 0, 0, 1, 1, hwnd_parent, 0, 0, NULL ); + test_dc_attributes(); test_parameters(); test_dc_visrgn(); @@ -614,6 +658,7 @@ test_invisible_create(); test_dc_layout();
+ DestroyWindow(hwnd_parent); DestroyWindow(hwnd_classdc2); DestroyWindow(hwnd_classdc); DestroyWindow(hwnd_owndc);
Modified: trunk/rostests/winetests/user32/dde.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/dde.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/dde.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/dde.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -776,7 +776,6 @@ else if (msg_index == 10) { DWORD rsize = 0; - size = 0;
size = DdeGetData(hdata, NULL, 0, 0); ok(size == 17, "DdeGetData should have returned 17 not %d\n", size); @@ -1591,7 +1590,7 @@ info.cb = sizeof(info); ret = DdeQueryConvInfo(hconv, QID_SYNC, &info); ok(ret, "wrong info size %d, DdeQueryConvInfo error %x\n", ret, DdeGetLastError(dde_inst)); - ok(info.ConvCtxt.iCodePage == client_unicode ? CP_WINUNICODE : CP_WINANSI, + ok(info.ConvCtxt.iCodePage == (client_unicode ? CP_WINUNICODE : CP_WINANSI), "wrong iCodePage %d\n", info.ConvCtxt.iCodePage); ok(!info.hConvPartner, "unexpected info.hConvPartner: %p\n", info.hConvPartner); todo_wine {
Modified: trunk/rostests/winetests/user32/input.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/input.c?r... ============================================================================== --- trunk/rostests/winetests/user32/input.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/input.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -1361,7 +1361,7 @@
/* Get a valid content for the input struct */ if(!GetCursorPos(&point)) { - skip("GetCursorPos() failed with error %u\n", GetLastError()); + win_skip("GetCursorPos() failed with error %u\n", GetLastError()); return; } memset(&in, 0, sizeof(MOUSEMOVEPOINT)); @@ -1595,6 +1595,14 @@ BOOL ret; char klid[KL_NAMELENGTH];
+if (0) /* crashes on native system */ + ret = GetKeyboardLayoutNameA(NULL); + + SetLastError(0xdeadbeef); + ret = GetKeyboardLayoutNameW(NULL); + ok(!ret, "got %d\n", ret); + ok(GetLastError() == ERROR_NOACCESS, "got %d\n", GetLastError()); + if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) return;
klid[0] = 0; @@ -1643,6 +1651,308 @@ ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) ); }
+static void simulate_click(BOOL left, int x, int y) +{ + INPUT input[2]; + UINT events_no; + + SetCursorPos(x, y); + memset(input, 0, sizeof(input)); + input[0].type = INPUT_MOUSE; + U(input[0]).mi.dx = x; + U(input[0]).mi.dy = y; + U(input[0]).mi.dwFlags = left ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN; + input[1].type = INPUT_MOUSE; + U(input[1]).mi.dx = x; + U(input[1]).mi.dy = y; + U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP; + events_no = SendInput(2, input, sizeof(input[0])); + ok(events_no == 2, "SendInput returned %d\n", events_no); +} + +static BOOL wait_for_message( MSG *msg ) +{ + BOOL ret; + + for (;;) + { + ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE); + if (ret) + { + if (msg->message == WM_PAINT) DispatchMessageA(msg); + else break; + } + else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break; + } + if (!ret) msg->message = 0; + return ret; +} + +static BOOL wait_for_event(HANDLE event, int timeout) +{ + DWORD end_time = GetTickCount() + timeout; + MSG msg; + + do { + if(MsgWaitForMultipleObjects(1, &event, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0) + return TRUE; + while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); + timeout = end_time - GetTickCount(); + }while(timeout > 0); + + return FALSE; +} + +static WNDPROC def_static_proc; +static DWORD hittest_no; +static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + if (msg == WM_NCHITTEST) + { + /* break infinite hittest loop */ + if(hittest_no > 50) return HTCLIENT; + hittest_no++; + } + + return def_static_proc(hwnd, msg, wp, lp); +} + +struct thread_data +{ + HANDLE start_event; + HANDLE end_event; + HWND win; +}; + +static DWORD WINAPI create_static_win(void *arg) +{ + struct thread_data *thread_data = arg; + HWND win; + + win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, + 100, 100, 100, 100, 0, NULL, NULL, NULL); + ok(win != 0, "CreateWindow failed\n"); + def_static_proc = (void*)SetWindowLongPtrA(win, + GWLP_WNDPROC, (LONG_PTR)static_hook_proc); + thread_data->win = win; + + SetEvent(thread_data->start_event); + wait_for_event(thread_data->end_event, 5000); + return 0; +} + +static void test_Input_mouse(void) +{ + BOOL got_button_down, got_button_up; + HWND hwnd, button_win, static_win; + struct thread_data thread_data; + HANDLE thread; + DWORD thread_id; + POINT pt; + MSG msg; + + button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP, + 100, 100, 100, 100, 0, NULL, NULL, NULL); + ok(button_win != 0, "CreateWindow failed\n"); + + pt.x = pt.y = 150; + hwnd = WindowFromPoint(pt); + if (hwnd != button_win) + { + skip("there's another window covering test window\n"); + DestroyWindow(button_win); + return; + } + + /* simple button click test */ + simulate_click(TRUE, 150, 150); + got_button_down = got_button_up = FALSE; + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_LBUTTONDOWN) + { + got_button_down = TRUE; + } + else if (msg.message == WM_LBUTTONUP) + { + got_button_up = TRUE; + break; + } + } + ok(got_button_down, "expected WM_LBUTTONDOWN message\n"); + ok(got_button_up, "expected WM_LBUTTONUP message\n"); + + /* click through HTTRANSPARENT child window */ + static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD, + 0, 0, 100, 100, button_win, NULL, NULL, NULL); + ok(static_win != 0, "CreateWindow failed\n"); + def_static_proc = (void*)SetWindowLongPtrA(static_win, + GWLP_WNDPROC, (LONG_PTR)static_hook_proc); + simulate_click(FALSE, 150, 150); + hittest_no = 0; + got_button_down = got_button_up = FALSE; + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_RBUTTONDOWN) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_down = TRUE; + } + else if (msg.message == WM_RBUTTONUP) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_up = TRUE; + break; + } + } + ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n"); + ok(got_button_down, "expected WM_RBUTTONDOWN message\n"); + ok(got_button_up, "expected WM_RBUTTONUP message\n"); + DestroyWindow(static_win); + + /* click through HTTRANSPARENT top-level window */ + static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, + 100, 100, 100, 100, 0, NULL, NULL, NULL); + ok(static_win != 0, "CreateWindow failed\n"); + def_static_proc = (void*)SetWindowLongPtrA(static_win, + GWLP_WNDPROC, (LONG_PTR)static_hook_proc); + simulate_click(TRUE, 150, 150); + hittest_no = 0; + got_button_down = got_button_up = FALSE; + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_LBUTTONDOWN) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_down = TRUE; + } + else if (msg.message == WM_LBUTTONUP) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_up = TRUE; + break; + } + } + ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n"); + ok(got_button_down, "expected WM_LBUTTONDOWN message\n"); + ok(got_button_up, "expected WM_LBUTTONUP message\n"); + DestroyWindow(static_win); + + /* click on HTTRANSPARENT top-level window that belongs to other thread */ + thread_data.start_event = CreateEventA(NULL, FALSE, FALSE, NULL); + ok(thread_data.start_event != NULL, "CreateEvent failed\n"); + thread_data.end_event = CreateEventA(NULL, FALSE, FALSE, NULL); + ok(thread_data.end_event != NULL, "CreateEvent failed\n"); + thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, NULL); + ok(thread != NULL, "CreateThread failed\n"); + hittest_no = 0; + got_button_down = got_button_up = FALSE; + WaitForSingleObject(thread_data.start_event, INFINITE); + simulate_click(FALSE, 150, 150); + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_RBUTTONDOWN) + got_button_down = TRUE; + else if (msg.message == WM_RBUTTONUP) + got_button_up = TRUE; + } + SetEvent(thread_data.end_event); + WaitForSingleObject(thread, INFINITE); + ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n"); + ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n"); + ok(!got_button_up, "unexpected WM_RBUTTONUP message\n"); + + /* click on HTTRANSPARENT top-level window that belongs to other thread, + * thread input queues are attached */ + thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, &thread_id); + ok(thread != NULL, "CreateThread failed\n"); + hittest_no = 0; + got_button_down = got_button_up = FALSE; + WaitForSingleObject(thread_data.start_event, INFINITE); + ok(AttachThreadInput(thread_id, GetCurrentThreadId(), TRUE), + "AttachThreadInput failed\n"); + while (wait_for_message(&msg)) DispatchMessageA(&msg); + SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); + simulate_click(TRUE, 150, 150); + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_LBUTTONDOWN) + got_button_down = TRUE; + else if (msg.message == WM_LBUTTONUP) + got_button_up = TRUE; + } + SetEvent(thread_data.end_event); + WaitForSingleObject(thread, INFINITE); + todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n"); + ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n"); + ok(!got_button_up, "unexpected WM_LBUTTONUP message\n"); + + /* click after SetCapture call */ + SetCapture(button_win); + got_button_down = got_button_up = FALSE; + simulate_click(FALSE, 50, 50); + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_RBUTTONDOWN) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_down = TRUE; + } + else if (msg.message == WM_RBUTTONUP) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_up = TRUE; + break; + } + } + ok(got_button_down, "expected WM_RBUTTONDOWN message\n"); + ok(got_button_up, "expected WM_RBUTTONUP message\n"); + + /* click on child window after SetCapture call */ + hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD, + 0, 0, 100, 100, button_win, NULL, NULL, NULL); + ok(hwnd != 0, "CreateWindow failed\n"); + got_button_down = got_button_up = FALSE; + simulate_click(TRUE, 150, 150); + while (wait_for_message(&msg)) + { + DispatchMessageA(&msg); + + if (msg.message == WM_LBUTTONDOWN) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_down = TRUE; + } + else if (msg.message == WM_LBUTTONUP) + { + ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd); + got_button_up = TRUE; + break; + } + } + ok(got_button_down, "expected WM_LBUTTONDOWN message\n"); + ok(got_button_up, "expected WM_LBUTTONUP message\n"); + DestroyWindow(hwnd); + ok(ReleaseCapture(), "ReleaseCapture failed\n"); + + CloseHandle(thread_data.start_event); + CloseHandle(thread_data.end_event); + DestroyWindow(button_win); +} + START_TEST(input) { init_function_pointers(); @@ -1652,6 +1962,7 @@ test_Input_blackbox(); test_Input_whitebox(); test_Input_unicode(); + test_Input_mouse(); } else win_skip("SendInput is not available\n");
Modified: trunk/rostests/winetests/user32/menu.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/menu.c?re... ============================================================================== --- trunk/rostests/winetests/user32/menu.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/menu.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -2976,6 +2976,7 @@ MENUITEMINFOA mii = { sizeof(MENUITEMINFOA) }; BOOL ret; DWORD gle; + HBRUSH brush;
if (!pGetMenuInfo || !pSetMenuInfo) { @@ -3091,6 +3092,31 @@ ok( ret, "GetMenuInfo() should have succeeded\n"); ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle); ok( !(mi.dwStyle & MNS_NOCHECK), "menustyle was not expected to have the MNS_NOCHECK flag\n"); + + /* test background brush */ + mi.cbSize = sizeof(mi); + mi.fMask = MIM_BACKGROUND; + ret = pGetMenuInfo( hmenu, &mi ); + ok( ret, "GetMenuInfo() should have succeeded\n" ); + ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack ); + + brush = CreateSolidBrush( RGB(0xff, 0, 0) ); + mi.hbrBack = brush; + ret = pSetMenuInfo( hmenu, &mi ); + ok( ret, "SetMenuInfo() should have succeeded\n" ); + mi.hbrBack = NULL; + ret = pGetMenuInfo( hmenu, &mi ); + ok( ret, "GetMenuInfo() should have succeeded\n" ); + ok( mi.hbrBack == brush, "got %p original %p\n", mi.hbrBack, brush ); + + mi.hbrBack = NULL; + ret = pSetMenuInfo( hmenu, &mi ); + ok( ret, "SetMenuInfo() should have succeeded\n" ); + ret = pGetMenuInfo( hmenu, &mi ); + ok( ret, "GetMenuInfo() should have succeeded\n" ); + ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack ); + DeleteObject( brush ); + /* clean up */ DestroyMenu( hsubmenu); DestroyMenu( hmenu);
Modified: trunk/rostests/winetests/user32/msg.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/msg.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/msg.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/msg.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -1172,51 +1172,6 @@ { WM_NCDESTROY, sent }, { 0 } }; -/* Moving the mouse in nonclient area */ -static const struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */ - { WM_NCHITTEST, sent }, - { WM_SETCURSOR, sent }, - { WM_NCMOUSEMOVE, posted }, - { 0 } -}; -/* Moving the mouse in client area */ -static const struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */ - { WM_NCHITTEST, sent }, - { WM_SETCURSOR, sent }, - { WM_MOUSEMOVE, posted }, - { 0 } -}; -/* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */ -static const struct message WmDragTitleBarSeq[] = { /* FIXME: add */ - { WM_NCLBUTTONDOWN, sent|wparam, HTCAPTION }, - { WM_SYSCOMMAND, sent|defwinproc|wparam, SC_MOVE+2 }, - { WM_GETMINMAXINFO, sent|defwinproc }, - { WM_ENTERSIZEMOVE, sent|defwinproc }, - { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, 0 }, - { WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, 0 }, - { WM_MOVE, sent|defwinproc }, - { WM_EXITSIZEMOVE, sent|defwinproc }, - { 0 } -}; -/* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */ -static const struct message WmDragThickBordersBarSeq[] = { /* FIXME: add */ - { WM_NCLBUTTONDOWN, sent|wparam, 0xd }, - { WM_SYSCOMMAND, sent|defwinproc|wparam, 0xf004 }, - { WM_GETMINMAXINFO, sent|defwinproc }, - { WM_ENTERSIZEMOVE, sent|defwinproc }, - { WM_SIZING, sent|defwinproc|wparam, 4}, /* one for each mouse movement */ - { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, 0 }, - { WM_GETMINMAXINFO, sent|defwinproc }, - { WM_NCCALCSIZE, sent|defwinproc|wparam, 1 }, - { WM_NCPAINT, sent|defwinproc|wparam, 1 }, - { WM_GETTEXT, sent|defwinproc }, - { WM_ERASEBKGND, sent|defwinproc }, - { WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, 0 }, - { WM_MOVE, sent|defwinproc }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, - { WM_EXITSIZEMOVE, sent|defwinproc }, - { 0 } -}; /* Resizing child window with MoveWindow (32) */ static const struct message WmResizingChildWithMoveWindowSeq[] = { { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE }, @@ -1227,41 +1182,6 @@ { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, - { 0 } -}; -/* Clicking on inactive button */ -static const struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */ - { WM_NCHITTEST, sent }, - { WM_PARENTNOTIFY, sent|parent|wparam, WM_LBUTTONDOWN }, - { WM_MOUSEACTIVATE, sent }, - { WM_MOUSEACTIVATE, sent|parent|defwinproc }, - { WM_SETCURSOR, sent }, - { WM_SETCURSOR, sent|parent|defwinproc }, - { WM_LBUTTONDOWN, posted }, - { WM_KILLFOCUS, posted|parent }, - { WM_SETFOCUS, posted }, - { WM_CTLCOLORBTN, posted|parent }, - { BM_SETSTATE, posted }, - { WM_CTLCOLORBTN, posted|parent }, - { WM_LBUTTONUP, posted }, - { BM_SETSTATE, posted }, - { WM_CTLCOLORBTN, posted|parent }, - { WM_COMMAND, posted|parent }, - { 0 } -}; -/* Reparenting a button (16/32) */ -/* The last child (button) reparented gets topmost for its new parent. */ -static const struct message WmReparentButtonSeq[] = { /* FIXME: add */ - { WM_SHOWWINDOW, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE }, - { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, - { WM_ERASEBKGND, sent|parent }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE }, - { WM_CHILDACTIVATE, sent }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW }, - { WM_MOVE, sent|defwinproc }, - { WM_SHOWWINDOW, sent|wparam, 1 }, { 0 } }; /* Creation of a custom dialog (32) */ @@ -1464,35 +1384,6 @@ { WM_NCDESTROY, sent }, { 0 } }; -/* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */ -static const struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */ - /* (inside dialog proc, handling WM_INITDIALOG) */ - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_NCCALCSIZE, sent }, - { WM_NCACTIVATE, sent|parent|wparam, 0 }, - { WM_GETTEXT, sent|defwinproc }, - { WM_ACTIVATE, sent|parent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|parent }, - { WM_NCACTIVATE, sent|wparam, 1 }, - { WM_ACTIVATE, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGED, sent|wparam, 0 }, - { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, - /* (setting focus) */ - { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, - { WM_NCPAINT, sent }, - { WM_GETTEXT, sent|defwinproc }, - { WM_ERASEBKGND, sent }, - { WM_CTLCOLORDLG, sent|defwinproc }, - { WM_WINDOWPOSCHANGED, sent|wparam, 0 }, - { WM_PAINT, sent }, - /* (bunch of WM_CTLCOLOR* for each control) */ - { WM_PAINT, sent|parent }, - { WM_ENTERIDLE, sent|parent|wparam, 0 }, - { WM_SETCURSOR, sent|parent }, - { 0 } -}; /* SetMenu for NonVisible windows with size change*/ static const struct message WmSetMenuNonVisibleSizeChangeSeq[] = { { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, @@ -4542,6 +4433,11 @@ { 0 } };
+static void CALLBACK apc_test_proc(ULONG_PTR param) +{ + /* nothing */ +} + static void test_MsgWaitForMultipleObjects(HWND hwnd) { DWORD ret; @@ -4583,17 +4479,61 @@ ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message); ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n"); ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message); + + /* MWMO_INPUTAVAILABLE should succeed even if the message was already seen */ + PostMessageA( hwnd, WM_USER, 0, 0 ); + ok(PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "PeekMessage should succeed\n"); + ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message); + + ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_INPUTAVAILABLE ); + ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret); + + ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n"); + ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message); + + /* without MWMO_ALERTABLE the result is never WAIT_IO_COMPLETION */ + ret = QueueUserAPC( apc_test_proc, GetCurrentThread(), 0 ); + ok(ret, "QueueUserAPC failed %u\n", GetLastError()); + + ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, 0 ); + ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjectsEx returned %x\n", ret); + + /* but even with MWMO_ALERTABLE window events are preferred */ + PostMessageA( hwnd, WM_USER, 0, 0 ); + + ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_ALERTABLE ); + ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret); + + ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n"); + ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message); + + /* the APC call is still queued */ + ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_ALERTABLE ); + ok(ret == WAIT_IO_COMPLETION, "MsgWaitForMultipleObjectsEx returned %x\n", ret); +} + +static DWORD CALLBACK show_window_thread(LPVOID arg) +{ + HWND hwnd = arg; + + /* function will not return if ShowWindow(SW_HIDE) calls SendMessage() */ + ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n"); + + return 0; }
/* test if we receive the right sequence of messages */ static void test_messages(void) { + DWORD tid; + HANDLE hthread; HWND hwnd, hparent, hchild; HWND hchild2, hbutton; HMENU hmenu; MSG msg; LRESULT res; POINT pos; + BOOL ret;
flush_sequence();
@@ -4619,6 +4559,19 @@ ShowWindow(hwnd, SW_HIDE); flush_events(); ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", FALSE); + + /* test ShowWindow(SW_HIDE) on a hidden window - single threaded */ + ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n"); + flush_events(); + ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE); + + /* test ShowWindow(SW_HIDE) on a hidden window - multi-threaded */ + hthread = CreateThread(NULL, 0, show_window_thread, hwnd, 0, &tid); + ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError()); + ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); + CloseHandle(hthread); + flush_events(); + ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
ShowWindow(hwnd, SW_SHOW); flush_events(); @@ -4867,10 +4820,24 @@
flush_events(); flush_sequence(); - ok(DrawMenuBar(hwnd), "DrawMenuBar failed: %d\n", GetLastError()); + ret = DrawMenuBar(hwnd); + ok(ret, "DrawMenuBar failed: %d\n", GetLastError()); flush_events(); ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE); ok(SetCursorPos(pos.x, pos.y), "SetCursorPos failed\n"); + + DestroyWindow(hwnd); + + hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_CHILD|WS_VISIBLE, + 0, 0, 100, 100, hparent, 0, GetModuleHandleA(0), NULL); + ok(hwnd != 0, "Failed to create custom dialog window\n"); + flush_events(); + flush_sequence(); + ret = DrawMenuBar(hwnd); + ok(ret, "DrawMenuBar failed: %d\n", GetLastError()); + flush_events(); + ok_sequence(WmEmptySeq, "DrawMenuBar for a child window", FALSE); + DestroyWindow(hwnd);
flush_sequence(); @@ -8400,6 +8367,13 @@ count++; }
+static DWORD exception; +static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + count++; + RaiseException(exception, 0, 0, NULL); +} + static DWORD WINAPI timer_thread_proc(LPVOID x) { struct timer_info *info = x; @@ -8528,6 +8502,41 @@ count, TIMER_COUNT_EXPECTED); KillTimer(NULL, id); /* Note: SetSystemTimer doesn't support a NULL window, see test_timers */ +} + +static void test_timers_exception(DWORD code) +{ + UINT_PTR id; + MSG msg; + + exception = code; + id = SetTimer(NULL, 0, 1000, callback_exception); + ok(id != 0, "did not get id from SetTimer.\n"); + + memset(&msg, 0, sizeof(msg)); + msg.message = WM_TIMER; + msg.wParam = id; + msg.lParam = (LPARAM)callback_exception; + + count = 0; + DispatchMessageA(&msg); + ok(count == 1, "did not get one count as expected (%i).\n", count); + + KillTimer(NULL, id); +} + +static void test_timers_exceptions(void) +{ + test_timers_exception(EXCEPTION_ACCESS_VIOLATION); + test_timers_exception(EXCEPTION_DATATYPE_MISALIGNMENT); + test_timers_exception(EXCEPTION_BREAKPOINT); + test_timers_exception(EXCEPTION_SINGLE_STEP); + test_timers_exception(EXCEPTION_ARRAY_BOUNDS_EXCEEDED); + test_timers_exception(EXCEPTION_FLT_DENORMAL_OPERAND); + test_timers_exception(EXCEPTION_FLT_DIVIDE_BY_ZERO); + test_timers_exception(EXCEPTION_FLT_INEXACT_RESULT); + test_timers_exception(EXCEPTION_ILLEGAL_INSTRUCTION); + test_timers_exception(0xE000BEEF); /* customer exception */ }
/* Various win events with arbitrary parameters */ @@ -10490,6 +10499,10 @@ /* test using PostQuitMessage */ flush_events(); PostQuitMessage(0xbeef); + + msg.message = 0; + ret = PeekMessageA(&msg, 0, 0, 0, PM_QS_SENDMESSAGE); + ok(!ret, "got %x message\n", msg.message);
ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE); ok(ret, "PeekMessage failed with error %d\n", GetLastError()); @@ -13324,7 +13337,7 @@ { ResetEvent( start_event ); ResetEvent( end_event ); -#if 0 +#ifndef __REACTOS__ sprintf( path, "%s msg %u", argv0, i ); #else sprintf( path, "%s msg_queue %u", argv0, i ); @@ -13996,9 +14009,6 @@ { HCBT_SETFOCUS, hook }, /* child */ { 0 } }; -static const struct message WmSetFocus_4[] = { - { 0 } -};
static void test_SetFocus(void) { @@ -14487,7 +14497,7 @@ #undef X }
-#if 0 +#ifndef __REACTOS__ START_TEST(msg) { char **test_argv; @@ -14576,6 +14586,7 @@ test_accelerators(); test_timers(); test_timers_no_wnd(); + test_timers_exceptions(); if (hCBT_hook) test_set_hook(); test_DestroyWindow(); test_DispatchMessage(); @@ -14628,7 +14639,7 @@ } DeleteCriticalSection( &sequence_cs ); } -#endif +#endif /* __REACTOS__ */
static void init_tests() { @@ -14662,12 +14673,12 @@ UnhookWindowsHookEx(hCBT_hook); if (pUnhookWinEvent && hEvent_hook) { - ret = pUnhookWinEvent(hEvent_hook); - ok( ret, "UnhookWinEvent error %d\n", GetLastError()); - SetLastError(0xdeadbeef); - ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */ - GetLastError() == 0xdeadbeef, /* Win9x */ + ret = pUnhookWinEvent(hEvent_hook); + ok( ret, "UnhookWinEvent error %d\n", GetLastError()); + SetLastError(0xdeadbeef); + ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */ + GetLastError() == 0xdeadbeef, /* Win9x */ "unexpected error %d\n", GetLastError()); } DeleteCriticalSection( &sequence_cs ); @@ -14770,6 +14781,7 @@ init_tests(); test_timers(); test_timers_no_wnd(); + test_timers_exceptions(); cleanup_tests(); }
@@ -14790,11 +14802,11 @@ 0, GetCurrentThreadId(), WINEVENT_INCONTEXT); if (pIsWinEventHookInstalled && hEvent_hook) - { - UINT event; - for (event = EVENT_MIN; event <= EVENT_MAX; event++) - ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event); - } + { + UINT event; + for (event = EVENT_MIN; event <= EVENT_MAX; event++) + ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event); + } } if (!hEvent_hook) win_skip( "no win event hook support\n" );
Modified: trunk/rostests/winetests/user32/win.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/win.c?rev... ============================================================================== --- trunk/rostests/winetests/user32/win.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/win.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -63,6 +63,8 @@ static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn);
static BOOL test_lbuttondown_flag; +static DWORD num_gettext_msgs; +static DWORD num_settext_msgs; static HWND hwndMessage; static HWND hwndMain, hwndMain2; static HHOOK hhook; @@ -101,6 +103,22 @@ diff = time - GetTickCount(); min_timeout = 50; } +} + +static BOOL wait_for_event(HANDLE event, int timeout) +{ + DWORD end_time = GetTickCount() + timeout; + MSG msg; + + do { + if(MsgWaitForMultipleObjects(1, &event, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0) + return TRUE; + while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); + timeout = end_time - GetTickCount(); + }while(timeout > 0); + + return FALSE; }
/* check the values returned by the various parent/owner functions on a given window */ @@ -777,6 +795,12 @@ ShowWindow((HWND)wparam, SW_SHOW); flush_events( FALSE ); } + break; + case WM_GETTEXT: + num_gettext_msgs++; + break; + case WM_SETTEXT: + num_settext_msgs++; break; }
@@ -5669,23 +5693,132 @@ ok(!IsWindow(hwnd), "window should not exist\n"); }
+static DWORD CALLBACK gettext_msg_thread( LPVOID arg ) +{ + HWND hwnd = arg; + char buf[32]; + INT buf_len; + + /* test GetWindowTextA */ + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) ); + ok( buf_len != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "another_caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + return 0; +} + +static DWORD CALLBACK settext_msg_thread( LPVOID arg ) +{ + HWND hwnd = arg; + BOOL success; + + /* test SetWindowTextA */ + num_settext_msgs = 0; + success = SetWindowTextA( hwnd, "thread_caption" ); + ok( success, "SetWindowTextA failed\n" ); + ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs ); + + return 0; +} + static void test_gettext(void) { - WNDCLASSA cls; - LPCSTR clsname = "gettexttest"; + DWORD tid, num_msgs; + HANDLE thread; + BOOL success; + char buf[32]; + INT buf_len; HWND hwnd; LRESULT r; - - memset( &cls, 0, sizeof cls ); - cls.lpfnWndProc = DefWindowProcA; - cls.lpszClassName = clsname; - cls.hInstance = GetModuleHandleA(NULL); - - if (!RegisterClassA( &cls )) return; - - hwnd = CreateWindowA( clsname, "test text", WS_OVERLAPPED, 0, 0, 10, 10, 0, NULL, NULL, NULL); - ok( hwnd != NULL, "window was null\n"); - + MSG msg; + + hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0, 0, 0, 0, 0, 0, 0, NULL ); + ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() ); + + /* test GetWindowTextA */ + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) ); + ok( buf_len != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + /* test WM_GETTEXT */ + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + r = SendMessageA( hwnd, WM_GETTEXT, sizeof(buf), (LONG_PTR)buf ); + ok( r != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + /* test SetWindowTextA */ + num_settext_msgs = 0; + success = SetWindowTextA( hwnd, "new_caption" ); + ok( success, "SetWindowTextA failed\n" ); + ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs ); + + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) ); + ok( buf_len != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "new_caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + /* test WM_SETTEXT */ + num_settext_msgs = 0; + r = SendMessageA( hwnd, WM_SETTEXT, 0, (ULONG_PTR)"another_caption" ); + ok( r != 0, "WM_SETTEXT failed\n" ); + ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs ); + + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) ); + ok( buf_len != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "another_caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) + DispatchMessageA( &msg ); + + /* test interthread GetWindowTextA */ + num_msgs = 0; + thread = CreateThread( NULL, 0, gettext_msg_thread, hwnd, 0, &tid ); + ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError()); + while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0) + { + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) + DispatchMessageA( &msg ); + num_msgs++; + } + CloseHandle( thread ); + ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs ); + + /* test interthread SetWindowText */ + num_msgs = 0; + thread = CreateThread( NULL, 0, settext_msg_thread, hwnd, 0, &tid ); + ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError()); + while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0) + { + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) + DispatchMessageA( &msg ); + num_msgs++; + } + CloseHandle( thread ); + ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs ); + + num_gettext_msgs = 0; + memset( buf, 0, sizeof(buf) ); + buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) ); + ok( buf_len != 0, "expected a nonempty window text\n" ); + ok( !strcmp(buf, "thread_caption"), "got wrong window text '%s'\n", buf ); + ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + /* seems to crash on every modern Windows version */ + if (0) + { r = SendMessageA( hwnd, WM_GETTEXT, 0x10, 0x1000); ok( r == 0, "settext should return zero\n");
@@ -5697,9 +5830,9 @@
r = SendMessageA( hwnd, WM_GETTEXT, 0x1000, 0xff000000); ok( r == 0, "settext should return zero (%ld)\n", r); + }
DestroyWindow(hwnd); - UnregisterClassA( clsname, NULL ); }
@@ -6915,32 +7048,44 @@ static void test_FindWindowEx(void) { HWND hwnd, found; - CHAR title[1];
hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0,0,0,0, 0, 0, 0, NULL ); ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
- title[0] = 0; - - found = FindWindowExA( 0, 0, "MainWindowClass", title ); + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "" ); ok( found == NULL, "expected a NULL hwnd\n" ); + ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + num_gettext_msgs = 0; found = FindWindowExA( 0, 0, "MainWindowClass", NULL ); ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); + ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "caption" ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); + ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
DestroyWindow( hwnd );
hwnd = CreateWindowExA( 0, "MainWindowClass", NULL, WS_POPUP, 0,0,0,0, 0, 0, 0, NULL ); ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
- found = FindWindowExA( 0, 0, "MainWindowClass", title ); + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "" ); ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); + ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs ); + + num_gettext_msgs = 0; found = FindWindowExA( 0, 0, "MainWindowClass", NULL ); ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); + ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
DestroyWindow( hwnd );
/* test behaviour with a window title that is an empty character */ - found = FindWindowExA( 0, 0, "Shell_TrayWnd", title ); + found = FindWindowExA( 0, 0, "Shell_TrayWnd", "" ); ok( found != NULL, "found is NULL, expected a valid hwnd\n" ); found = FindWindowExA( 0, 0, "Shell_TrayWnd", NULL ); ok( found != NULL, "found is NULL, expected a valid hwnd\n" ); @@ -7200,6 +7345,167 @@ ok(ret, "UnregisterClass(my_window) failed\n"); }
+static void simulate_click(int x, int y) +{ + INPUT input[2]; + UINT events_no; + + SetCursorPos(x, y); + memset(input, 0, sizeof(input)); + input[0].type = INPUT_MOUSE; + U(input[0]).mi.dx = x; + U(input[0]).mi.dy = y; + U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + input[1].type = INPUT_MOUSE; + U(input[1]).mi.dx = x; + U(input[1]).mi.dy = y; + U(input[1]).mi.dwFlags = MOUSEEVENTF_LEFTUP; + events_no = SendInput(2, input, sizeof(input[0])); + ok(events_no == 2, "SendInput returned %d\n", events_no); +} + +static WNDPROC def_static_proc; +static BOOL got_hittest; +static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + if(msg == WM_NCHITTEST) + got_hittest = TRUE; + if(msg == WM_LBUTTONDOWN) + ok(0, "unexpected call\n"); + + return def_static_proc(hwnd, msg, wp, lp); +} + +static void window_from_point_proc(HWND parent) +{ + HANDLE start_event, end_event; + HANDLE win, child_static, child_button; + BOOL got_click; + DWORD ret; + POINT pt; + MSG msg; + + start_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_wfp_start"); + ok(start_event != 0, "OpenEvent failed\n"); + end_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_wfp_end"); + ok(end_event != 0, "OpenEvent failed\n"); + + child_static = CreateWindowExA(0, "static", "static", WS_CHILD | WS_VISIBLE, + 0, 0, 100, 100, parent, 0, NULL, NULL); + ok(child_static != 0, "CreateWindowEx failed\n"); + pt.x = pt.y = 150; + win = WindowFromPoint(pt); + ok(win == parent, "WindowFromPoint returned %p, expected %p\n", win, parent); + + child_button = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE, + 100, 0, 100, 100, parent, 0, NULL, NULL); + ok(child_button != 0, "CreateWindowEx failed\n"); + pt.x = 250; + win = WindowFromPoint(pt); + ok(win == child_button, "WindowFromPoint returned %p, expected %p\n", win, child_button); + + /* without this window simulate click test keeps sending WM_NCHITTEST + * message to child_static in an infinite loop */ + win = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE, + 0, 0, 100, 100, parent, 0, NULL, NULL); + ok(win != 0, "CreateWindowEx failed\n"); + def_static_proc = (void*)SetWindowLongPtrA(child_static, + GWLP_WNDPROC, (LONG_PTR)static_hook_proc); + flush_events(TRUE); + SetEvent(start_event); + + got_hittest = FALSE; + got_click = FALSE; + while(!got_click && wait_for_message(&msg)) { + if(msg.message == WM_LBUTTONUP) { + ok(msg.hwnd == win, "msg.hwnd = %p, expected %p\n", msg.hwnd, win); + got_click = TRUE; + } + DispatchMessageA(&msg); + } + ok(got_hittest, "transparent window didn't get WM_NCHITTEST message\n"); + ok(got_click, "button under static window didn't get WM_LBUTTONUP\n"); + + ret = WaitForSingleObject(end_event, 5000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret); + + CloseHandle(start_event); + CloseHandle(end_event); +} + +static void test_window_from_point(const char *argv0) +{ + HWND hwnd, child, win; + POINT pt; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + char cmd[MAX_PATH]; + HANDLE start_event, end_event; + + hwnd = CreateWindowExA(0, "MainWindowClass", NULL, WS_POPUP | WS_VISIBLE, + 100, 100, 200, 100, 0, 0, NULL, NULL); + ok(hwnd != 0, "CreateWindowEx failed\n"); + + pt.x = pt.y = 150; + win = WindowFromPoint(pt); + pt.x = 250; + if(win == hwnd) + win = WindowFromPoint(pt); + if(win != hwnd) { + skip("there's another window covering test window\n"); + DestroyWindow(hwnd); + return; + } + + child = CreateWindowExA(0, "static", "static", WS_CHILD | WS_VISIBLE, + 0, 0, 100, 100, hwnd, 0, NULL, NULL); + ok(child != 0, "CreateWindowEx failed\n"); + pt.x = pt.y = 150; + win = WindowFromPoint(pt); + ok(win == hwnd, "WindowFromPoint returned %p, expected %p\n", win, hwnd); + DestroyWindow(child); + + child = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE, + 0, 0, 100, 100, hwnd, 0, NULL, NULL); + ok(child != 0, "CreateWindowEx failed\n"); + win = WindowFromPoint(pt); + ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child); + DestroyWindow(child); + + start_event = CreateEventA(NULL, FALSE, FALSE, "test_wfp_start"); + ok(start_event != 0, "CreateEvent failed\n"); + end_event = CreateEventA(NULL, FALSE, FALSE, "test_wfp_end"); + ok(start_event != 0, "CreateEvent failed\n"); + + sprintf(cmd, "%s win create_children %p\n", argv0, hwnd); + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + ok(CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, + &startup, &info), "CreateProcess failed.\n"); + ok(wait_for_event(start_event, 1000), "didn't get start_event\n"); + + child = GetWindow(hwnd, GW_CHILD); + win = WindowFromPoint(pt); + ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child); + + simulate_click(150, 150); + flush_events(TRUE); + + child = GetWindow(child, GW_HWNDNEXT); + pt.x = 250; + win = WindowFromPoint(pt); + ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child); + + SetEvent(end_event); + winetest_wait_child_process(info.hProcess); + CloseHandle(start_event); + CloseHandle(end_event); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + + DestroyWindow(hwnd); +} + static void test_map_points(void) { BOOL ret; @@ -7673,8 +7979,71 @@ CloseHandle(data.thread_replied); }
+static void test_GetMessagePos(void) +{ + HWND button; + DWORD pos; + MSG msg; + + button = CreateWindowExA(0, "button", "button", WS_VISIBLE, + 100, 100, 100, 100, 0, 0, 0, NULL); + ok(button != 0, "CreateWindowExA failed\n"); + + SetCursorPos(120, 140); + flush_events(TRUE); + pos = GetMessagePos(); + ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos); + + SetCursorPos(340, 320); + pos = GetMessagePos(); + ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos); + + SendMessageW(button, WM_APP, 0, 0); + pos = GetMessagePos(); + ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos); + + PostMessageA(button, WM_APP, 0, 0); + GetMessageA(&msg, button, 0, 0); + ok(msg.message == WM_APP, "msg.message = %x\n", msg.message); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos); + + PostMessageA(button, WM_APP, 0, 0); + SetCursorPos(350, 330); + GetMessageA(&msg, button, 0, 0); + ok(msg.message == WM_APP, "msg.message = %x\n", msg.message); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos); + + PostMessageA(button, WM_APP, 0, 0); + SetCursorPos(320, 340); + PostMessageA(button, WM_APP+1, 0, 0); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos); + GetMessageA(&msg, button, 0, 0); + ok(msg.message == WM_APP, "msg.message = %x\n", msg.message); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(350, 330), "pos = %08x\n", pos); + GetMessageA(&msg, button, 0, 0); + ok(msg.message == WM_APP+1, "msg.message = %x\n", msg.message); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(320, 340), "pos = %08x\n", pos); + + SetTimer(button, 1, 250, NULL); + SetCursorPos(330, 350); + GetMessageA(&msg, button, 0, 0); + ok(msg.message == WM_TIMER, "msg.message = %x\n", msg.message); + pos = GetMessagePos(); + todo_wine ok(pos == MAKELONG(330, 350), "pos = %08x\n", pos); + KillTimer(button, 1); + + DestroyWindow(button); +} + START_TEST(win) { + char **argv; + int argc = winetest_get_mainargs( &argv ); HMODULE user32 = GetModuleHandleA( "user32.dll" ); HMODULE gdi32 = GetModuleHandleA("gdi32.dll"); pGetAncestor = (void *)GetProcAddress( user32, "GetAncestor" ); @@ -7695,6 +8064,15 @@ pSetLayout = (void *)GetProcAddress( gdi32, "SetLayout" ); pMirrorRgn = (void *)GetProcAddress( gdi32, "MirrorRgn" );
+ if (argc==4 && !strcmp(argv[2], "create_children")) + { + HWND hwnd; + + sscanf(argv[3], "%p", &hwnd); + window_from_point_proc(hwnd); + return; + } + if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window", @@ -7706,20 +8084,7 @@
if(!SetForegroundWindow(hwndMain)) { /* workaround for foreground lock timeout */ - INPUT input[2]; - UINT events_no; - - memset(input, 0, sizeof(input)); - input[0].type = INPUT_MOUSE; - U(input[0]).mi.dx = 101; - U(input[0]).mi.dy = 101; - U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTDOWN; - input[0].type = INPUT_MOUSE; - U(input[0]).mi.dx = 101; - U(input[0]).mi.dy = 101; - U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTUP; - events_no = SendInput(2, input, sizeof(input[0])); - ok(events_no == 2, "SendInput returned %d\n", events_no); + simulate_click(101, 101); ok(SetForegroundWindow(hwndMain), "SetForegroundWindow failed\n"); }
@@ -7745,6 +8110,7 @@
/* Add the tests below this line */ test_child_window_from_point(); + test_window_from_point(argv[0]); test_thick_child_size(hwndMain); test_fullscreen(); test_hwnd_message(); @@ -7792,7 +8158,7 @@ test_csparentdc(); test_SetWindowLong(); test_ShowWindow(); - if (0) test_gettext(); /* crashes on NT4 */ + test_gettext(); test_GetUpdateRect(); test_Expose(); test_layered_window(); @@ -7805,6 +8171,7 @@ test_update_region(); test_window_without_child_style(); test_smresult(); + test_GetMessagePos();
/* add the tests above this line */ if (hhook) UnhookWindowsHookEx(hhook);
Modified: trunk/rostests/winetests/user32/winstation.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/winstatio... ============================================================================== --- trunk/rostests/winetests/user32/winstation.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/winstation.c [iso-8859-1] Thu Feb 26 09:05:15 2015 @@ -932,7 +932,7 @@ GetProcessWindowStation(); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { - skip("WindowStation calls not supported on this platform\n"); + win_skip("WindowStation calls not supported on this platform\n"); return; }