[WS2_32_APITEST]
[reactos.git] / rostests / apitests / user32 / DeferWindowPos.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for DeferWindowPos function family
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9
10 #include <winuser.h>
11 #include "helper.h"
12 #include <undocuser.h>
13
14 HWND hWnd1, hWnd2, hWnd3, hWnd4;
15
16 /* FIXME: test for HWND_TOP, etc...*/
17 static int get_iwnd(HWND hWnd)
18 {
19 if(hWnd == hWnd1) return 1;
20 else if(hWnd == hWnd2) return 2;
21 else if(hWnd == hWnd3) return 3;
22 else if(hWnd == hWnd4) return 4;
23 else return 0;
24 }
25
26 LRESULT CALLBACK DWPTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
27 {
28 int iwnd = get_iwnd(hWnd);
29
30 if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
31 return DefWindowProc(hWnd, message, wParam, lParam);
32
33 switch(message)
34 {
35 case WM_IME_SETCONTEXT:
36 case WM_IME_NOTIFY :
37 case WM_GETICON :
38 case WM_GETTEXT:
39 break;
40 case WM_WINDOWPOSCHANGING:
41 case WM_WINDOWPOSCHANGED:
42 {
43 WINDOWPOS* pwp = (WINDOWPOS*)lParam;
44 ok(wParam==0,"expected wParam=0\n");
45 RECORD_MESSAGE(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags);
46 break;
47 }
48 default:
49 RECORD_MESSAGE(iwnd, message, SENT, 0,0);
50 }
51 return DefWindowProc(hWnd, message, wParam, lParam);
52 }
53
54 static void FlushMessages()
55 {
56 MSG msg;
57
58 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
59 {
60 int iwnd = get_iwnd(msg.hwnd);
61 if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
62 RECORD_MESSAGE(iwnd, msg.message, POST,0,0);
63 DispatchMessageA( &msg );
64 }
65 }
66
67 /* unfortunately sometimes MSCTF windows get between the expected chain of windows
68 so just checking the next window does not work*/
69 static BOOL IsNext(HWND hWnd1, HWND hWnd2)
70 {
71 HWND hWndNext;
72
73 hWndNext=hWnd1;
74 while((hWndNext = GetWindow(hWndNext,GW_HWNDNEXT)))
75 {
76 if(hWndNext == hWnd2)
77 {
78 return TRUE;
79 }
80 }
81 return FALSE;
82 }
83
84 #define EXPECT_NEXT(hWnd1, hWnd2) \
85 ok(IsNext(hWnd1, hWnd2), \
86 "After hwnd%d, expected hwnd%d not hwnd%d\n", \
87 get_iwnd(hWnd1), get_iwnd(hWnd2),get_iwnd(GetWindow(hWnd1,GW_HWNDNEXT)) )
88
89 #define EXPECT_CHAIN(A,B,C,D) \
90 EXPECT_NEXT(hWnd##A, hWnd##B); \
91 EXPECT_NEXT(hWnd##B, hWnd##C); \
92 EXPECT_NEXT(hWnd##C, hWnd##D);
93
94 #define ok_windowpos(hwnd, x, y, w, h, wnd) do { RECT rt; GetWindowRect(hwnd, &rt); \
95 ok(rt.left == (x) && rt.top == (y) && rt.right == (x)+(w) && rt.bottom == (y)+(h), \
96 "Unexpected %s position: (%ld, %ld) - (%ld, %ld)\n", wnd, rt.left, rt.top, rt.right, rt.bottom); } while (0)
97
98 #define ok_lasterr(err, s) ok(GetLastError() == (err), "%s error = %lu\n", s, GetLastError())
99
100 static void set_default_pos()
101 {
102 SetWindowPos(hWnd1, 0, 10,20,200,210, SWP_NOOWNERZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
103 SetWindowPos(hWnd2, 0, 30,40,220,230, SWP_NOOWNERZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
104 SetWindowPos(hWnd3, 0, 20,350,300,300, SWP_NOOWNERZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
105 SetWindowPos(hWnd4, 0, 250,250,200,200, SWP_NOOWNERZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
106 SetActiveWindow(hWnd4);
107 FlushMessages();
108 EMPTY_CACHE();
109 }
110
111 static void Test_DWP_Error(HWND hWnd, HWND hWnd2)
112 {
113 HDWP hDwp;
114 BOOL ret;
115
116 ok_windowpos(hWnd1, 10, 20, 200, 210, "Window 1");
117 ok_windowpos(hWnd2, 30, 40, 220, 230, "Window 2");
118
119 /* close invalid handles */
120 SetLastError(DNS_ERROR_RCODE_NXRRSET);
121 ret = EndDeferWindowPos(NULL);
122 ok(ret == 0, "EndDeferWindowPos succeeded with invalid handle\n");
123 ok_lasterr(ERROR_INVALID_DWP_HANDLE, "EndDeferWindowPos");
124
125 SetLastError(DNS_ERROR_RCODE_NXRRSET);
126 ret = EndDeferWindowPos((HDWP)-1);
127 ok(ret == 0, "EndDeferWindowPos succeeded with invalid handle\n");
128 ok_lasterr(ERROR_INVALID_DWP_HANDLE, "EndDeferWindowPos");
129
130 /* negative window count */
131 SetLastError(DNS_ERROR_RCODE_NXRRSET);
132 hDwp = BeginDeferWindowPos(-1);
133 ok(hDwp == NULL, "BeginDeferWindowPos failed\n");
134 ok_lasterr(ERROR_INVALID_PARAMETER, "BeginDeferWindowPos");
135
136 /* zero windows */
137 SetLastError(DNS_ERROR_RCODE_NXRRSET);
138 hDwp = BeginDeferWindowPos(0);
139 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
140 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
141 ret = EndDeferWindowPos(hDwp);
142 ok(ret != 0, "EndDeferWindowPos failed\n");
143 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos");
144
145 /* more windows than expected */
146 SetLastError(DNS_ERROR_RCODE_NXRRSET);
147 hDwp = BeginDeferWindowPos(0);
148 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
149 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
150 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
151 ok(hDwp != NULL, "DeferWindowPos failed\n");
152 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
153 ret = EndDeferWindowPos(hDwp);
154 ok(ret != 0, "EndDeferWindowPos failed\n");
155 ok(GetLastError() == ERROR_SUCCESS /* win7 sp1/x64 */
156 || GetLastError() == ERROR_INVALID_WINDOW_HANDLE /* 2k3 sp1/x86 */,
157 "EndDeferWindowPos error = %lu\n", GetLastError());
158 ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1");
159
160 /* more windows than expected 2 */
161 SetLastError(DNS_ERROR_RCODE_NXRRSET);
162 hDwp = BeginDeferWindowPos(1);
163 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
164 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
165 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 30, 20, 190, 195, SWP_NOZORDER);
166 ok(hDwp != NULL, "DeferWindowPos failed\n");
167 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
168 hDwp = DeferWindowPos(hDwp, hWnd2, NULL, 20, 30, 195, 190, SWP_NOZORDER);
169 ok(hDwp != NULL, "DeferWindowPos failed\n");
170 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
171 ret = EndDeferWindowPos(hDwp);
172 ok(ret != 0, "EndDeferWindowPos failed\n");
173 ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos");
174 ok_windowpos(hWnd, 30, 20, 190, 195, "Window 1");
175 ok_windowpos(hWnd2, 20, 30, 195, 190, "Window 2");
176
177 /* fewer windows than expected */
178 MoveWindow(hWnd, 10, 20, 200, 210, FALSE);
179 SetLastError(DNS_ERROR_RCODE_NXRRSET);
180 hDwp = BeginDeferWindowPos(2);
181 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
182 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
183 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
184 ok(hDwp != NULL, "DeferWindowPos failed\n");
185 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
186 ret = EndDeferWindowPos(hDwp);
187 ok(ret != 0, "EndDeferWindowPos failed\n");
188 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos");
189 ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1");
190
191 /* no operation, 1 window */
192 SetLastError(DNS_ERROR_RCODE_NXRRSET);
193 hDwp = BeginDeferWindowPos(1);
194 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
195 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
196 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
197 ok(hDwp != NULL, "DeferWindowPos failed\n");
198 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
199 ret = EndDeferWindowPos(hDwp);
200 ok(ret != 0, "EndDeferWindowPos failed\n");
201 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "EndDeferWindowPos");
202 ok_windowpos(hWnd, 10, 20, 200, 210, "Window 1");
203
204 /* same window twice */
205 SetLastError(DNS_ERROR_RCODE_NXRRSET);
206 hDwp = BeginDeferWindowPos(2);
207 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
208 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
209 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 80, 90, 220, 210, SWP_NOZORDER);
210 ok(hDwp != NULL, "DeferWindowPos failed\n");
211 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
212 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 100, 110, 230, 250, SWP_NOZORDER);
213 ok(hDwp != NULL, "DeferWindowPos failed\n");
214 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
215 ret = EndDeferWindowPos(hDwp);
216 ok(ret != 0, "EndDeferWindowPos failed\n");
217 ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos");
218 ok_windowpos(hWnd, 100, 110, 230, 250, "Window 1");
219
220 /* move & resize operation, 1 window */
221 SetLastError(DNS_ERROR_RCODE_NXRRSET);
222 hDwp = BeginDeferWindowPos(1);
223 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
224 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
225 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 20, 10, 210, 200, SWP_NOZORDER);
226 ok(hDwp != NULL, "DeferWindowPos failed\n");
227 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
228 ret = EndDeferWindowPos(hDwp);
229 ok(ret != 0, "EndDeferWindowPos failed\n");
230 ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos");
231 ok_windowpos(hWnd, 20, 10, 210, 200, "Window 1");
232
233 /* move & resize operation, 2 windows */
234 SetLastError(DNS_ERROR_RCODE_NXRRSET);
235 hDwp = BeginDeferWindowPos(2);
236 ok(hDwp != NULL, "BeginDeferWindowPos failed\n");
237 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "BeginDeferWindowPos");
238 hDwp = DeferWindowPos(hDwp, hWnd, NULL, 50, 60, 230, 240, SWP_NOZORDER);
239 ok(hDwp != NULL, "DeferWindowPos failed\n");
240 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
241 hDwp = DeferWindowPos(hDwp, hWnd2, NULL, 70, 80, 250, 260, SWP_NOZORDER);
242 ok(hDwp != NULL, "DeferWindowPos failed\n");
243 ok_lasterr(DNS_ERROR_RCODE_NXRRSET, "DeferWindowPos");
244 ret = EndDeferWindowPos(hDwp);
245 ok(ret != 0, "EndDeferWindowPos failed\n");
246 ok_lasterr(ERROR_SUCCESS, "EndDeferWindowPos");
247 ok_windowpos(hWnd, 50, 60, 230, 240, "Window 1");
248 ok_windowpos(hWnd2, 70, 80, 250, 260, "Window 2");
249
250 FlushMessages();
251 EMPTY_CACHE();
252 }
253
254 MSG_ENTRY move1_chain[]={
255 {1,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER},
256 {1,WM_GETMINMAXINFO},
257 {1,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOSIZE | SWP_NOACTIVATE|SWP_NOOWNERZORDER | SWP_NOCLIENTSIZE},
258 {1,WM_MOVE},
259 {0,0}};
260
261 MSG_ENTRY resize1_chain[]={
262 {1,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER},
263 {1,WM_GETMINMAXINFO},
264 {1,WM_NCCALCSIZE},
265 {1,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE|SWP_NOOWNERZORDER | SWP_NOCLIENTMOVE},
266 {1,WM_SIZE},
267 {1,WM_NCCALCSIZE},
268 {0,0}};
269
270 MSG_ENTRY move1_2_chain[]={
271 {1,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER},
272 {1,WM_GETMINMAXINFO},
273 {2,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER},
274 {2,WM_GETMINMAXINFO},
275 {1,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE|SWP_NOOWNERZORDER | SWP_NOCLIENTSIZE},
276 {1,WM_MOVE},
277 {2,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOSIZE | SWP_NOACTIVATE|SWP_NOOWNERZORDER | SWP_NOCLIENTSIZE},
278 {2,WM_MOVE},
279 {0,0}};
280
281
282 MSG_ENTRY ZOrder1_chain[]={
283 {1,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE},
284 {1,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
285 {0,0}};
286
287 MSG_ENTRY ZOrder1and2_chain[]={
288 {1,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE},
289 {2,WM_WINDOWPOSCHANGING, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE},
290 {1,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
291 {2,WM_WINDOWPOSCHANGED, SENT, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
292 {0,0}};
293
294 static void Test_DWP_SimpleMsg(HWND hWnd1, HWND hWnd2)
295 {
296 HDWP hdwp;
297 BOOL ret;
298
299 SetWindowPos(hWnd1, 0, 10,20,100,100,0);
300 SetWindowPos(hWnd2, 0, 10,20,100,100,0);
301 FlushMessages();
302 EMPTY_CACHE();
303
304 /* move hWnd1 */
305 hdwp = BeginDeferWindowPos(1);
306 ok(hdwp != NULL, "BeginDeferWindowPos failed\n");
307 hdwp = DeferWindowPos(hdwp, hWnd1, HWND_TOP, 20, 30, 100, 100, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
308 ok(hdwp != NULL, "DeferWindowPos failed\n");
309 FlushMessages();
310 COMPARE_CACHE(empty_chain);
311 ret = EndDeferWindowPos(hdwp);
312 ok(ret != 0, "EndDeferWindowPos failed\n");
313 FlushMessages();
314 COMPARE_CACHE(move1_chain);
315
316 /* resize hWnd1 */
317 hdwp = BeginDeferWindowPos(1);
318 ok(hdwp != NULL, "BeginDeferWindowPos failed\n");
319 hdwp = DeferWindowPos(hdwp, hWnd1, HWND_TOP, 20, 30, 110, 110, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
320 ok(hdwp != NULL, "DeferWindowPos failed\n");
321 FlushMessages();
322 COMPARE_CACHE(empty_chain);
323 ret = EndDeferWindowPos(hdwp);
324 ok(ret != 0, "EndDeferWindowPos failed\n");
325 FlushMessages();
326 COMPARE_CACHE(resize1_chain);
327
328 /* move both windows */
329 hdwp = BeginDeferWindowPos(1);
330 ok(hdwp != NULL, "BeginDeferWindowPos failed\n");
331 hdwp = DeferWindowPos(hdwp, hWnd1, HWND_TOP, 30, 40, 110, 110, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
332 ok(hdwp != NULL, "DeferWindowPos failed\n");
333 hdwp = DeferWindowPos(hdwp, hWnd2, HWND_TOP, 30, 40, 100, 100, SWP_NOACTIVATE|SWP_NOOWNERZORDER);
334 ok(hdwp != NULL, "DeferWindowPos failed\n");
335 FlushMessages();
336 COMPARE_CACHE(empty_chain);
337 ret = EndDeferWindowPos(hdwp);
338 ok(ret != 0, "EndDeferWindowPos failed\n");
339 FlushMessages();
340 COMPARE_CACHE(move1_2_chain);
341
342 /* change the z-order of the first window */
343 hdwp = BeginDeferWindowPos(1);
344 ok(hdwp != NULL, "BeginDeferWindowPos failed\n");
345 hdwp = DeferWindowPos(hdwp, hWnd1, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE);
346 ok(hdwp != NULL, "DeferWindowPos failed\n");
347 FlushMessages();
348 COMPARE_CACHE(empty_chain);
349 ret = EndDeferWindowPos(hdwp);
350 ok(ret != 0, "EndDeferWindowPos failed\n");
351 FlushMessages();
352 COMPARE_CACHE(ZOrder1_chain);
353
354 /* change the z-order of both windows */
355 hdwp = BeginDeferWindowPos(2);
356 ok(hdwp != NULL, "BeginDeferWindowPos failed\n");
357 hdwp = DeferWindowPos(hdwp, hWnd1, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE);
358 ok(hdwp != NULL, "DeferWindowPos failed\n");
359 hdwp = DeferWindowPos(hdwp, hWnd2, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE);
360 ok(hdwp != NULL, "DeferWindowPos failed\n");
361 FlushMessages();
362 COMPARE_CACHE(empty_chain);
363 ret = EndDeferWindowPos(hdwp);
364 ok(ret != 0, "EndDeferWindowPos failed\n");
365 FlushMessages();
366 COMPARE_CACHE(ZOrder1and2_chain);
367
368 }
369
370 #define OwnerZOrderAParams SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOSIZE
371
372 MSG_ENTRY OwnerZOrder1A_chain[]={
373 {4,WM_WINDOWPOSCHANGING, SENT,0, OwnerZOrderAParams},
374 {3,WM_WINDOWPOSCHANGING, SENT,4, OwnerZOrderAParams},
375 {1,WM_WINDOWPOSCHANGING, SENT,3, OwnerZOrderAParams},
376 {0,0}};
377
378 MSG_ENTRY OwnerZOrder2A_chain[]={
379 {2,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderAParams},
380 {2,WM_WINDOWPOSCHANGED , SENT, 0, OwnerZOrderAParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
381 {0,0}};
382
383 MSG_ENTRY OwnerZOrder3A_chain[]={
384 {3,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderAParams},
385 {4,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderAParams},
386 {1,WM_WINDOWPOSCHANGING, SENT, 4, OwnerZOrderAParams},
387 {3,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderAParams |SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
388 {4,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderAParams |SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
389 {1,WM_WINDOWPOSCHANGED, SENT, 4, OwnerZOrderAParams |SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
390 {0,0}};
391
392 MSG_ENTRY OwnerZOrder4A_chain[]={
393 {3,WM_WINDOWPOSCHANGING, SENT, 0 ,OwnerZOrderAParams},
394 {4,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderAParams} ,
395 {1,WM_WINDOWPOSCHANGING, SENT, 4, OwnerZOrderAParams},
396 {0,0}};
397
398 MSG_ENTRY OwnerZOrder5A_chain[]={
399 {4,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderAParams},
400 {3,WM_WINDOWPOSCHANGING, SENT, 4, OwnerZOrderAParams},
401 {1,WM_WINDOWPOSCHANGING, SENT, 3, OwnerZOrderAParams},
402 {4,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderAParams|SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
403 {0,0}};
404
405 #define OwnerZOrderBParams SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOOWNERZORDER
406
407 MSG_ENTRY OwnerZOrder1B_chain[]={
408 {1,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderBParams},
409 {1,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderBParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
410 {0,0}};
411
412 MSG_ENTRY OwnerZOrder2B_chain[]={
413 {2,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderBParams},
414 {2,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderBParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
415 {0,0}};
416
417 MSG_ENTRY OwnerZOrder3B_chain[]={
418 {3,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderBParams},
419 {3,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderBParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
420 {0,0}};
421
422 MSG_ENTRY OwnerZOrder4B_chain[]={
423 {1,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderBParams},
424 {1,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderBParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
425 {0,0}};
426
427 MSG_ENTRY OwnerZOrder5B_chain[]={
428 {4,WM_WINDOWPOSCHANGING, SENT, 0, OwnerZOrderBParams},
429 {4,WM_WINDOWPOSCHANGED, SENT, 0, OwnerZOrderBParams | SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE},
430 {0,0}};
431
432 static void Test_DWP_OwnerZOrder()
433 {
434 EXPECT_CHAIN(4,3,1,2);
435
436 /* test how SetWindowPos can change the z order of owner windows */
437 /* note that SWP_NOACTIVATE must be used because otherwise
438 SetWindowPos will call SetWindowPos again with different parameters */
439 SetWindowPos(hWnd1, 0, 0,0,0,0, OwnerZOrderAParams);
440 FlushMessages();
441 COMPARE_CACHE(OwnerZOrder1A_chain);
442 EXPECT_CHAIN(4,3,1,2);
443
444 SetWindowPos(hWnd2, 0, 0,0,0,0, OwnerZOrderAParams);
445 FlushMessages();
446 COMPARE_CACHE(OwnerZOrder2A_chain);
447 EXPECT_CHAIN(2,4,3,1);
448
449 SetWindowPos(hWnd3, 0, 0,0,0,0, OwnerZOrderAParams);
450 FlushMessages();
451 COMPARE_CACHE(OwnerZOrder3A_chain);
452 EXPECT_CHAIN(3,4,1,2);
453
454 SetWindowPos(hWnd1, 0, 0,0,0,0, OwnerZOrderAParams);
455 FlushMessages();
456 COMPARE_CACHE(OwnerZOrder4A_chain);
457 EXPECT_CHAIN(3,4,1,2);
458
459 SetWindowPos(hWnd4, 0, 0,0,0,0, OwnerZOrderAParams);
460 FlushMessages();
461 COMPARE_CACHE(OwnerZOrder5A_chain);
462 EXPECT_CHAIN(4,3,1,2);
463
464 /* now do the same thing one more time with SWP_NOOWNERZORDER */
465 /* SWP_NOACTIVATE is needed because without it SetActiveWindow
466 will be calledit and it will call SetWindowPos again
467 WITHOUT SWP_NOOWNERZORDER. that means that
468 in order for SWP_NOOWNERZORDER to have effect we have to use
469 SWP_NOACTIVATE as well */
470 set_default_pos();
471 EXPECT_CHAIN(4,3,2,1);
472
473 SetWindowPos(hWnd1, 0, 0,0,0,0, OwnerZOrderBParams);
474 FlushMessages();
475 COMPARE_CACHE(OwnerZOrder1B_chain);
476 EXPECT_CHAIN(1,4,3,2);
477
478 SetWindowPos(hWnd2, 0, 0,0,0,0, OwnerZOrderBParams);
479 FlushMessages();
480 COMPARE_CACHE(OwnerZOrder2B_chain);
481 EXPECT_CHAIN(2,1,4,3);
482
483 SetWindowPos(hWnd3, 0, 0,0,0,0, OwnerZOrderBParams);
484 FlushMessages();
485 COMPARE_CACHE(OwnerZOrder3B_chain);
486 EXPECT_CHAIN(3,2,1,4);
487
488 SetWindowPos(hWnd1, 0, 0,0,0,0, OwnerZOrderBParams);
489 FlushMessages();
490 COMPARE_CACHE(OwnerZOrder4B_chain);
491 EXPECT_CHAIN(1,3,2,4);
492
493 SetWindowPos(hWnd4, 0, 0,0,0,0, OwnerZOrderBParams);
494 FlushMessages();
495 COMPARE_CACHE(OwnerZOrder5B_chain);
496 EXPECT_CHAIN(4,1,3,2);
497
498 }
499
500 START_TEST(DeferWindowPos)
501 {
502 SetCursorPos(0,0);
503
504 RegisterSimpleClass(DWPTestProc, L"ownertest");
505 hWnd1 = CreateWindowExW(0, L"ownertest", L"abc", 0, 10, 20,
506 200, 210, NULL, NULL, 0, NULL);
507 hWnd2 = CreateWindowExW(0, L"ownertest", L"def", 0, 30, 40,
508 220, 230, NULL, NULL, 0, NULL);
509 hWnd3 = CreateWindowW(L"ownertest", L"ownertest", WS_OVERLAPPEDWINDOW,
510 20, 350, 300, 300, hWnd1, NULL, 0, NULL);
511 hWnd4 = CreateWindowW(L"ownertest", L"ownertest", WS_OVERLAPPEDWINDOW,
512 250, 250, 200, 200, hWnd1, NULL, 0, NULL);
513
514 ok(hWnd1 != NULL, "CreateWindow failed\n");
515 ok(hWnd2 != NULL, "CreateWindow failed\n");
516 ok(hWnd3 != NULL, "CreateWindow failed\n");
517 ok(hWnd4 != NULL, "CreateWindow failed\n");
518
519 set_default_pos();
520 Test_DWP_Error(hWnd1, hWnd2);
521
522 set_default_pos();
523 Test_DWP_SimpleMsg(hWnd1, hWnd2);
524
525 set_default_pos();
526 Test_DWP_OwnerZOrder();
527
528 DestroyWindow(hWnd4);
529 DestroyWindow(hWnd3);
530 DestroyWindow(hWnd2);
531 DestroyWindow(hWnd1);
532 }