Author: akhaldi Date: Sat Oct 5 10:20:53 2013 New Revision: 60530
URL: http://svn.reactos.org/svn/reactos?rev=60530&view=rev Log: [USER32_WINETEST] * Sync with Wine 1.7.1. CORE-7469
Modified: trunk/rostests/winetests/user32/CMakeLists.txt trunk/rostests/winetests/user32/class.c trunk/rostests/winetests/user32/clipboard.c trunk/rostests/winetests/user32/dce.c trunk/rostests/winetests/user32/dde.c trunk/rostests/winetests/user32/menu.c trunk/rostests/winetests/user32/msg.c trunk/rostests/winetests/user32/testlist.c trunk/rostests/winetests/user32/win.c
Modified: trunk/rostests/winetests/user32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/CMakeList... ============================================================================== --- trunk/rostests/winetests/user32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/CMakeLists.txt [iso-8859-1] Sat Oct 5 10:20:53 2013 @@ -1,6 +1,3 @@ - -add_definitions( - -D__ROS_LONG64__)
list(APPEND SOURCE broadcast.c @@ -29,13 +26,9 @@ wsprintf.c testlist.c)
-add_executable(user32_winetest - ${SOURCE} - resource.rc) - -target_link_libraries(user32_winetest wine) +add_executable(user32_winetest ${SOURCE} resource.rc) set_module_type(user32_winetest win32cui) -add_importlibs(user32_winetest user32 gdi32 advapi32 msvcrt kernel32 ntdll) +add_importlibs(user32_winetest user32 gdi32 advapi32 msvcrt kernel32) add_cd_file(TARGET user32_winetest DESTINATION reactos/bin FOR all)
if(NOT MSVC)
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] Sat Oct 5 10:20:53 2013 @@ -977,6 +977,58 @@ ok(wcx.lpfnWndProc != NULL, "got null proc\n"); }
+static void test_icons(void) +{ + WNDCLASSEXW wcex, ret_wcex; + WCHAR cls_name[] = {'I','c','o','n','T','e','s','t','C','l','a','s','s',0}; + HWND hwnd; + HINSTANCE hinst = GetModuleHandleW(0); + HICON hsmicon, hsmallnew; + ICONINFO icinf; + + memset(&wcex, 0, sizeof wcex); + wcex.cbSize = sizeof wcex; + wcex.lpfnWndProc = ClassTest_WndProc; + wcex.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION); + wcex.hInstance = hinst; + wcex.lpszClassName = cls_name; + ok(RegisterClassExW(&wcex), "RegisterClassExW returned 0\n"); + hwnd = CreateWindowExW(0, cls_name, NULL, WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, NULL, NULL, hinst, 0); + ok(hwnd != NULL, "Window was not created\n"); + + ok(GetClassInfoExW(hinst, cls_name, &ret_wcex), "Class info was not retrieved\n"); + ok(wcex.hIcon == ret_wcex.hIcon, "Icons don't match\n"); + ok(ret_wcex.hIconSm != NULL, "hIconSm should be non-zero handle\n"); + + hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM); + ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n"); + + hsmallnew = CopyImage(wcex.hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), 0); + ok(!SetClassLongPtrW(hwnd, GCLP_HICONSM, (LONG_PTR)hsmallnew), + "Previous hIconSm should be zero\n"); + ok(hsmallnew == (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM), + "Should return explicitly assigned small icon\n"); + ok(!GetIconInfo(hsmicon, &icinf), "Previous small icon should be destroyed\n"); + + SetClassLongPtrW(hwnd, GCLP_HICONSM, 0); + hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM); + ok( hsmicon != NULL, "GetClassLong should return non-zero handle\n"); + + SetClassLongPtrW(hwnd, GCLP_HICON, 0); + ok(!GetClassLongPtrW(hwnd, GCLP_HICONSM), "GetClassLong should return zero handle\n"); + + SetClassLongPtrW(hwnd, GCLP_HICON, (LONG_PTR)LoadIconW(NULL, (LPCWSTR)IDI_QUESTION)); + hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM); + ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n"); + UnregisterClassW(cls_name, hinst); + ok(GetIconInfo(hsmicon, &icinf), "Icon should NOT be destroyed\n"); + + DestroyIcon(hsmallnew); + DestroyWindow(hwnd); +} + START_TEST(class) { HANDLE hInstance = GetModuleHandleA( NULL ); @@ -995,6 +1047,7 @@ CreateDialogParamTest(hInstance); test_styles(); test_builtinproc(); + test_icons();
/* this test unregisters the Button class so it should be executed at the end */ test_instances();
Modified: trunk/rostests/winetests/user32/clipboard.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/clipboard... ============================================================================== --- trunk/rostests/winetests/user32/clipboard.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/clipboard.c [iso-8859-1] Sat Oct 5 10:20:53 2013 @@ -269,6 +269,83 @@ ok(r, "gle %d\n", GetLastError()); }
+static CRITICAL_SECTION clipboard_cs; +static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + switch(msg) { + case WM_DRAWCLIPBOARD: + EnterCriticalSection(&clipboard_cs); + LeaveCriticalSection(&clipboard_cs); + break; + case WM_USER: + PostQuitMessage(0); + break; + } + + return DefWindowProc(hwnd, msg, wp, lp); +} + +static DWORD WINAPI clipboard_thread(void *param) +{ + HWND win = param; + BOOL r; + + EnterCriticalSection(&clipboard_cs); + SetLastError(0xdeadbeef); + SetClipboardViewer(win); + ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError()); + LeaveCriticalSection(&clipboard_cs); + + r = OpenClipboard(win); + ok(r, "OpenClipboard failed: %d\n", GetLastError()); + + r = EmptyClipboard(); + ok(r, "EmptyClipboard failed: %d\n", GetLastError()); + + EnterCriticalSection(&clipboard_cs); + r = CloseClipboard(); + ok(r, "CloseClipboard failed: %d\n", GetLastError()); + LeaveCriticalSection(&clipboard_cs); + + r = PostMessage(win, WM_USER, 0, 0); + ok(r, "PostMessage failed: %d\n", GetLastError()); + return 0; +} + +static void test_messages(void) +{ + WNDCLASS cls; + HWND win; + MSG msg; + HANDLE thread; + DWORD tid; + + InitializeCriticalSection(&clipboard_cs); + + memset(&cls, 0, sizeof(cls)); + cls.lpfnWndProc = clipboard_wnd_proc; + cls.hInstance = GetModuleHandle(0); + cls.lpszClassName = "clipboard_test"; + RegisterClass(&cls); + + win = CreateWindow("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0); + ok(win != NULL, "CreateWindow failed: %d\n", GetLastError()); + + thread = CreateThread(NULL, 0, clipboard_thread, (void*)win, 0, &tid); + ok(thread != NULL, "CreateThread failed: %d\n", GetLastError()); + + while(GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); + CloseHandle(thread); + + UnregisterClass("clipboard_test", GetModuleHandle(0)); + DeleteCriticalSection(&clipboard_cs); +} + START_TEST(clipboard) { SetLastError(0xdeadbeef); @@ -278,4 +355,5 @@ test_RegisterClipboardFormatA(); test_ClipboardOwner(); test_synthesized(); -} + test_messages(); +}
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] Sat Oct 5 10:20:53 2013 @@ -78,7 +78,7 @@ old_hdc = hdcs[0]; SetROP2( old_hdc, R2_WHITE ); } - while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] ); + while (i > 0) ReleaseDC( hwnd_cache, hdcs[--i] );
for (i = 0; i < 20; i++) { @@ -91,7 +91,7 @@ else ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc ); } - while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] ); + while (i > 0) ReleaseDC( hwnd_cache, hdcs[--i] );
for (i = 0; i < 20; i++) { @@ -107,7 +107,7 @@ else ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc ); } - while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] ); + while (i > 0) ReleaseDC( hwnd_cache, hdcs[--i] );
/* test own DC */
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] Sat Oct 5 10:20:53 2013 @@ -143,7 +143,7 @@ else lstrcpyA(str, "requested data\r\n");
- size = sizeof(DDEDATA) + lstrlenA(str) + 1; + size = FIELD_OFFSET(DDEDATA, Value[lstrlenA(str) + 1]); hglobal = GlobalAlloc(GMEM_MOVEABLE, size); ok(hglobal != NULL, "Expected non-NULL hglobal\n");
@@ -314,8 +314,7 @@ { str = (LPSTR)DdeAccessData(hdata, &size); ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\r\n', got %s\n", str); - ok(size == 19 || broken(size == 28), /* sizes are rounded up on win9x */ - "Expected 19, got %d\n", size); + ok(size == 17, "Expected 17, got %d\n", size);
ret = DdeUnaccessData(hdata); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); @@ -336,8 +335,7 @@ { str = (LPSTR)DdeAccessData(hdata, &size); ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\r\n', got %s\n", str); - ok(size == 19 || broken(size == 28), /* sizes are rounded up on win9x */ - "Expected 19, got %d\n", size); + ok(size == 17, "Expected 17, got %d\n", size);
ret = DdeUnaccessData(hdata); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); @@ -357,8 +355,7 @@ { str = (LPSTR)DdeAccessData(hdata, &size); ok(!lstrcmpA(str, "requested data\r\n"), "Expected 'requested data\r\n', got %s\n", str); - ok(size == 19 || broken(size == 28), /* sizes are rounded up on win9x */ - "Expected 19, got %d\n", size); + ok(size == 17, "Expected 17, got %d\n", size);
ret = DdeUnaccessData(hdata); ok(ret == TRUE, "Expected TRUE, got %d\n", ret); @@ -483,8 +480,7 @@ { str = (LPSTR)DdeAccessData(hdata, &size); ok(!lstrcmpA(str, "command executed\r\n"), "Expected 'command executed\r\n', got %s\n", str); - ok(size == 21 || broken(size == 28), /* sizes are rounded up on win9x */ - "Expected 21, got %d\n", size); + ok(size == 19, "Expected 19, got %d\n", size);
ret = DdeUnaccessData(hdata); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
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] Sat Oct 5 10:20:53 2013 @@ -3266,7 +3266,8 @@ { DWORD ret; HWND hwnd, hwndchild; - HMENU menu; + HMENU menu, menubar; + MSG msg; if( !pEndMenu) { /* win95 */ win_skip( "EndMenu is not available\n"); return; @@ -3287,7 +3288,8 @@ ret = AppendMenuA( menu, MF_STRING, 1, "winetest"); ok( ret, "Functie failed lasterror is %u\n", GetLastError()); /* seems to be needed only on wine :( */ - {MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);} + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessage(&msg); /* test the effect of sending a WM_CANCELMODE message in the WM_INITMENULOOP * handler of the menu owner */ /* test results is extracted from variable g_got_enteridle. Possible values: @@ -3314,7 +3316,27 @@ g_hwndtosend = hwnd; TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL); ok( g_got_enteridle == 2, "received %d WM_ENTERIDLE messages, should be 2\n", g_got_enteridle); + + /* test canceling tracking in a window's menu bar */ + menubar = CreateMenu(); + ok( menubar != NULL, "CreateMenu failed with error %d\n", GetLastError()); + ret = AppendMenuA( menubar, MF_POPUP|MF_STRING, (UINT_PTR)menu, "winetest"); + ok( ret, "AppendMenuA failed lasterror is %u\n", GetLastError()); + ret = SetMenu( hwnd, menubar ); + ok( ret, "SetMenu failed lasterror is %u\n", GetLastError()); + /* initiate tracking */ + g_hwndtosend = hwnd; + ret = SendMessage( hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0 ); + ok( ret == 0, "Sending WM_SYSCOMMAND/SC_KEYMENU failed lasterror is %u\n", GetLastError()); + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessage(&msg); + todo_wine { + ok(g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle); + } + ok(g_got_enteridle < 2, "received %d WM_ENTERIDLE messages, should be less than 2\n", g_got_enteridle); + /* cleanup */ + DestroyMenu( menubar ); DestroyMenu( menu); DestroyWindow( hwndchild); DestroyWindow( hwnd);
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] Sat Oct 5 10:20:53 2013 @@ -1722,6 +1722,8 @@ static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO); static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD); static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD); +static UINT_PTR (WINAPI *pSetSystemTimer)(HWND, UINT_PTR, UINT, TIMERPROC); +static UINT_PTR (WINAPI *pKillSystemTimer)(HWND, UINT_PTR); /* kernel32 functions */ static BOOL (WINAPI *pGetCPInfoExA)(UINT, DWORD, LPCPINFOEXA);
@@ -1746,6 +1748,8 @@ GET_PROC(user32, GetMonitorInfoA) GET_PROC(user32, MonitorFromPoint) GET_PROC(user32, UpdateLayeredWindow) + GET_PROC(user32, SetSystemTimer) + GET_PROC(user32, KillSystemTimer)
GET_PROC(kernel32, GetCPInfoExA)
@@ -8156,7 +8160,15 @@ { }
-#define TIMER_ID 0x19 +#define TIMER_ID 0x19 +#define TIMER_COUNT_EXPECTED 64 +#define TIMER_COUNT_TOLERANCE 9 + +static int count = 0; +static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + count++; +}
static DWORD WINAPI timer_thread_proc(LPVOID x) { @@ -8176,7 +8188,9 @@ static void test_timers(void) { struct timer_info info; + DWORD start; DWORD id; + MSG msg;
info.hWnd = CreateWindow ("TestWindowClass", NULL, WS_OVERLAPPEDWINDOW , @@ -8198,23 +8212,53 @@
ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n");
+ /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms, + * but testing indicates that the minimum timeout is actually about 15.6 ms. Since there is + * some measurement error between test runs we're allowing for ±8 counts (~2 ms). + */ + count = 0; + id = SetTimer(info.hWnd, TIMER_ID, 0, callback_count); + ok(id != 0, "did not get id from SetTimer.\n"); + ok(id==TIMER_ID, "SetTimer timer ID different\n"); + start = GetTickCount(); + while (GetTickCount()-start < 1001 && GetMessage(&msg, info.hWnd, 0, 0)) + DispatchMessage(&msg); + ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE + || broken(abs(count-43) < TIMER_COUNT_TOLERANCE) /* w2k3 */, + "did not get expected count for minimum timeout (%d != ~%d).\n", + count, TIMER_COUNT_EXPECTED); + ok(KillTimer(info.hWnd, id), "KillTimer failed\n"); + /* Perform the same check on SetSystemTimer (only available on w2k3 and older) */ + if (pSetSystemTimer) + { + int syscount = 0; + + count = 0; + id = pSetSystemTimer(info.hWnd, TIMER_ID, 0, callback_count); + ok(id != 0, "did not get id from SetSystemTimer.\n"); + ok(id==TIMER_ID, "SetTimer timer ID different\n"); + start = GetTickCount(); + while (GetTickCount()-start < 1001 && GetMessage(&msg, info.hWnd, 0, 0)) + { + if (msg.message == WM_SYSTIMER) + syscount++; + DispatchMessage(&msg); + } + ok(abs(syscount-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE, + "did not get expected count for minimum timeout (%d != ~%d).\n", + syscount, TIMER_COUNT_EXPECTED); + todo_wine ok(count == 0, "did not get expected count for callback timeout (%d != 0).\n", + count); + ok(pKillSystemTimer(info.hWnd, id), "KillSystemTimer failed\n"); + } + ok(DestroyWindow(info.hWnd), "failed to destroy window\n"); }
-static int count = 0; -static VOID CALLBACK callback_count( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime -) -{ - count++; -} - static void test_timers_no_wnd(void) { UINT_PTR id, id2; + DWORD start; MSG msg;
count = 0; @@ -8232,6 +8276,22 @@ Sleep(250); while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg); ok(count == 1, "killing replaced timer did not work (%i).\n", count); + + /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms, + * but testing indicates that the minimum timeout is actually about 15.6 ms. Since there is + * some measurement error between test runs we're allowing for ±8 counts (~2 ms). + */ + count = 0; + id = SetTimer(NULL, 0, 0, callback_count); + ok(id != 0, "did not get id from SetTimer.\n"); + start = GetTickCount(); + while (GetTickCount()-start < 1001 && GetMessage(&msg, NULL, 0, 0)) + DispatchMessage(&msg); + ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE, + "did not get expected count for minimum timeout (%d != ~%d).\n", + count, TIMER_COUNT_EXPECTED); + KillTimer(NULL, id); + /* Note: SetSystemTimer doesn't support a NULL window, see test_timers */ }
/* Various win events with arbitrary parameters */ @@ -9089,6 +9149,26 @@ DeleteObject( hrgn ); GetClientRect( hwnd, &rect ); ValidateRect( hwnd, &rect ); /* this will stop WM_PAINTs */ + ok( !count, "Got multiple WM_PAINTs\n" ); + if (++count > 10) break; + } + } + + flush_sequence(); + RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE|RDW_ERASE|RDW_FRAME ); + count = 0; + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + { + if (msg.message != WM_PAINT) DispatchMessage( &msg ); + else + { + HDC hdc; + + flush_sequence(); + hdc = BeginPaint( hwnd, NULL ); + ok( !hdc, "got valid hdc %p from BeginPaint\n", hdc ); + ok( !EndPaint( hwnd, NULL ), "EndPaint succeeded\n" ); + ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE ); ok( !count, "Got multiple WM_PAINTs\n" ); if (++count > 10) break; } @@ -11818,6 +11898,93 @@
DestroyWindow(hwnd); DestroyWindow(hwnd2); +} + +static void test_unicode_wm_char(void) +{ + HWND hwnd; + MSG msg; + struct message seq[2]; + HKL hkl_orig, hkl_greek; + DWORD cp; + LCID thread_locale; + + hkl_orig = GetKeyboardLayout( 0 ); + GetLocaleInfoW( LOWORD( hkl_orig ), LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, (WCHAR*)&cp, sizeof(cp) / sizeof(WCHAR) ); + if (cp != 1252) + { + skip( "Default codepage %d\n", cp ); + return; + } + + hkl_greek = LoadKeyboardLayout( "00000408", 0 ); + if (!hkl_greek || hkl_greek == hkl_orig /* win2k */) + { + skip( "Unable to load Greek keyboard layout\n" ); + return; + } + + hwnd = CreateWindowExW( 0, testWindowClassW, NULL, WS_OVERLAPPEDWINDOW, + 100, 100, 200, 200, 0, 0, 0, NULL ); + flush_sequence(); + + PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 ); + + ok( GetMessageW( &msg, hwnd, 0, 0 ), "no message\n" ); + ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); + ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); + ok( msg.wParam == 0x3b1, "bad wparam %lx\n", msg.wParam ); + ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam ); + + DispatchMessageW( &msg ); + + memset( seq, 0, sizeof(seq) ); + seq[0].message = WM_CHAR; + seq[0].flags = sent|wparam; + seq[0].wParam = 0x3b1; + + ok_sequence( seq, "unicode WM_CHAR", FALSE ); + + flush_sequence(); + + /* greek alpha -> 'a' in cp1252 */ + PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 ); + + ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" ); + ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); + ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); + ok( msg.wParam == 0x61, "bad wparam %lx\n", msg.wParam ); + ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam ); + + DispatchMessageA( &msg ); + + seq[0].wParam = 0x61; + ok_sequence( seq, "unicode WM_CHAR", FALSE ); + + thread_locale = GetThreadLocale(); + ActivateKeyboardLayout( hkl_greek, 0 ); + ok( GetThreadLocale() == thread_locale, "locale changed from %08x to %08x\n", + thread_locale, GetThreadLocale() ); + + flush_sequence(); + + /* greek alpha -> 0xe1 in cp1253 */ + PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 ); + + ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" ); + ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); + ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); + ok( msg.wParam == 0xe1, "bad wparam %lx\n", msg.wParam ); + ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam ); + + DispatchMessageA( &msg ); + + seq[0].wParam = 0x3b1; + ok_sequence( seq, "unicode WM_CHAR", FALSE ); + + DestroyWindow( hwnd ); + ActivateKeyboardLayout( hkl_orig, 0 ); + UnloadKeyboardLayout( hkl_greek ); }
#define ID_LISTBOX 0x000f @@ -14044,6 +14211,7 @@ test_EndDialog(); test_nullCallback(); test_dbcs_wm_char(); + test_unicode_wm_char(); test_menu_messages(); test_paintingloop(); test_defwinproc();
Modified: trunk/rostests/winetests/user32/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/user32/testlist.... ============================================================================== --- trunk/rostests/winetests/user32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/winetests/user32/testlist.c [iso-8859-1] Sat Oct 5 10:20:53 2013 @@ -1,10 +1,7 @@ /* Automatically generated file; DO NOT EDIT!! */
-#define WIN32_LEAN_AND_MEAN -#include <windows.h> - #define STANDALONE -#include "wine/test.h" +#include <wine/test.h>
extern void func_broadcast(void); extern void func_class(void);
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] Sat Oct 5 10:20:53 2013 @@ -1507,6 +1507,71 @@ DestroyWindow(mdi_child); }
+static void test_MDI_child_stack(HWND mdi_client) +{ + HWND child_1, child_2, child_3, child_4; + HWND stack[4]; + MDICREATESTRUCTA cs; + + cs.szClass = "MDI_child_Class_1"; + cs.szTitle = "MDI child"; + cs.hOwner = GetModuleHandleA(0); + cs.x = CW_USEDEFAULT; + cs.y = CW_USEDEFAULT; + cs.cx = CW_USEDEFAULT; + cs.cy = CW_USEDEFAULT; + cs.style = 0; + cs.lParam = (LPARAM)mdi_lParam_test_message; + + child_1 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs); + ok(child_1 != 0, "expected child_1 to be non NULL\n"); + child_2 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs); + ok(child_2 != 0, "expected child_2 to be non NULL\n"); + child_3 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs); + ok(child_3 != 0, "expected child_3 to be non NULL\n"); + child_4 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs); + ok(child_4 != 0, "expected child_4 to be non NULL\n"); + + stack[0] = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, 0); + stack[1] = GetWindow(stack[0], GW_HWNDNEXT); + stack[2] = GetWindow(stack[1], GW_HWNDNEXT); + stack[3] = GetWindow(stack[2], GW_HWNDNEXT); + trace("Initial MDI child stack: %p->%p->%p->%p\n", stack[0], stack[1], stack[2], stack[3]); + ok(stack[0] == child_4 && stack[1] == child_3 && + stack[2] == child_2 && stack[3] == child_1, + "Unexpected initial order, should be: %p->%p->%p->%p\n", + child_4, child_3, child_2, child_1); + + trace("Activate child next to %p\n", child_3); + SendMessage(mdi_client, WM_MDINEXT, (WPARAM)child_3, 0); + + stack[0] = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, 0); + stack[1] = GetWindow(stack[0], GW_HWNDNEXT); + stack[2] = GetWindow(stack[1], GW_HWNDNEXT); + stack[3] = GetWindow(stack[2], GW_HWNDNEXT); + ok(stack[0] == child_2 && stack[1] == child_4 && + stack[2] == child_1 && stack[3] == child_3, + "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n", + child_2, child_4, child_1, child_3, stack[0], stack[1], stack[2], stack[3]); + + trace("Activate child previous to %p\n", child_1); + SendMessage(mdi_client, WM_MDINEXT, (WPARAM)child_1, 1); + + stack[0] = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, 0); + stack[1] = GetWindow(stack[0], GW_HWNDNEXT); + stack[2] = GetWindow(stack[1], GW_HWNDNEXT); + stack[3] = GetWindow(stack[2], GW_HWNDNEXT); + ok(stack[0] == child_4 && stack[1] == child_2 && + stack[2] == child_1 && stack[3] == child_3, + "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n", + child_4, child_2, child_1, child_3, stack[0], stack[1], stack[2], stack[3]); + + DestroyWindow(child_1); + DestroyWindow(child_2); + DestroyWindow(child_3); + DestroyWindow(child_4); +} + /********************************************************************** * MDI_ChildGetMinMaxInfo (copied from windows/mdi.c) * @@ -1787,6 +1852,17 @@ &client_cs); assert(mdi_client); test_MDI_create(hwnd, mdi_client, client_cs.idFirstChild); + DestroyWindow(mdi_client); + + /* Test child window stack management */ + mdi_client = CreateWindowExA(0, "mdiclient", + NULL, + WS_CHILD, + 0, 0, rc.right, rc.bottom, + hwnd, 0, GetModuleHandle(0), + &client_cs); + assert(mdi_client); + test_MDI_child_stack(mdi_client); DestroyWindow(mdi_client); break; } @@ -2637,7 +2713,7 @@ SetActiveWindow(0); check_wnd_state(0, 0, 0, 0);
- trace("testing SetActiveWindow %p\n", hwnd); + /*trace("testing SetActiveWindow %p\n", hwnd);*/
ShowWindow(hwnd, SW_SHOW); check_wnd_state(hwnd, hwnd, hwnd, 0); @@ -2657,11 +2733,11 @@
SetWindowPos(hwnd,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW); check_wnd_state(hwnd, hwnd, hwnd, 0); - trace("testing ShowWindow SW_HIDE window %p\n", hwnd); + ShowWindow(hwnd, SW_HIDE); check_wnd_state(0, 0, 0, 0);
- trace("testing SetActiveWindow on an invisible window %p\n", hwnd); + /*trace("testing SetActiveWindow on an invisible window %p\n", hwnd);*/ SetActiveWindow(hwnd); check_wnd_state(hwnd, hwnd, hwnd, 0);
@@ -7326,6 +7402,73 @@ DestroyWindow(wnd0); }
+static void test_update_region(void) +{ + HWND hwnd, parent, child; + HRGN rgn1, rgn2; + const RECT rc = {15, 15, 40, 40}; + const POINT wnd_orig = {30, 20}; + const POINT child_orig = {10, 5}; + + parent = CreateWindowExA(0, "MainWindowClass", NULL, + WS_VISIBLE | WS_CLIPCHILDREN, + 0, 0, 300, 150, NULL, NULL, GetModuleHandleA(0), 0); + hwnd = CreateWindowExA(0, "MainWindowClass", NULL, + WS_VISIBLE | WS_CLIPCHILDREN | WS_CHILD, + 0, 0, 200, 100, parent, NULL, GetModuleHandleA(0), 0); + child = CreateWindowExA(0, "MainWindowClass", NULL, + WS_VISIBLE | WS_CHILD, + child_orig.x, child_orig.y, 100, 50, + hwnd, NULL, GetModuleHandleA(0), 0); + assert(parent && hwnd && child); + + ValidateRgn(parent, NULL); + ValidateRgn(hwnd, NULL); + InvalidateRect(hwnd, &rc, FALSE); + ValidateRgn(child, NULL); + + rgn1 = CreateRectRgn(0, 0, 0, 0); + ok(GetUpdateRgn(parent, rgn1, FALSE) == NULLREGION, + "has invalid area after ValidateRgn(NULL)\n"); + GetUpdateRgn(hwnd, rgn1, FALSE); + rgn2 = CreateRectRgnIndirect(&rc); + ok(EqualRgn(rgn1, rgn2), "assigned and retrieved update regions are different\n"); + ok(GetUpdateRgn(child, rgn2, FALSE) == NULLREGION, + "has invalid area after ValidateRgn(NULL)\n"); + + SetWindowPos(hwnd, 0, wnd_orig.x, wnd_orig.y, 0, 0, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE); + + /* parent now has non-simple update region, it consist of + * two rects, that was exposed after hwnd moving ... */ + SetRectRgn(rgn1, 0, 0, 200, wnd_orig.y); + SetRectRgn(rgn2, 0, 0, wnd_orig.x, 100); + CombineRgn(rgn1, rgn1, rgn2, RGN_OR); + /* ... and mapped hwnd's invalid area, that hwnd has before moving */ + SetRectRgn(rgn2, rc.left + wnd_orig.x, rc.top + wnd_orig.y, + rc.right + wnd_orig.x, rc.bottom + wnd_orig.y); + CombineRgn(rgn1, rgn1, rgn2, RGN_OR); + GetUpdateRgn(parent, rgn2, FALSE); +todo_wine + ok(EqualRgn(rgn1, rgn2), "wrong update region\n"); + + /* hwnd has the same invalid region as before moving */ + SetRectRgn(rgn1, rc.left, rc.top, rc.right, rc.bottom); + GetUpdateRgn(hwnd, rgn2, FALSE); + ok(EqualRgn(rgn1, rgn2), "wrong update region\n"); + + /* hwnd's invalid area maps to child during moving */ + SetRectRgn(rgn1, rc.left - child_orig.x , rc.top - child_orig.y, + rc.right - child_orig.x, rc.bottom - child_orig.y); + GetUpdateRgn(child, rgn2, FALSE); +todo_wine + ok(EqualRgn(rgn1, rgn2), "wrong update region\n"); + + DeleteObject(rgn1); + DeleteObject(rgn2); + DestroyWindow(parent); +} + START_TEST(win) { HMODULE user32 = GetModuleHandleA( "user32.dll" ); @@ -7438,6 +7581,7 @@ test_handles( hwndMain ); test_winregion(); test_map_points(); + test_update_region();
/* add the tests above this line */ if (hhook) UnhookWindowsHookEx(hhook);