2 * Unit tests for window handling
4 * Copyright 2002 Bill Medland
5 * Copyright 2002 Alexandre Julliard
6 * Copyright 2003 Dmitry Timoshkov
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "wine/test.h"
35 #ifndef SPI_GETDESKWALLPAPER
36 #define SPI_GETDESKWALLPAPER 0x0073
39 #define LONG_PTR INT_PTR
40 #define ULONG_PTR UINT_PTR
42 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
44 static HWND hwndMain
, hwndMain2
;
47 /* check the values returned by the various parent/owner functions on a given window */
48 static void check_parents( HWND hwnd
, HWND ga_parent
, HWND gwl_parent
, HWND get_parent
,
49 HWND gw_owner
, HWND ga_root
, HWND ga_root_owner
)
55 res
= pGetAncestor( hwnd
, GA_PARENT
);
56 ok( res
== ga_parent
, "Wrong result for GA_PARENT %p expected %p", res
, ga_parent
);
58 res
= (HWND
)GetWindowLongA( hwnd
, GWL_HWNDPARENT
);
59 ok( res
== gwl_parent
, "Wrong result for GWL_HWNDPARENT %p expected %p", res
, gwl_parent
);
60 res
= GetParent( hwnd
);
61 ok( res
== get_parent
, "Wrong result for GetParent %p expected %p", res
, get_parent
);
62 res
= GetWindow( hwnd
, GW_OWNER
);
63 ok( res
== gw_owner
, "Wrong result for GW_OWNER %p expected %p", res
, gw_owner
);
66 res
= pGetAncestor( hwnd
, GA_ROOT
);
67 ok( res
== ga_root
, "Wrong result for GA_ROOT %p expected %p", res
, ga_root
);
68 res
= pGetAncestor( hwnd
, GA_ROOTOWNER
);
69 ok( res
== ga_root_owner
, "Wrong result for GA_ROOTOWNER %p expected %p", res
, ga_root_owner
);
74 static HWND
create_tool_window( LONG style
, HWND parent
)
76 HWND ret
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style
,
77 0, 0, 100, 100, parent
, 0, 0, NULL
);
78 ok( ret
!= 0, "Creation failed" );
82 /* test parent and owner values for various combinations */
83 static void test_parent_owner(void)
86 HWND test
, owner
, ret
;
87 HWND desktop
= GetDesktopWindow();
88 HWND child
= create_tool_window( WS_CHILD
, hwndMain
);
90 trace( "main window %p main2 %p desktop %p child %p\n", hwndMain
, hwndMain2
, desktop
, child
);
92 /* child without parent, should fail */
93 test
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
94 WS_CHILD
, 0, 0, 100, 100, 0, 0, 0, NULL
);
95 ok( !test
, "WS_CHILD without parent created" );
98 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
99 style
= GetWindowLongA( desktop
, GWL_STYLE
);
100 ok( !SetWindowLongA( desktop
, GWL_STYLE
, WS_POPUP
), "Set GWL_STYLE on desktop succeeded" );
101 ok( !SetWindowLongA( desktop
, GWL_STYLE
, 0 ), "Set GWL_STYLE on desktop succeeded" );
102 ok( GetWindowLongA( desktop
, GWL_STYLE
) == style
, "Desktop style changed" );
104 /* normal child window */
105 test
= create_tool_window( WS_CHILD
, hwndMain
);
106 trace( "created child %p\n", test
);
107 check_parents( test
, hwndMain
, hwndMain
, hwndMain
, 0, hwndMain
, hwndMain
);
108 SetWindowLongA( test
, GWL_STYLE
, 0 );
109 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
110 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
111 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
112 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
|WS_CHILD
);
113 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
114 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
115 DestroyWindow( test
);
117 /* normal child window with WS_MAXIMIZE */
118 test
= create_tool_window( WS_CHILD
| WS_MAXIMIZE
, hwndMain
);
119 DestroyWindow( test
);
121 /* normal child window with WS_THICKFRAME */
122 test
= create_tool_window( WS_CHILD
| WS_THICKFRAME
, hwndMain
);
123 DestroyWindow( test
);
125 /* popup window with WS_THICKFRAME */
126 test
= create_tool_window( WS_POPUP
| WS_THICKFRAME
, hwndMain
);
127 DestroyWindow( test
);
129 /* child of desktop */
130 test
= create_tool_window( WS_CHILD
, desktop
);
131 trace( "created child of desktop %p\n", test
);
132 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
133 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
134 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
135 SetWindowLongA( test
, GWL_STYLE
, 0 );
136 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
137 DestroyWindow( test
);
139 /* child of desktop with WS_MAXIMIZE */
140 test
= create_tool_window( WS_CHILD
| WS_MAXIMIZE
, desktop
);
141 DestroyWindow( test
);
143 /* child of desktop with WS_MINIMIZE */
144 test
= create_tool_window( WS_CHILD
| WS_MINIMIZE
, desktop
);
145 DestroyWindow( test
);
148 test
= create_tool_window( WS_CHILD
, child
);
149 trace( "created child of child %p\n", test
);
150 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
151 SetWindowLongA( test
, GWL_STYLE
, 0 );
152 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
153 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
154 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
155 DestroyWindow( test
);
157 /* child of child with WS_MAXIMIZE */
158 test
= create_tool_window( WS_CHILD
| WS_MAXIMIZE
, child
);
159 DestroyWindow( test
);
161 /* child of child with WS_MINIMIZE */
162 test
= create_tool_window( WS_CHILD
| WS_MINIMIZE
, child
);
163 DestroyWindow( test
);
165 /* not owned top-level window */
166 test
= create_tool_window( 0, 0 );
167 trace( "created top-level %p\n", test
);
168 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
169 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
170 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
171 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
172 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
173 DestroyWindow( test
);
175 /* not owned top-level window with WS_MAXIMIZE */
176 test
= create_tool_window( WS_MAXIMIZE
, 0 );
177 DestroyWindow( test
);
179 /* owned top-level window */
180 test
= create_tool_window( 0, hwndMain
);
181 trace( "created owned top-level %p\n", test
);
182 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
183 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
184 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
185 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
186 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
187 DestroyWindow( test
);
189 /* owned top-level window with WS_MAXIMIZE */
190 test
= create_tool_window( WS_MAXIMIZE
, hwndMain
);
191 DestroyWindow( test
);
193 /* not owned popup */
194 test
= create_tool_window( WS_POPUP
, 0 );
195 trace( "created popup %p\n", test
);
196 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
197 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
198 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
199 SetWindowLongA( test
, GWL_STYLE
, 0 );
200 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
201 DestroyWindow( test
);
203 /* not owned popup with WS_MAXIMIZE */
204 test
= create_tool_window( WS_POPUP
| WS_MAXIMIZE
, 0 );
205 DestroyWindow( test
);
208 test
= create_tool_window( WS_POPUP
, hwndMain
);
209 trace( "created owned popup %p\n", test
);
210 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
211 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
212 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
213 SetWindowLongA( test
, GWL_STYLE
, 0 );
214 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
215 DestroyWindow( test
);
217 /* owned popup with WS_MAXIMIZE */
218 test
= create_tool_window( WS_POPUP
| WS_MAXIMIZE
, hwndMain
);
219 DestroyWindow( test
);
221 /* top-level window owned by child (same as owned by top-level) */
222 test
= create_tool_window( 0, child
);
223 trace( "created top-level owned by child %p\n", test
);
224 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
225 DestroyWindow( test
);
227 /* top-level window owned by child (same as owned by top-level) with WS_MAXIMIZE */
228 test
= create_tool_window( WS_MAXIMIZE
, child
);
229 DestroyWindow( test
);
231 /* popup owned by desktop (same as not owned) */
232 test
= create_tool_window( WS_POPUP
, desktop
);
233 trace( "created popup owned by desktop %p\n", test
);
234 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
235 DestroyWindow( test
);
237 /* popup owned by desktop (same as not owned) with WS_MAXIMIZE */
238 test
= create_tool_window( WS_POPUP
| WS_MAXIMIZE
, desktop
);
239 DestroyWindow( test
);
241 /* popup owned by child (same as owned by top-level) */
242 test
= create_tool_window( WS_POPUP
, child
);
243 trace( "created popup owned by child %p\n", test
);
244 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
245 DestroyWindow( test
);
247 /* popup owned by child (same as owned by top-level) with WS_MAXIMIZE */
248 test
= create_tool_window( WS_POPUP
| WS_MAXIMIZE
, child
);
249 DestroyWindow( test
);
251 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
252 test
= create_tool_window( WS_POPUP
| WS_CHILD
, 0 );
253 trace( "created WS_CHILD popup %p\n", test
);
254 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
255 DestroyWindow( test
);
257 /* not owned popup with WS_CHILD | WS_MAXIMIZE (same as WS_POPUP only) */
258 test
= create_tool_window( WS_POPUP
| WS_CHILD
| WS_MAXIMIZE
, 0 );
259 DestroyWindow( test
);
261 /* owned popup with WS_CHILD (same as WS_POPUP only) */
262 test
= create_tool_window( WS_POPUP
| WS_CHILD
, hwndMain
);
263 trace( "created owned WS_CHILD popup %p\n", test
);
264 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
265 DestroyWindow( test
);
267 /* owned popup with WS_CHILD (same as WS_POPUP only) with WS_MAXIMIZE */
268 test
= create_tool_window( WS_POPUP
| WS_CHILD
| WS_MAXIMIZE
, hwndMain
);
269 DestroyWindow( test
);
271 /******************** parent changes *************************/
272 trace( "testing parent changes\n" );
275 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
276 #if 0 /* this test succeeds on NT but crashes on win9x systems */
277 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
278 ok( !ret
, "Set GWL_HWNDPARENT succeeded on desktop" );
279 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
280 ok( !SetParent( desktop
, hwndMain
), "SetParent succeeded on desktop" );
281 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
283 /* normal child window */
284 test
= create_tool_window( WS_CHILD
, hwndMain
);
285 trace( "created child %p\n", test
);
287 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
288 ok( ret
== hwndMain
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain
);
289 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
291 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
292 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
293 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
295 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)desktop
);
296 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
297 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
299 /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
300 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
301 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
302 check_parents( test
, desktop
, child
, desktop
, child
, test
, desktop
);
304 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
305 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
306 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
307 DestroyWindow( test
);
309 /* not owned top-level window */
310 test
= create_tool_window( 0, 0 );
311 trace( "created top-level %p\n", test
);
313 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
314 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
315 check_parents( test
, desktop
, hwndMain2
, 0, hwndMain2
, test
, test
);
317 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
318 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
319 check_parents( test
, desktop
, child
, 0, child
, test
, test
);
321 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
322 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
323 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
324 DestroyWindow( test
);
326 /* not owned popup */
327 test
= create_tool_window( WS_POPUP
, 0 );
328 trace( "created popup %p\n", test
);
330 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
331 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
332 check_parents( test
, desktop
, hwndMain2
, hwndMain2
, hwndMain2
, test
, hwndMain2
);
334 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
335 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
336 check_parents( test
, desktop
, child
, child
, child
, test
, hwndMain
);
338 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
339 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
340 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
341 DestroyWindow( test
);
343 /* normal child window */
344 test
= create_tool_window( WS_CHILD
, hwndMain
);
345 trace( "created child %p\n", test
);
347 ret
= SetParent( test
, desktop
);
348 ok( ret
== hwndMain
, "SetParent return value %p expected %p", ret
, hwndMain
);
349 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
351 ret
= SetParent( test
, child
);
352 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
353 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
355 ret
= SetParent( test
, hwndMain2
);
356 ok( ret
== child
, "SetParent return value %p expected %p", ret
, child
);
357 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
358 DestroyWindow( test
);
360 /* not owned top-level window */
361 test
= create_tool_window( 0, 0 );
362 trace( "created top-level %p\n", test
);
364 ret
= SetParent( test
, child
);
365 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
366 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
367 DestroyWindow( test
);
370 test
= create_tool_window( WS_POPUP
, hwndMain2
);
371 trace( "created owned popup %p\n", test
);
373 ret
= SetParent( test
, child
);
374 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
375 check_parents( test
, child
, child
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
377 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (ULONG_PTR
)hwndMain
);
378 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
379 check_parents( test
, hwndMain
, hwndMain
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
380 DestroyWindow( test
);
382 /**************** test owner destruction *******************/
384 /* owned child popup */
385 owner
= create_tool_window( 0, 0 );
386 test
= create_tool_window( WS_POPUP
, owner
);
387 trace( "created owner %p and popup %p\n", owner
, test
);
388 ret
= SetParent( test
, child
);
389 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
390 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
391 /* window is now child of 'child' but owned by 'owner' */
392 DestroyWindow( owner
);
393 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
394 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
395 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
398 /* owned top-level popup */
399 owner
= create_tool_window( 0, 0 );
400 test
= create_tool_window( WS_POPUP
, owner
);
401 trace( "created owner %p and popup %p\n", owner
, test
);
402 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
403 DestroyWindow( owner
);
404 ok( !IsWindow(test
), "Window %p not destroyed by owner destruction", test
);
406 /* top-level popup owned by child */
407 owner
= create_tool_window( WS_CHILD
, hwndMain2
);
408 test
= create_tool_window( WS_POPUP
, 0 );
409 trace( "created owner %p and popup %p\n", owner
, test
);
410 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (ULONG_PTR
)owner
);
411 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
412 check_parents( test
, desktop
, owner
, owner
, owner
, test
, hwndMain2
);
413 DestroyWindow( owner
);
414 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
415 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
416 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
420 DestroyWindow(child
);
424 static LRESULT WINAPI
main_window_procA(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
428 case WM_GETMINMAXINFO
:
430 MINMAXINFO
* minmax
= (MINMAXINFO
*)lparam
;
432 trace("hwnd %p, WM_GETMINMAXINFO, %08x, %08lx\n", hwnd
, wparam
, lparam
);
433 trace("ptReserved (%ld,%ld), ptMaxSize (%ld,%ld), ptMaxPosition (%ld,%ld)\n"
434 " ptMinTrackSize (%ld,%ld), ptMaxTrackSize (%ld,%ld)\n",
435 minmax
->ptReserved
.x
, minmax
->ptReserved
.y
,
436 minmax
->ptMaxSize
.x
, minmax
->ptMaxSize
.y
,
437 minmax
->ptMaxPosition
.x
, minmax
->ptMaxPosition
.y
,
438 minmax
->ptMinTrackSize
.x
, minmax
->ptMinTrackSize
.y
,
439 minmax
->ptMaxTrackSize
.x
, minmax
->ptMaxTrackSize
.y
);
440 SetWindowLongA(hwnd
, GWL_USERDATA
, 0x20031021);
445 BOOL got_getminmaxinfo
= GetWindowLongA(hwnd
, GWL_USERDATA
) == 0x20031021;
446 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lparam
;
448 trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd
, cs
->hwndParent
, cs
->style
);
449 if (got_getminmaxinfo
)
450 trace("%p got WM_GETMINMAXINFO\n", hwnd
);
452 if ((cs
->style
& WS_THICKFRAME
) || !(cs
->style
& (WS_POPUP
| WS_CHILD
)))
453 ok(got_getminmaxinfo
, "main: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
455 ok(!got_getminmaxinfo
, "main: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
460 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
463 static LRESULT WINAPI
tool_window_procA(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
467 case WM_GETMINMAXINFO
:
469 MINMAXINFO
* minmax
= (MINMAXINFO
*)lparam
;
471 trace("hwnd %p, WM_GETMINMAXINFO, %08x, %08lx\n", hwnd
, wparam
, lparam
);
472 trace("ptReserved (%ld,%ld), ptMaxSize (%ld,%ld), ptMaxPosition (%ld,%ld)\n"
473 " ptMinTrackSize (%ld,%ld), ptMaxTrackSize (%ld,%ld)\n",
474 minmax
->ptReserved
.x
, minmax
->ptReserved
.y
,
475 minmax
->ptMaxSize
.x
, minmax
->ptMaxSize
.y
,
476 minmax
->ptMaxPosition
.x
, minmax
->ptMaxPosition
.y
,
477 minmax
->ptMinTrackSize
.x
, minmax
->ptMinTrackSize
.y
,
478 minmax
->ptMaxTrackSize
.x
, minmax
->ptMaxTrackSize
.y
);
479 SetWindowLongA(hwnd
, GWL_USERDATA
, 0x20031021);
484 BOOL got_getminmaxinfo
= GetWindowLongA(hwnd
, GWL_USERDATA
) == 0x20031021;
485 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lparam
;
487 trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd
, cs
->hwndParent
, cs
->style
);
488 if (got_getminmaxinfo
)
489 trace("%p got WM_GETMINMAXINFO\n", hwnd
);
491 if ((cs
->style
& WS_THICKFRAME
) || !(cs
->style
& (WS_POPUP
| WS_CHILD
)))
492 ok(got_getminmaxinfo
, "tool: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
494 ok(!got_getminmaxinfo
, "tool: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
499 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
502 static BOOL
RegisterWindowClasses(void)
507 cls
.lpfnWndProc
= main_window_procA
;
510 cls
.hInstance
= GetModuleHandleA(0);
512 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
513 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
514 cls
.lpszMenuName
= NULL
;
515 cls
.lpszClassName
= "MainWindowClass";
517 if(!RegisterClassA(&cls
)) return FALSE
;
520 cls
.lpfnWndProc
= tool_window_procA
;
523 cls
.hInstance
= GetModuleHandleA(0);
525 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
526 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
527 cls
.lpszMenuName
= NULL
;
528 cls
.lpszClassName
= "ToolWindowClass";
530 if(!RegisterClassA(&cls
)) return FALSE
;
535 static LRESULT CALLBACK
cbt_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
537 static const char *CBT_code_name
[10] = {
548 const char *code_name
= (nCode
>= 0 && nCode
<= HCBT_SETFOCUS
) ? CBT_code_name
[nCode
] : "Unknown";
550 trace("CBT: %d (%s), %08x, %08lx\n", nCode
, code_name
, wParam
, lParam
);
556 CBT_CREATEWNDA
*createwnd
= (CBT_CREATEWNDA
*)lParam
;
557 trace("HCBT_CREATEWND: hwnd %p, parent %p, style %08lx\n",
558 (HWND
)wParam
, createwnd
->lpcs
->hwndParent
, createwnd
->lpcs
->style
);
559 ok(createwnd
->hwndInsertAfter
== HWND_TOP
, "hwndInsertAfter should be always HWND_TOP\n");
564 return CallNextHookEx(hhook
, nCode
, wParam
, lParam
);
567 static void test_shell_window()
571 HMODULE hinst
, hUser32
;
572 BOOL (WINAPI
*SetShellWindow
)(HWND
);
573 BOOL (WINAPI
*SetShellWindowEx
)(HWND
, HWND
);
574 HWND hwnd1
, hwnd2
, hwnd3
, hwnd4
, hwnd5
;
575 HWND shellWindow
, nextWnd
;
577 shellWindow
= GetShellWindow();
578 hinst
= GetModuleHandle(0);
579 hUser32
= GetModuleHandleA("user32");
581 SetShellWindow
= (void *)GetProcAddress(hUser32
, "SetShellWindow");
582 SetShellWindowEx
= (void *)GetProcAddress(hUser32
, "SetShellWindowEx");
584 trace("previous shell window: %p\n", shellWindow
);
590 ret
= DestroyWindow(shellWindow
);
591 error
= GetLastError();
593 ok(!ret
, "DestroyWindow(shellWindow)\n");
594 /* passes on Win XP, but not on Win98
595 ok(error==ERROR_ACCESS_DENIED, "ERROR_ACCESS_DENIED after DestroyWindow(shellWindow)\n"); */
597 /* close old shell instance */
598 GetWindowThreadProcessId(shellWindow
, &pid
);
599 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, pid
);
600 ret
= TerminateProcess(hProcess
, 0);
601 ok(ret
, "termination of previous shell process failed: GetLastError()=%ld", GetLastError());
602 WaitForSingleObject(hProcess
, INFINITE
); /* wait for termination */
603 CloseHandle(hProcess
);
606 hwnd1
= CreateWindowEx(0, TEXT("#32770"), TEXT("TEST1"), WS_OVERLAPPEDWINDOW
/*|WS_VISIBLE*/, 100, 100, 300, 200, 0, 0, hinst
, 0);
607 trace("created window 1: %p\n", hwnd1
);
609 ret
= SetShellWindow(hwnd1
);
610 ok(ret
, "first call to SetShellWindow(hwnd1)\n");
611 shellWindow
= GetShellWindow();
612 ok(shellWindow
==hwnd1
, "wrong shell window: %p", shellWindow
);
614 ret
= SetShellWindow(hwnd1
);
615 ok(!ret
, "second call to SetShellWindow(hwnd1)\n");
617 ret
= SetShellWindow(0);
618 error
= GetLastError();
619 /* passes on Win XP, but not on Win98
620 ok(!ret, "reset shell window by SetShellWindow(0)\n");
621 ok(error==ERROR_INVALID_WINDOW_HANDLE, "ERROR_INVALID_WINDOW_HANDLE after SetShellWindow(0)\n"); */
623 ret
= SetShellWindow(hwnd1
);
624 /* passes on Win XP, but not on Win98
625 ok(!ret, "third call to SetShellWindow(hwnd1)\n"); */
629 SetWindowLong(hwnd1
, GWL_EXSTYLE
, GetWindowLong(hwnd1
,GWL_EXSTYLE
)|WS_EX_TOPMOST
);
630 ret
= GetWindowLong(hwnd1
,GWL_EXSTYLE
)&WS_EX_TOPMOST
? TRUE
: FALSE
;
631 ok(!ret
, "SetWindowExStyle(hwnd1, WS_EX_TOPMOST)\n");
634 ret
= DestroyWindow(hwnd1
);
635 ok(ret
, "DestroyWindow(hwnd1)\n");
637 hwnd2
= CreateWindowEx(WS_EX_TOPMOST
, TEXT("#32770"), TEXT("TEST2"), WS_OVERLAPPEDWINDOW
/*|WS_VISIBLE*/, 150, 250, 300, 200, 0, 0, hinst
, 0);
638 trace("created window 2: %p\n", hwnd2
);
639 ret
= SetShellWindow(hwnd2
);
640 ok(!ret
, "SetShellWindow(hwnd2) with WS_EX_TOPMOST");
642 hwnd3
= CreateWindowEx(0, TEXT("#32770"), TEXT("TEST3"), WS_OVERLAPPEDWINDOW
/*|WS_VISIBLE*/, 200, 400, 300, 200, 0, 0, hinst
, 0);
643 trace("created window 3: %p\n", hwnd3
);
645 hwnd4
= CreateWindowEx(0, TEXT("#32770"), TEXT("TEST4"), WS_OVERLAPPEDWINDOW
/*|WS_VISIBLE*/, 250, 500, 300, 200, 0, 0, hinst
, 0);
646 trace("created window 4: %p\n", hwnd4
);
648 nextWnd
= GetWindow(hwnd4
, GW_HWNDNEXT
);
649 ok(nextWnd
==hwnd3
, "wrong next window for hwnd4: %p - expected hwnd3\n", nextWnd
);
651 ret
= SetShellWindow(hwnd4
);
652 ok(ret
, "SetShellWindow(hwnd4)\n");
653 shellWindow
= GetShellWindow();
654 ok(shellWindow
==hwnd4
, "wrong shell window: %p - expected hwnd4", shellWindow
);
656 nextWnd
= GetWindow(hwnd4
, GW_HWNDNEXT
);
657 ok(nextWnd
==0, "wrong next window for hwnd4: %p - expected 0\n", nextWnd
);
659 ret
= SetWindowPos(hwnd4
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOSIZE
|SWP_NOMOVE
);
660 ok(ret
, "SetWindowPos(hwnd4, HWND_TOPMOST)\n");
662 ret
= SetWindowPos(hwnd4
, hwnd3
, 0, 0, 0, 0, SWP_NOSIZE
|SWP_NOMOVE
);
663 ok(ret
, "SetWindowPos(hwnd4, hwnd3");
665 ret
= SetShellWindow(hwnd3
);
666 ok(!ret
, "SetShellWindow(hwnd3)\n");
667 shellWindow
= GetShellWindow();
668 ok(shellWindow
==hwnd4
, "wrong shell window: %p - expected hwnd4", shellWindow
);
670 hwnd5
= CreateWindowEx(0, TEXT("#32770"), TEXT("TEST5"), WS_OVERLAPPEDWINDOW
/*|WS_VISIBLE*/, 300, 600, 300, 200, 0, 0, hinst
, 0);
671 trace("created window 5: %p\n", hwnd5
);
672 ret
= SetWindowPos(hwnd4
, hwnd5
, 0, 0, 0, 0, SWP_NOSIZE
|SWP_NOMOVE
);
673 ok(ret
, "SetWindowPos(hwnd4, hwnd5)\n");
677 nextWnd
= GetWindow(hwnd4
, GW_HWNDNEXT
);
678 ok(nextWnd
==0, "wrong next window for hwnd4 after SetWindowPos(): %p - expected 0\n", nextWnd
);
681 /* destroy test windows */
682 DestroyWindow(hwnd2
);
683 DestroyWindow(hwnd3
);
684 DestroyWindow(hwnd4
);
685 DestroyWindow(hwnd5
);
688 /************** MDI test ****************/
690 static const char mdi_lParam_test_message
[] = "just a test string";
692 static void test_MDI_create(HWND parent
, HWND mdi_client
)
694 MDICREATESTRUCTA mdi_cs
;
697 mdi_cs
.szClass
= "MDI_child_Class_1";
698 mdi_cs
.szTitle
= "MDI child 1";
699 mdi_cs
.hOwner
= GetModuleHandle(0);
702 mdi_cs
.cx
= CW_USEDEFAULT
;
703 mdi_cs
.cy
= CW_USEDEFAULT
;
704 mdi_cs
.style
= WS_CAPTION
| WS_CHILD
/*| WS_VISIBLE*/;
705 mdi_cs
.lParam
= (LPARAM
)mdi_lParam_test_message
;
706 mdi_child
= (HWND
)SendMessageA(mdi_client
, WM_MDICREATE
, 0, (LPARAM
)&mdi_cs
);
708 DestroyWindow(mdi_child
);
710 mdi_child
= CreateMDIWindowA("MDI_child_Class_1", "MDI child 2",
711 WS_CAPTION
| WS_CHILD
/*| WS_VISIBLE*/,
712 10, 10, CW_USEDEFAULT
, CW_USEDEFAULT
,
713 mdi_client
, GetModuleHandle(0),
714 (LPARAM
)mdi_lParam_test_message
);
716 DestroyWindow(mdi_child
);
718 mdi_child
= CreateWindowExA(0, "MDI_child_Class_2", "MDI child 3",
719 WS_CAPTION
| WS_CHILD
/*| WS_VISIBLE*/,
720 20, 20, CW_USEDEFAULT
, CW_USEDEFAULT
,
721 mdi_client
, 0, GetModuleHandle(0),
722 (LPVOID
)mdi_lParam_test_message
);
724 DestroyWindow(mdi_child
);
727 static LRESULT WINAPI
mdi_child_wnd_proc_1(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
733 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lparam
;
734 MDICREATESTRUCTA
*mdi_cs
= (MDICREATESTRUCTA
*)cs
->lpCreateParams
;
736 todo_wine
/* apparently Windows has a common code for MDI and other windows */
738 ok(cs
->dwExStyle
& WS_EX_MDICHILD
, "WS_EX_MDICHILD should be set\n");
740 ok(mdi_cs
->lParam
== (LPARAM
)mdi_lParam_test_message
, "wrong mdi_cs->lParam\n");
744 return DefMDIChildProcA(hwnd
, msg
, wparam
, lparam
);
747 static LRESULT WINAPI
mdi_child_wnd_proc_2(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
753 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lparam
;
755 ok(!(cs
->dwExStyle
& WS_EX_MDICHILD
), "WS_EX_MDICHILD should not be set\n");
756 ok(cs
->lpCreateParams
== mdi_lParam_test_message
, "wrong cs->lpCreateParams\n");
760 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
763 static LRESULT WINAPI
mdi_main_wnd_procA(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
765 static HWND mdi_client
;
771 CLIENTCREATESTRUCT client_cs
;
774 GetClientRect(hwnd
, &rc
);
776 client_cs
.hWindowMenu
= 0;
777 client_cs
.idFirstChild
= 1;
779 mdi_client
= CreateWindowExA(0, "mdiclient",
781 WS_CHILD
| WS_CLIPCHILDREN
/*| WS_VISIBLE*/,
782 0, 0, rc
.right
, rc
.bottom
,
783 hwnd
, 0, GetModuleHandle(0),
787 test_MDI_create(hwnd
, mdi_client
);
795 return DefFrameProcA(hwnd
, mdi_client
, msg
, wparam
, lparam
);
798 static BOOL
mdi_RegisterWindowClasses(void)
803 cls
.lpfnWndProc
= mdi_main_wnd_procA
;
806 cls
.hInstance
= GetModuleHandleA(0);
808 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
809 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
810 cls
.lpszMenuName
= NULL
;
811 cls
.lpszClassName
= "MDI_parent_Class";
812 if(!RegisterClassA(&cls
)) return FALSE
;
814 cls
.lpfnWndProc
= mdi_child_wnd_proc_1
;
815 cls
.lpszClassName
= "MDI_child_Class_1";
816 if(!RegisterClassA(&cls
)) return FALSE
;
818 cls
.lpfnWndProc
= mdi_child_wnd_proc_2
;
819 cls
.lpszClassName
= "MDI_child_Class_2";
820 if(!RegisterClassA(&cls
)) return FALSE
;
825 static void test_mdi(void)
830 if (!mdi_RegisterWindowClasses()) assert(0);
832 mdi_hwndMain
= CreateWindowExA(0, "MDI_parent_Class", "MDI parent window",
833 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
834 WS_MAXIMIZEBOX
/*| WS_VISIBLE*/,
835 100, 100, CW_USEDEFAULT
, CW_USEDEFAULT
,
836 GetDesktopWindow(), 0,
837 GetModuleHandle(0), NULL
);
838 assert(mdi_hwndMain
);
840 while(GetMessage(&msg, 0, 0, 0))
842 TranslateMessage(&msg);
843 DispatchMessage(&msg);
848 static void test_icons(void)
852 HICON icon
= LoadIconA(0, (LPSTR
)IDI_APPLICATION
);
853 HICON icon2
= LoadIconA(0, (LPSTR
)IDI_QUESTION
);
854 HICON small_icon
= LoadImageA(0, (LPSTR
)IDI_APPLICATION
, IMAGE_ICON
,
855 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_SHARED
);
858 cls
.cbSize
= sizeof(cls
);
860 cls
.lpfnWndProc
= DefWindowProcA
;
864 cls
.hIcon
= LoadIconA(0, (LPSTR
)IDI_HAND
);
865 cls
.hIconSm
= small_icon
;
866 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
867 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
868 cls
.lpszMenuName
= NULL
;
869 cls
.lpszClassName
= "IconWindowClass";
871 RegisterClassExA(&cls
);
873 hwnd
= CreateWindowExA(0, "IconWindowClass", "icon test", 0,
874 100, 100, CW_USEDEFAULT
, CW_USEDEFAULT
, 0, 0, NULL
, NULL
);
877 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_BIG
, 0 );
878 ok( res
== 0, "wrong big icon %p/0\n", res
);
879 res
= (HICON
)SendMessageA( hwnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)icon
);
880 ok( res
== 0, "wrong previous big icon %p/0\n", res
);
881 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_BIG
, 0 );
882 ok( res
== icon
, "wrong big icon after set %p/%p\n", res
, icon
);
883 res
= (HICON
)SendMessageA( hwnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)icon2
);
884 ok( res
== icon
, "wrong previous big icon %p/%p\n", res
, icon
);
885 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_BIG
, 0 );
886 ok( res
== icon2
, "wrong big icon after set %p/%p\n", res
, icon2
);
888 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL
, 0 );
889 ok( res
== 0, "wrong small icon %p/0\n", res
);
890 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL2
, 0 );
891 ok( res
!= 0, "wrong small icon %p\n", res
);
892 res
= (HICON
)SendMessageA( hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)icon
);
893 ok( res
== 0, "wrong previous small icon %p/0\n", res
);
894 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL
, 0 );
895 ok( res
== icon
, "wrong small icon after set %p/%p\n", res
, icon
);
896 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL2
, 0 );
897 ok( res
== icon
, "wrong small icon after set %p/%p\n", res
, icon
);
898 res
= (HICON
)SendMessageA( hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)small_icon
);
899 ok( res
== icon
, "wrong previous small icon %p/%p\n", res
, icon
);
900 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL
, 0 );
901 ok( res
== small_icon
, "wrong small icon after set %p/%p\n", res
, small_icon
);
902 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_SMALL2
, 0 );
903 ok( res
== small_icon
, "wrong small icon after set %p/%p\n", res
, small_icon
);
905 /* make sure the big icon hasn't changed */
906 res
= (HICON
)SendMessageA( hwnd
, WM_GETICON
, ICON_BIG
, 0 );
907 ok( res
== icon2
, "wrong big icon after set %p/%p\n", res
, icon2
);
912 pGetAncestor
= (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
914 if (!RegisterWindowClasses()) assert(0);
916 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, GetCurrentThreadId());
919 hwndMain
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
920 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
921 WS_MAXIMIZEBOX
| WS_POPUP
,
924 hwndMain2
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
925 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
926 WS_MAXIMIZEBOX
| WS_POPUP
,
938 UnhookWindowsHookEx(hhook
);