[USER32_WINETEST] Sync with Wine Staging 1.7.43.
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 8 Jun 2015 10:56:37 +0000 (10:56 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 8 Jun 2015 10:56:37 +0000 (10:56 +0000)
svn path=/trunk/; revision=68067

rostests/winetests/user32/class.c
rostests/winetests/user32/clipboard.c
rostests/winetests/user32/input.c
rostests/winetests/user32/msg.c
rostests/winetests/user32/static.c
rostests/winetests/user32/win.c
rostests/winetests/user32/winstation.c

index 124af20..1f689a3 100755 (executable)
@@ -1002,6 +1002,13 @@ static void test_icons(void)
     hsmicon = (HICON)GetClassLongPtrW(hwnd, GCLP_HICONSM);
     ok(hsmicon != NULL, "GetClassLong should return non-zero handle\n");
 
+    ok(SendMessageA(hwnd, WM_GETICON, ICON_BIG, 0) == 0,
+                    "WM_GETICON with ICON_BIG should not return the class icon\n");
+    ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL, 0) == 0,
+                    "WM_GETICON with ICON_SMALL should not return the class icon\n");
+    ok(SendMessageA(hwnd, WM_GETICON, ICON_SMALL2, 0) == 0,
+                    "WM_GETICON with ICON_SMALL2 should not return the class icon\n");
+
     hsmallnew = CopyImage(wcex.hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
                                                 GetSystemMetrics(SM_CYSMICON), 0);
     ok(!SetClassLongPtrW(hwnd, GCLP_HICONSM, (LONG_PTR)hsmallnew),
index 40218be..b4a1a68 100755 (executable)
@@ -35,9 +35,18 @@ static BOOL is_win9x = FALSE;
                 expected_error, GetLastError()); \
     } while (0)
 
+static DWORD WINAPI open_clipboard_thread(LPVOID arg)
+{
+    HWND hWnd = arg;
+    ok(OpenClipboard(hWnd), "OpenClipboard second time in the same hwnd failed\n");
+    return 0;
+}
+
 static void test_ClipboardOwner(void)
 {
+    HANDLE thread;
     HWND hWnd1, hWnd2;
+    DWORD dwret;
     BOOL ret;
 
     SetLastError(0xdeadbeef);
@@ -66,7 +75,12 @@ static void test_ClipboardOwner(void)
     ok( ret, "CloseClipboard error %d\n", GetLastError());
 
     ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
-    todo_wine ok(OpenClipboard(hWnd1), "OpenClipboard second time in the same hwnd failed\n");
+    thread = CreateThread(NULL, 0, open_clipboard_thread, hWnd1, 0, NULL);
+    ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
+    dwret = WaitForSingleObject(thread, 1000);
+    ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", dwret);
+    CloseHandle(thread);
+    ok(OpenClipboard(hWnd1), "OpenClipboard second time in the same hwnd failed\n");
 
     SetLastError(0xdeadbeef);
     ret = OpenClipboard(hWnd2);
@@ -150,8 +164,8 @@ todo_wine
 
         if (format_id < 0xc000)
             ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf);
-        else
-            if (len) trace("%04x: %s\n", format_id, len ? buf : "");
+        else if (len && winetest_debug > 1)
+            trace("%04x: %s\n", format_id, len ? buf : "");
     }
 
     ret = OpenClipboard(0);
index be9b3d0..5f8d68c 100755 (executable)
@@ -1542,7 +1542,7 @@ static void test_ToUnicode(void)
 {
     WCHAR wStr[4];
     BYTE state[256];
-    const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f;
+    const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f, SC_A = 0x1e;
     const BYTE HIGHEST_BIT = 0x80;
     int i, ret;
     for(i=0; i<256; i++)
@@ -1564,9 +1564,13 @@ static void test_ToUnicode(void)
         ok(wStr[1]==0 || broken(wStr[1]!=0) /* nt4 */,
            "ToUnicode didn't null-terminate the buffer when there was room.\n");
     }
+
+    ret = ToUnicode('A', SC_A, state, wStr, 4, 0);
+    ok(ret == 1, "ToUnicode for character A didn't return 1 (was %i)\n", ret);
+    ok(wStr[0] == 'a', "ToUnicode for character 'A' was %i (expected %i)\n", wStr[0], 'a');
+
     state[VK_CONTROL] |= HIGHEST_BIT;
     state[VK_LCONTROL] |= HIGHEST_BIT;
