[USER32_APITEST] -Add a monster of a test to check if WM_DESTROYCLIPBOARD is blocking...
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Thu, 24 Aug 2017 23:08:09 +0000 (23:08 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Thu, 24 Aug 2017 23:08:09 +0000 (23:08 +0000)
svn path=/trunk/; revision=75663

rostests/apitests/user32/CMakeLists.txt
rostests/apitests/user32/EmptyClipboard.c [new file with mode: 0644]
rostests/apitests/user32/testlist.c

index bc4b769..3b75883 100644 (file)
@@ -9,6 +9,7 @@ list(APPEND SOURCE
     DestroyCursorIcon.c
     DrawIconEx.c
     desktop.c
+    EmptyClipboard.c
     EnumDisplaySettings.c
     GetDCEx.c
     GetIconInfo.c
diff --git a/rostests/apitests/user32/EmptyClipboard.c b/rostests/apitests/user32/EmptyClipboard.c
new file mode 100644 (file)
index 0000000..a7d0140
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * PURPOSE:         Test for EmptyClipboard
+ * PROGRAMMERS:     Giannis Adamopoulos
+ */
+
+#include <apitest.h>
+
+#include <wingdi.h>
+#include <winuser.h>
+
+#include <msgtrace.h>
+#include <user32testhelpers.h>
+
+HWND hWnd1, hWnd2;
+
+CRITICAL_SECTION CritSect;
+
+/* FIXME: test for HWND_TOP, etc...*/
+static int get_iwnd(HWND hWnd)
+{
+    if(hWnd == hWnd1) return 1;
+    else if(hWnd2 && hWnd == hWnd2) return 2;
+    else return 0;
+}
+
+LRESULT CALLBACK ClipTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    int iwnd = get_iwnd(hWnd);
+
+    if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
+        return DefWindowProc(hWnd, message, wParam, lParam);
+
+    switch(message)
+    {
+    case WM_GETICON :
+    case WM_SETICON:
+        break;
+    case WM_DESTROYCLIPBOARD:
+        Sleep(1000);
+    default:
+       EnterCriticalSection(&CritSect);
+        RECORD_MESSAGE(iwnd, message, SENT, 0,0);
+        LeaveCriticalSection(&CritSect);
+    }
+    return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static void RecordAndDispatch(MSG* pmsg)
+{
+    int iwnd = get_iwnd(pmsg->hwnd);
+    if(!(pmsg->message > WM_USER || !iwnd || IsDWmMsg(pmsg->message) || IseKeyMsg(pmsg->message)))
+    {
+        EnterCriticalSection(&CritSect);
+        RECORD_MESSAGE(iwnd, pmsg->message, POST,0,0);
+        LeaveCriticalSection(&CritSect);
+    }
+    DispatchMessageA( pmsg );
+}
+
+static void FlushMessages()
+{
+    MSG msg;
+    while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
+        RecordAndDispatch(&msg);
+}
+
+static DWORD WINAPI ClipThread(PVOID Parameter)
+{
+    BOOL ret;
+
+    hWnd2 = CreateWindowW(L"clipstest", L"clipstest", WS_OVERLAPPEDWINDOW,
+                        20, 20, 300, 300, NULL, NULL, 0, NULL);
+
+    /* Get ownership of the clipboard and record the messages we get */
+    ret = OpenClipboard(hWnd2);
+    ok (ret, "OpenClipboard failed\n");
+
+    EnterCriticalSection(&CritSect);
+    RECORD_MESSAGE(1, WM_DESTROYCLIPBOARD, MARKER,0,0);
+    LeaveCriticalSection(&CritSect);
+
+    ret = EmptyClipboard();
+    ok (ret, "EmptyClipboard failed\n");
+
+    EnterCriticalSection(&CritSect);
+    RECORD_MESSAGE(1, WM_DESTROYCLIPBOARD, MARKER,1,0);
+    LeaveCriticalSection(&CritSect);
+
+    ret = CloseClipboard();
+    ok (ret, "CloseClipboard failed\n");
+
+    /* Record if we got any post messages */
+    FlushMessages();
+
+    /* Force the parent thread out of its loop */
+    PostMessageW(hWnd1, WM_QUIT, 0, 0);
+
+    return 0;
+}
+
+MSG_ENTRY EmptyClipboard_chain[]={
+    {1,WM_DESTROYCLIPBOARD, MARKER, 0},
+    {1,WM_DESTROYCLIPBOARD, SENT},
+    {1,WM_DESTROYCLIPBOARD, MARKER, 1},
+    {0,0}};
+
+void TestMessages()
+{
+    HANDLE hThread;
+    DWORD dwThread;
+    BOOL ret;
+    MSG msg;
+
+    /* Initialize the test */
+    InitializeCriticalSection(&CritSect);
+
+    RegisterSimpleClass(ClipTestProc, L"clipstest");
+
+    hWnd2 = NULL;
+    hWnd1 = CreateWindowW(L"clipstest", L"clipstest", WS_OVERLAPPEDWINDOW,
+                        20, 20, 300, 300, NULL, NULL, 0, NULL);
+    ok (hWnd1 != NULL, "CreateWindowW failed\n");
+
+    EMPTY_CACHE();
+
+    /* Get ownership of the clipboard and record the messages we get */
+    ret = OpenClipboard(hWnd1);
+    ok (ret, "OpenClipboard failed\n");
+
+    ret = EmptyClipboard();
+    ok (ret, "EmptyClipboard failed\n");
+
+    ret = CloseClipboard();
+    ok (ret, "CloseClipboard failed\n");
+
+    /* Record posted messages */
+    FlushMessages();
+    COMPARE_CACHE(empty_chain);
+
+    /* Create the child thread and record messages till we get the WM_QUIT */
+    hThread = CreateThread(NULL, 0, ClipThread, NULL, 0, &dwThread);
+
+    while (GetMessage(&msg, 0, 0 ,0))
+        RecordAndDispatch(&msg);
+
+    COMPARE_CACHE(EmptyClipboard_chain);
+
+    CloseHandle(hThread);
+}
+
+void TestOwnership()
+{
+    BOOL ret;
+    HWND hWnd, hWndClipOwner;
+
+    ret = OpenClipboard(NULL);
+    ok (ret, "OpenClipboard failed\n");
+
+    ret = EmptyClipboard();
+    ok (ret, "EmptyClipboard failed\n");
+
+    ret = CloseClipboard();
+    ok (ret, "CloseClipboard failed\n");
+
+    hWndClipOwner = GetClipboardOwner();
+    ok (hWndClipOwner == NULL, "Expected NULL owner\n");
+
+    hWnd = CreateWindowW(L"static", L"static", WS_OVERLAPPEDWINDOW, 20, 20, 300, 300, NULL, NULL, 0, NULL);
+    ok (hWnd != 0 , "CreateWindowW failed\n");
+
+    ret = OpenClipboard(hWnd);
+    ok (ret, "OpenClipboard failed\n");
+
+    hWndClipOwner = GetClipboardOwner();
+    ok (hWndClipOwner == NULL, "Expected NULL owner\n");
+
+    ret = EmptyClipboard();
+    ok (ret, "EmptyClipboard failed\n");
+
+    ret = CloseClipboard();
+    ok (ret, "CloseClipboard failed\n");
+
+    hWndClipOwner = GetClipboardOwner();
+    ok (hWndClipOwner == hWnd, "Expected hWnd owner\n");
+
+    DestroyWindow(hWnd);
+}
+
+START_TEST(EmptyClipboard)
+{
+    TestOwnership();
+    TestMessages();
+}
index 74db390..494137a 100644 (file)
@@ -11,6 +11,7 @@ extern void func_DeferWindowPos(void);
 extern void func_DestroyCursorIcon(void);
 extern void func_DrawIconEx(void);
 extern void func_desktop(void);
+extern void func_EmptyClipboard(void);
 extern void func_EnumDisplaySettings(void);
 extern void func_GetDCEx(void);
 extern void func_GetIconInfo(void);
@@ -50,6 +51,7 @@ const struct test winetest_testlist[] =
     { "DestroyCursorIcon", func_DestroyCursorIcon },
     { "DrawIconEx", func_DrawIconEx },
     { "desktop", func_desktop },
+    { "EmptyClipboard", func_EmptyClipboard },
     { "EnumDisplaySettings", func_EnumDisplaySettings },
     { "GetDCEx", func_GetDCEx },
     { "GetIconInfo", func_GetIconInfo },