1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for EmptyClipboard
5  * PROGRAMMERS:     Giannis Adamopoulos
6  */
7 
8 #include "precomp.h"
9 
10 HWND hWnd1, hWnd2;
11 
12 CRITICAL_SECTION CritSect;
13 
14 /* FIXME: test for HWND_TOP, etc...*/
15 static int get_iwnd(HWND hWnd)
16 {
17     if(hWnd == hWnd1) return 1;
18     else if(hWnd2 && hWnd == hWnd2) return 2;
19     else return 0;
20 }
21 
22 LRESULT CALLBACK ClipTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
23 {
24     int iwnd = get_iwnd(hWnd);
25 
26     if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
27         return DefWindowProc(hWnd, message, wParam, lParam);
28 
29     switch(message)
30     {
31     case WM_GETICON :
32     case WM_SETICON:
33         break;
34     case WM_DESTROYCLIPBOARD:
35         Sleep(1000);
36     default:
37       	EnterCriticalSection(&CritSect);
38         RECORD_MESSAGE(iwnd, message, SENT, 0,0);
39         LeaveCriticalSection(&CritSect);
40     }
41     return DefWindowProc(hWnd, message, wParam, lParam);
42 }
43 
44 static void RecordAndDispatch(MSG* pmsg)
45 {
46     int iwnd = get_iwnd(pmsg->hwnd);
47     if(!(pmsg->message > WM_USER || !iwnd || IsDWmMsg(pmsg->message) || IseKeyMsg(pmsg->message)))
48     {
49         EnterCriticalSection(&CritSect);
50         RECORD_MESSAGE(iwnd, pmsg->message, POST,0,0);
51         LeaveCriticalSection(&CritSect);
52     }
53     DispatchMessageA( pmsg );
54 }
55 
56 static void FlushMessages()
57 {
58     MSG msg;
59     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
60         RecordAndDispatch(&msg);
61 }
62 
63 static DWORD WINAPI ClipThread(PVOID Parameter)
64 {
65     BOOL ret;
66 
67     hWnd2 = CreateWindowW(L"clipstest", L"clipstest", WS_OVERLAPPEDWINDOW,
68                         20, 20, 300, 300, NULL, NULL, 0, NULL);
69 
70     /* Get ownership of the clipboard and record the messages we get */
71     ret = OpenClipboard(hWnd2);
72     ok (ret, "OpenClipboard failed\n");
73 
74     EnterCriticalSection(&CritSect);
75     RECORD_MESSAGE(1, WM_DESTROYCLIPBOARD, MARKER,0,0);
76     LeaveCriticalSection(&CritSect);
77 
78     ret = EmptyClipboard();
79     ok (ret, "EmptyClipboard failed\n");
80 
81     EnterCriticalSection(&CritSect);
82     RECORD_MESSAGE(1, WM_DESTROYCLIPBOARD, MARKER,1,0);
83     LeaveCriticalSection(&CritSect);
84 
85     ret = CloseClipboard();
86     ok (ret, "CloseClipboard failed\n");
87 
88     /* Record if we got any post messages */
89     FlushMessages();
90 
91     /* Force the parent thread out of its loop */
92     PostMessageW(hWnd1, WM_QUIT, 0, 0);
93 
94     return 0;
95 }
96 
97 MSG_ENTRY EmptyClipboard_chain[]={
98     {1,WM_DESTROYCLIPBOARD, MARKER, 0},
99     {1,WM_DESTROYCLIPBOARD, SENT},
100     {1,WM_DESTROYCLIPBOARD, MARKER, 1},
101     {0,0}};
102 
103 void TestMessages()
104 {
105     HANDLE hThread;
106     DWORD dwThread;
107     BOOL ret;
108     MSG msg;
109 
110     /* Initialize the test */
111     InitializeCriticalSection(&CritSect);
112 
113     RegisterSimpleClass(ClipTestProc, L"clipstest");
114 
115     hWnd2 = NULL;
116     hWnd1 = CreateWindowW(L"clipstest", L"clipstest", WS_OVERLAPPEDWINDOW,
117                         20, 20, 300, 300, NULL, NULL, 0, NULL);
118     ok (hWnd1 != NULL, "CreateWindowW failed\n");
119 
120     EMPTY_CACHE();
121 
122     /* Get ownership of the clipboard and record the messages we get */
123     ret = OpenClipboard(hWnd1);
124     ok (ret, "OpenClipboard failed\n");
125 
126     ret = EmptyClipboard();
127     ok (ret, "EmptyClipboard failed\n");
128 
129     ret = CloseClipboard();
130     ok (ret, "CloseClipboard failed\n");
131 
132     /* Record posted messages */
133     FlushMessages();
134     COMPARE_CACHE(empty_chain);
135 
136     /* Create the child thread and record messages till we get the WM_QUIT */
137     hThread = CreateThread(NULL, 0, ClipThread, NULL, 0, &dwThread);
138 
139     while (GetMessage(&msg, 0, 0 ,0))
140         RecordAndDispatch(&msg);
141 
142     COMPARE_CACHE(EmptyClipboard_chain);
143 
144     CloseHandle(hThread);
145 }
146 
147 void TestOwnership()
148 {
149     BOOL ret;
150     HWND hWnd, hWndClipOwner;
151 
152     ret = OpenClipboard(NULL);
153     ok (ret, "OpenClipboard failed\n");
154 
155     ret = EmptyClipboard();
156     ok (ret, "EmptyClipboard failed\n");
157 
158     ret = CloseClipboard();
159     ok (ret, "CloseClipboard failed\n");
160 
161     hWndClipOwner = GetClipboardOwner();
162     ok (hWndClipOwner == NULL, "Expected NULL owner\n");
163 
164     hWnd = CreateWindowW(L"static", L"static", WS_OVERLAPPEDWINDOW, 20, 20, 300, 300, NULL, NULL, 0, NULL);
165     ok (hWnd != 0 , "CreateWindowW failed\n");
166 
167     ret = OpenClipboard(hWnd);
168     ok (ret, "OpenClipboard failed\n");
169 
170     hWndClipOwner = GetClipboardOwner();
171     ok (hWndClipOwner == NULL, "Expected NULL owner\n");
172 
173     ret = EmptyClipboard();
174     ok (ret, "EmptyClipboard failed\n");
175 
176     ret = CloseClipboard();
177     ok (ret, "CloseClipboard failed\n");
178 
179     hWndClipOwner = GetClipboardOwner();
180     ok (hWndClipOwner == hWnd, "Expected hWnd owner\n");
181 
182     DestroyWindow(hWnd);
183 }
184 
185 START_TEST(EmptyClipboard)
186 {
187     TestOwnership();
188     TestMessages();
189 }
190