-
     ret = ToUnicode(VK_TAB, SC_TAB, state, wStr, 2, 0);
     ok(ret == 0, "ToUnicode for CTRL + Tab didn't return 0 (was %i)\n", ret);
 
@@ -1575,12 +1579,76 @@ static void test_ToUnicode(void)
     if(ret == 1)
         ok(wStr[0]=='\n', "ToUnicode for CTRL + Return was %i (expected 10)\n", wStr[0]);
 
+    ret = ToUnicode('A', SC_A, state, wStr, 4, 0);
+    ok(ret == 1, "ToUnicode for CTRL + character A didn't return 1 (was %i)\n", ret);
+    ok(wStr[0] == 1, "ToUnicode for CTRL + character 'A' was %i (expected 1)\n", wStr[0]);
+
     state[VK_SHIFT] |= HIGHEST_BIT;
     state[VK_LSHIFT] |= HIGHEST_BIT;
     ret = ToUnicode(VK_TAB, SC_TAB, state, wStr, 2, 0);
     ok(ret == 0, "ToUnicode for CTRL + SHIFT + Tab didn't return 0 (was %i)\n", ret);
     ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0);
     todo_wine ok(ret == 0, "ToUnicode for CTRL + SHIFT + Return didn't return 0 (was %i)\n", ret);
+
+    ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0);
+    ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToUnicode(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0);
+    ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToUnicode('A', SC_A, NULL, wStr, 4, 0);
+    ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToUnicodeEx(VK_TAB, SC_TAB, NULL, wStr, 4, 0, GetKeyboardLayout(0));
+    ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToUnicodeEx(VK_RETURN, SC_RETURN, NULL, wStr, 4, 0, GetKeyboardLayout(0));
+    ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToUnicodeEx('A', SC_A, NULL, wStr, 4, 0, GetKeyboardLayout(0));
+    ok(ret == 0, "ToUnicodeEx with NULL keystate didn't return 0 (was %i)\n", ret);
+}
+
+static void test_ToAscii(void)
+{
+    WORD character;
+    BYTE state[256];
+    const BYTE SC_RETURN = 0x1c, SC_A = 0x1e;
+    const BYTE HIGHEST_BIT = 0x80;
+    int ret;
+
+    memset(state, 0, sizeof(state));
+
+    character = 0;
+    ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
+    ok(ret == 1, "ToAscii for Return key didn't return 1 (was %i)\n", ret);
+    ok(character == '\r', "ToAscii for Return was %i (expected 13)\n", character);
+
+    character = 0;
+    ret = ToAscii('A', SC_A, state, &character, 0);
+    ok(ret == 1, "ToAscii for character 'A' didn't return 1 (was %i)\n", ret);
+    ok(character == 'a', "ToAscii for character 'A' was %i (expected %i)\n", character, 'a');
+
+    state[VK_CONTROL] |= HIGHEST_BIT;
+    state[VK_LCONTROL] |= HIGHEST_BIT;
+    character = 0;
+    ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
+    ok(ret == 1, "ToAscii for CTRL + Return key didn't return 1 (was %i)\n", ret);
+    ok(character == '\n', "ToAscii for CTRL + Return was %i (expected 10)\n", character);
+
+    character = 0;
+    ret = ToAscii('A', SC_A, state, &character, 0);
+    ok(ret == 1, "ToAscii for CTRL + character 'A' didn't return 1 (was %i)\n", ret);
+    ok(character == 1, "ToAscii for CTRL + character 'A' was %i (expected 1)\n", character);
+
+    state[VK_SHIFT] |= HIGHEST_BIT;
+    state[VK_LSHIFT] |= HIGHEST_BIT;
+    ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0);
+    todo_wine ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
+
+    ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0);
+    ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToAscii('A', SC_A, NULL, &character, 0);
+    ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToAsciiEx(VK_RETURN, SC_RETURN, NULL, &character, 0, GetKeyboardLayout(0));
+    ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
+    ret = ToAsciiEx('A', SC_A, NULL, &character, 0, GetKeyboardLayout(0));
+    ok(ret == 0, "ToAsciiEx for NULL keystate didn't return 0 (was %i)\n", ret);
 }
 
 static void test_get_async_key_state(void)
@@ -1899,6 +1967,9 @@ static void test_Input_mouse(void)
     ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
 
     /* click after SetCapture call */
+    hwnd = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
+            0, 0, 100, 100, 0, NULL, NULL, NULL);
+    ok(hwnd != 0, "CreateWindow failed\n");
     SetCapture(button_win);
     got_button_down = got_button_up = FALSE;
     simulate_click(FALSE, 50, 50);
@@ -1920,6 +1991,7 @@ static void test_Input_mouse(void)
     }
     ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
     ok(got_button_up, "expected WM_RBUTTONUP message\n");
+    DestroyWindow(hwnd);
 
     /* click on child window after SetCapture call */
     hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD,
@@ -1953,6 +2025,307 @@ static void test_Input_mouse(void)
     DestroyWindow(button_win);
 }
 
+
+static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    if (message == WM_USER+1)
+    {
+        HWND hwnd = (HWND)lParam;
+        ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
+        ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
+    }
+    return DefWindowProcA(hwnd, message, wParam, lParam);
+}
+
+struct wnd_event
+{
+    HWND hwnd;
+    HANDLE wait_event;
+    HANDLE start_event;
+    DWORD attach_from;
+    DWORD attach_to;
+    BOOL setWindows;
+};
+
+static DWORD WINAPI thread_proc(void *param)
+{
+    MSG msg;
+    struct wnd_event *wnd_event = param;
+    BOOL ret;
+
+    if (wnd_event->wait_event)
+    {
+        ok(WaitForSingleObject(wnd_event->wait_event, INFINITE) == WAIT_OBJECT_0,
+           "WaitForSingleObject failed\n");
+        CloseHandle(wnd_event->wait_event);
+    }
+
+    if (wnd_event->attach_from)
+    {
+        ret = AttachThreadInput(wnd_event->attach_from, GetCurrentThreadId(), TRUE);
+        ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    }
+
+    if (wnd_event->attach_to)
+    {
+        ret = AttachThreadInput(GetCurrentThreadId(), wnd_event->attach_to, TRUE);
+        ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    }
+
+    wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
+                                      100, 100, 200, 200, 0, 0, 0, NULL);
+    ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
+
+    if (wnd_event->setWindows)
+    {
+        SetFocus(wnd_event->hwnd);
+        SetActiveWindow(wnd_event->hwnd);
+    }
+
+    SetEvent(wnd_event->start_event);
+
+    while (GetMessageA(&msg, 0, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessageA(&msg);
+    }
+
+    return 0;
+}
+
+static void test_attach_input(void)
+{
+    HANDLE hThread;
+    HWND ourWnd, Wnd2;
+    DWORD ret, tid;
+    struct wnd_event wnd_event;
+    WNDCLASSA cls;
+
+    cls.style = 0;
+    cls.lpfnWndProc = MsgCheckProcA;
+    cls.cbClsExtra = 0;
+    cls.cbWndExtra = 0;
+    cls.hInstance = GetModuleHandleA(0);
+    cls.hIcon = 0;
+    cls.hCursor = LoadCursorW( NULL, (LPCWSTR)IDC_ARROW);
+    cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    cls.lpszMenuName = NULL;
+    cls.lpszClassName = "TestWindowClass";
+    if(!RegisterClassA(&cls)) return;
+
+    wnd_event.wait_event = NULL;
+    wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.attach_from = 0;
+    wnd_event.attach_to = 0;
+    wnd_event.setWindows = FALSE;
+    if (!wnd_event.start_event)
+    {
+        win_skip("skipping interthread message test under win9x\n");
+        return;
+    }
+
+    hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+    ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(wnd_event.start_event);
+
+    ourWnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+                            0, 0, 0, 0, 0, 0, 0, NULL);
+    ok(ourWnd!= 0, "failed to create ourWnd window\n");
+
+    Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+                            0, 0, 0, 0, 0, 0, 0, NULL);
+    ok(Wnd2!= 0, "failed to create Wnd2 window\n");
+
+    SetFocus(ourWnd);
+    SetActiveWindow(ourWnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
+
+    SetActiveWindow(Wnd2);
+    SetFocus(Wnd2);
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
+
+    ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+    ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(hThread);
+
+    wnd_event.wait_event = NULL;
+    wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.attach_from = 0;
+    wnd_event.attach_to = 0;
+    wnd_event.setWindows = TRUE;
+
+    hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+    ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(wnd_event.start_event);
+
+    SetFocus(ourWnd);
+    SetActiveWindow(ourWnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
+    ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
+    ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
+    ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    SetFocus(Wnd2);
+    SetActiveWindow(Wnd2);
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
+
+    ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+    ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(hThread);
+
+    wnd_event.wait_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.attach_from = 0;
+    wnd_event.attach_to = 0;
+    wnd_event.setWindows = TRUE;
+
+    hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+    ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(!ret, "AttachThreadInput succeeded\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
+       "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = AttachThreadInput(tid, GetCurrentThreadId(), TRUE);
+    ok(!ret, "AttachThreadInput succeeded\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* <= Win XP */,
+       "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+    SetEvent(wnd_event.wait_event);
+
+    ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(wnd_event.start_event);
+
+    ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+    ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(hThread);
+
+    wnd_event.wait_event = NULL;
+    wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.attach_from = GetCurrentThreadId();
+    wnd_event.attach_to = 0;
+    wnd_event.setWindows = FALSE;
+
+    SetFocus(ourWnd);
+    SetActiveWindow(ourWnd);
+
+    hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+    ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(wnd_event.start_event);
+
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+
+    ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+    ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(hThread);
+
+    wnd_event.wait_event = NULL;
+    wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+    wnd_event.attach_from = 0;
+    wnd_event.attach_to = GetCurrentThreadId();
+    wnd_event.setWindows = FALSE;
+
+    SetFocus(ourWnd);
+    SetActiveWindow(ourWnd);
+
+    hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+    ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(wnd_event.start_event);
+
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+
+    ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+    ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+    ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+    CloseHandle(hThread);
+    DestroyWindow(ourWnd);
+    DestroyWindow(Wnd2);
+}
+
 START_TEST(input)
 {
     init_function_pointers();
@@ -1970,9 +2343,11 @@ START_TEST(input)
     test_mouse_ll_hook();
     test_key_map();
     test_ToUnicode();
+    test_ToAscii();
     test_get_async_key_state();
     test_keyboard_layout_name();
     test_key_names();
+    test_attach_input();
 
     if(pGetMouseMovePointsEx)
         test_GetMouseMovePointsEx();
index 9dca54c..3d48999 100755 (executable)
@@ -10440,6 +10440,115 @@ done:
     flush_events();
 }
 
+static void test_PeekMessage3(void)
+{
+    HWND hwnd;
+    BOOL ret;
+    MSG msg;
+
+    hwnd = CreateWindowA("TestWindowClass", "PeekMessage3", WS_OVERLAPPEDWINDOW,
+                         10, 10, 800, 800, NULL, NULL, NULL, NULL);
+    ok(hwnd != NULL, "expected hwnd != NULL\n");
+    flush_events();
+
+    /* GetMessage() and PeekMessage(..., PM_REMOVE) should prefer messages which
+     * were already seen. */
+
+    SetTimer(hwnd, 1, 0, NULL);
+    while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    SetTimer(hwnd, 1, 0, NULL);
+    while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    /* It doesn't matter if a message range is specified or not. */
+
+    SetTimer(hwnd, 1, 0, NULL);
+    while (!PeekMessageA(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    /* But not if the post messages were added before the PeekMessage() call. */
+
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    SetTimer(hwnd, 1, 0, NULL);
+    while (!PeekMessageA(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    /* More complicated test with multiple messages. */
+
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    SetTimer(hwnd, 1, 0, NULL);
+    while (!PeekMessageA(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    PostMessageA(hwnd, WM_USER + 1, 0, 0);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER + 1, "msg.message = %u instead of WM_USER + 1\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    /* Also works for posted messages, but the situation is a bit different,
+     * because both messages are in the same queue. */
+
+    PostMessageA(hwnd, WM_TIMER, 0, 0);
+    while (!PeekMessageA(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    PostMessageA(hwnd, WM_USER, 0, 0);
+    PostMessageA(hwnd, WM_TIMER, 0, 0);
+    while (!PeekMessageA(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE));
+    ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
+    ret = GetMessageA(&msg, NULL, 0, 0);
+    ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
+    ret = PeekMessageA(&msg, NULL, 0, 0, 0);
+    ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
+
+    DestroyWindow(hwnd);
+    flush_events();
+}
+
 static INT_PTR CALLBACK wm_quit_dlg_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
 {
     struct recvd_message msg;
@@ -14124,10 +14233,9 @@ todo_wine
     ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
     ok(ret, "AttachThreadInput error %d\n", GetLastError());
 
-todo_wine {
     ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
     ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
-}
+
     flush_events();
     flush_sequence();
 
@@ -14484,6 +14592,160 @@ static void test_TrackPopupMenuEmpty(void)
     DestroyWindow(hwnd);
 }
 
+static const struct message send_message_1[] = {
+    { WM_USER+2, sent|wparam|lparam, 0, 0 },
+    { WM_USER, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message send_message_2[] = {
+    { WM_USER+4, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message send_message_3[] = {
+    { WM_USER+3, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+static const struct message send_message_4[] = {
+    { WM_USER+1, sent|wparam|lparam, 0, 0 },
+    { 0 }
+};
+
+static DWORD WINAPI SendMessage_thread_1(void *param)
+{
+    struct wnd_event *wnd_event = param;
+
+    trace("thread: starting\n");
+    WaitForSingleObject(wnd_event->start_event, INFINITE);
+
+    trace("thread: call PostMessage\n");
+    PostMessageA(wnd_event->hwnd, WM_USER, 0, 0);
+
+    trace("thread: call PostMessage\n");
+    PostMessageA(wnd_event->hwnd, WM_USER+1, 0, 0);
+
+    trace("thread: call SendMessage\n");
+    SendMessageA(wnd_event->hwnd, WM_USER+2, 0, 0);
+
+    trace("thread: call SendMessage\n");
+    SendMessageA(wnd_event->hwnd, WM_USER+3, 0, 0);
+
+    return 0;
+}
+
+static DWORD WINAPI SendMessage_thread_2(void *param)
+{
+    struct wnd_event *wnd_event = param;
+
+    trace("thread: starting\n");
+    WaitForSingleObject(wnd_event->start_event, INFINITE);
+
+    trace("thread: call PostMessage\n");
+    PostMessageA(wnd_event->hwnd, WM_USER, 0, 0);
+
+    trace("thread: call PostMessage\n");
+    PostMessageA(wnd_event->hwnd, WM_USER+1, 0, 0);
+
+    /* this leads to sending an internal message under Wine */
+    trace("thread: call EnableWindow\n");
+    EnableWindow(wnd_event->hwnd, TRUE);
+
+    trace("thread: call SendMessage\n");
+    SendMessageA(wnd_event->hwnd, WM_USER+2, 0, 0);
+
+    trace("thread: call SendMessage\n");
+    SendMessageA(wnd_event->hwnd, WM_USER+3, 0, 0);
+
+    return 0;
+}
+
+static void test_SendMessage_other_thread(int thread_n)
+{
+    DWORD qs_all_input = QS_ALLINPUT & ~QS_RAWINPUT;
+    HANDLE hthread;
+    struct wnd_event wnd_event;
+    DWORD tid, ret;
+    MSG msg;
+
+    wnd_event.start_event = CreateEventA(NULL, 0, 0, NULL);
+
+    wnd_event.hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+                                     100, 100, 200, 200, 0, 0, 0, NULL);
+    ok(wnd_event.hwnd != 0, "CreateWindowEx failed\n");
+
+    hthread = CreateThread(NULL, 0, thread_n == 1 ? SendMessage_thread_1 : SendMessage_thread_2, &wnd_event, 0, &tid);
+    ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
+    CloseHandle(hthread);
+
+    flush_events();
+    flush_sequence();
+
+    ret = GetQueueStatus(QS_SENDMESSAGE);
+    ok(ret == 0, "wrong status %08x\n", ret);
+
+    SetEvent(wnd_event.start_event);
+
+    /* wait for other thread's SendMessage */
+    for (;;)
+    {
+        ret = GetQueueStatus(QS_SENDMESSAGE);
+        if (ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE)) break;
+        Sleep(50);
+    }
+
+    ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+    ok(ret == MAKELONG(QS_POSTMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
+
+    trace("main: call GetMessage\n");
+    GetMessageA(&msg, 0, 0, 0);
+    ok(msg.message == WM_USER, "expected WM_USER, got %04x\n", msg.message);
+    DispatchMessageA(&msg);
+    ok_sequence(send_message_1, "SendMessage from other thread 1", thread_n == 2);
+
+    /* intentionally yield */
+    MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
+
+    trace("main: call SendMessage\n");
+    SendMessageA(wnd_event.hwnd, WM_USER+4, 0, 0);
+    ok_sequence(send_message_2, "SendMessage from other thread 2", FALSE);
+
+    ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+    ok(ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
+
+    trace("main: call PeekMessage\n");
+    ok(PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE), "PeekMessage should not fail\n");
+    ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message);
+    ok_sequence(send_message_3, "SendMessage from other thread 3", thread_n == 2);
+
+    trace("main: call PeekMessage\n");
+    ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should not fail\n");
+    ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message);
+    DispatchMessageA(&msg);
+    ok_sequence(send_message_4, "SendMessage from other thread 4", FALSE);
+
+    /* intentionally yield */
+    MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
+
+    ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+    /* FIXME: remove once Wine is fixed */
+if (thread_n == 2) todo_wine
+    ok(ret == 0, "wrong status %08x\n", ret);
+else
+    ok(ret == 0, "wrong status %08x\n", ret);
+
+    trace("main: call PeekMessage\n");
+    ok(!PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should fail\n");
+    ok_sequence(WmEmptySeq, "SendMessage from other thread 5", thread_n == 2);
+
+    ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+    ok(ret == 0, "wrong status %08x\n", ret);
+
+    trace("main: call DestroyWindow\n");
+    DestroyWindow(msg.hwnd);
+
+    flush_events();
+    flush_sequence();
+}
+
 static void init_funcs(void)
 {
     HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
@@ -14562,12 +14824,16 @@ START_TEST(msg)
         pUnhookWinEvent = 0;
     }
     hEvent_hook = 0;
+
+    test_SendMessage_other_thread(1);
+    test_SendMessage_other_thread(2);
     test_SetFocus();
     test_SetParent();
     test_PostMessage();
     test_ShowWindow();
     test_PeekMessage();
     test_PeekMessage2();
+    test_PeekMessage3();
     test_WaitForInputIdle( test_argv[0] );
     test_scrollwindowex();
     test_messages();
@@ -14700,9 +14966,12 @@ START_TEST(msg_queue)
     }
 
     init_tests();
+    test_SendMessage_other_thread(1);
+    test_SendMessage_other_thread(2);
     test_PostMessage();
     test_PeekMessage();
     test_PeekMessage2();
+    test_PeekMessage3();
     test_interthread_messages();
     test_DispatchMessage();
     test_SendMessageTimeout();
index d4aa9b1..841889d 100644 (file)
@@ -117,6 +117,21 @@ static void test_updates(int style, int flags)
     DestroyWindow(hStatic);
 }
 
+static void test_set_text(void)
+{
+    HWND hStatic = build_static(SS_SIMPLE);
+    char buffA[10];
+
+    GetWindowTextA(hStatic, buffA, sizeof(buffA));
+    ok(!strcmp(buffA, "Test"), "got wrong text %s\n", buffA);
+
+    SetWindowTextA(hStatic, NULL);
+    GetWindowTextA(hStatic, buffA, sizeof(buffA));
+    ok(buffA[0] == 0, "got wrong text %s\n", buffA);
+
+    DestroyWindow(hStatic);
+}
+
 START_TEST(static)
 {
     static const char szClassName[] = "testclass";
@@ -148,6 +163,7 @@ START_TEST(static)
     test_updates(SS_WHITERECT, TODO_COUNT);
     test_updates(SS_ETCHEDHORZ, TODO_COUNT);
     test_updates(SS_ETCHEDVERT, TODO_COUNT);
+    test_set_text();
 
     DestroyWindow(hMainWnd);
 }
index 0acf5f9..7cdbc6f 100644 (file)
@@ -2007,23 +2007,20 @@ static void test_icons(void)
 
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == 0, "wrong small icon %p/0\n", res );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res != 0, "wrong small icon %p\n", res );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( (res && res != small_icon && res != icon2) || broken(!res), "wrong small2 icon %p\n", res );
     res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)icon );
     ok( res == 0, "wrong previous small icon %p/0\n", res );
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( res == icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, icon );
     res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)small_icon );
     ok( res == icon, "wrong previous small icon %p/%p\n", res, icon );
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( res == small_icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, small_icon );
 
     /* make sure the big icon hasn't changed */
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
@@ -3797,7 +3794,7 @@ static LRESULT WINAPI StyleCheckProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
 
             ok((lpss->styleOld & ~WS_EX_WINDOWEDGE) == (lpcs->dwExStyle & ~WS_EX_WINDOWEDGE),
                 "Ex style (0x%08x) should match what the caller passed to CreateWindowEx (0x%08x)\n",
-                (lpss->styleOld & ~WS_EX_WINDOWEDGE), (lpcs->dwExStyle & ~WS_EX_WINDOWEDGE));
+                lpss->styleOld, lpcs->dwExStyle);
 
             ok(lpss->styleNew == lpcs->style,
                 "Style (0x%08x) should match what the caller passed to CreateWindowEx (0x%08x)\n",
@@ -3985,14 +3982,14 @@ static void check_dialog_style(DWORD style_in, DWORD ex_style_in, DWORD style_ou
 
     style = GetWindowLongA(hwnd, GWL_STYLE);
     ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
-    ok(style == (style_out | DS_3DLOOK), "expected style %#x, got %#x\n", style_out | DS_3DLOOK, style);
+    ok(style == (style_out | DS_3DLOOK), "got %#x\n", style);
     ok(ex_style == ex_style_out, "expected ex_style %#x, got %#x\n", ex_style_out, ex_style);
 
     /* try setting the styles explicitly */
     SetWindowLongA(hwnd, GWL_EXSTYLE, ex_style_in);
     style = GetWindowLongA(hwnd, GWL_STYLE);
     ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
-    ok(style == (style_out | DS_3DLOOK), "expected style %#x, got %#x\n", style_out|DS_3DLOOK, style);
+    ok(style == (style_out | DS_3DLOOK), "got %#x\n", style);
     /* WS_EX_WINDOWEDGE can't always be changed */
     if (ex_style_in & WS_EX_DLGMODALFRAME)
         ex_style_out = ex_style_in | WS_EX_WINDOWEDGE;
@@ -4883,6 +4880,7 @@ static void test_IsWindowUnicode(void)
     WNDCLASSA classA;
     WNDCLASSW classW;
     HWND hwnd;
+    ATOM atom;
 
     memset(&classW, 0, sizeof(classW));
     classW.hInstance = GetModuleHandleA(0);
@@ -4894,7 +4892,8 @@ static void test_IsWindowUnicode(void)
     classA.hInstance = GetModuleHandleA(0);
     classA.lpfnWndProc = def_window_procA;
     classA.lpszClassName = ansi_class_nameA;
-    assert(RegisterClassA(&classA));
+    atom = RegisterClassA(&classA);
+    assert(atom);
 
     /* unicode class: window proc */
     hwnd = CreateWindowExW(0, unicode_class_nameW, NULL, WS_POPUP,
@@ -5794,7 +5793,7 @@ static void test_gettext(void)
         num_msgs++;
     }
     CloseHandle( thread );
-    ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
+    ok( num_msgs >= 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
 
     /* test interthread SetWindowText */
     num_msgs = 0;
@@ -5807,7 +5806,7 @@ static void test_gettext(void)
         num_msgs++;
     }
     CloseHandle( thread );
-    ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
+    ok( num_msgs >= 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
 
     num_gettext_msgs = 0;
     memset( buf, 0, sizeof(buf) );
@@ -8006,35 +8005,40 @@ static void test_GetMessagePos(void)
     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);
+    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);
+    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);
+    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);
+    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);
+    ok(pos == MAKELONG(320, 340), "pos = %08x\n", pos);
 
     SetTimer(button, 1, 250, NULL);
     SetCursorPos(330, 350);
     GetMessageA(&msg, button, 0, 0);
+    while (msg.message == WM_PAINT)
+    {
+        UpdateWindow( button );
+        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);
+    ok(pos == MAKELONG(330, 350), "pos = %08x\n", pos);
     KillTimer(button, 1);
 
     DestroyWindow(button);
index c09ebb1..30c56c3 100755 (executable)
@@ -880,7 +880,10 @@ static void test_foregroundwindow(void)
                     if (input_desk_id == thread_desk_id)
                     {
                         ok(ret, "SetForegroundWindow failed!\n");
-                        ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
+                        if (hwnd)
+                            ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
+                        else
+                            todo_wine ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
                     }
                     else
                     {
@@ -893,12 +896,18 @@ static void test_foregroundwindow(void)
                     if (input_desk_id == thread_desk_id)
                     {
                         ok(!ret, "SetForegroundWindow should fail!\n");
-                        ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
+                        if (hwnd)
+                            ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
+                        else
+                            todo_wine ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
                     }
                     else
                     {
                         todo_wine ok(!ret, "SetForegroundWindow should fail!\n");
-                        todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
+                        if (!hwnd)
+                            ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
+                        else
+                            todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
                     }
                 }
             }