2 * Unit tests for window handling
4 * Copyright 2002 Bill Medland
5 * Copyright 2002 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/test.h"
33 # define IDC_ARROWA IDC_ARROW
36 #ifndef SPI_GETDESKWALLPAPER
37 #define SPI_GETDESKWALLPAPER 0x0073
40 #define LONG_PTR INT_PTR
41 #define ULONG_PTR UINT_PTR
43 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
45 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
)GetWindowLongW( 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
= GetWindowLongW( desktop
, GWL_STYLE
);
100 ok( !SetWindowLongW( desktop
, GWL_STYLE
, WS_POPUP
), "Set GWL_STYLE on desktop succeeded" );
101 ok( !SetWindowLongW( desktop
, GWL_STYLE
, 0 ), "Set GWL_STYLE on desktop succeeded" );
102 ok( GetWindowLongW( 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 SetWindowLongW( test
, GWL_STYLE
, 0 );
109 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
110 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
111 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
112 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
|WS_CHILD
);
113 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
114 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
115 DestroyWindow( test
);
117 /* child of desktop */
118 test
= create_tool_window( WS_CHILD
, desktop
);
119 trace( "created child of desktop %p\n", test
);
120 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
121 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
122 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
123 SetWindowLongW( test
, GWL_STYLE
, 0 );
124 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
125 DestroyWindow( test
);
128 test
= create_tool_window( WS_CHILD
, child
);
129 trace( "created child of child %p\n", test
);
130 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
131 SetWindowLongW( test
, GWL_STYLE
, 0 );
132 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
133 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
134 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
135 DestroyWindow( test
);
137 /* not owned top-level window */
138 test
= create_tool_window( 0, 0 );
139 trace( "created top-level %p\n", test
);
140 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
141 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
142 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
143 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
144 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
145 DestroyWindow( test
);
147 /* owned top-level window */
148 test
= create_tool_window( 0, hwndMain
);
149 trace( "created owned top-level %p\n", test
);
150 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
151 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
152 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
153 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
154 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
155 DestroyWindow( test
);
157 /* not owned popup */
158 test
= create_tool_window( WS_POPUP
, 0 );
159 trace( "created popup %p\n", test
);
160 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
161 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
162 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
163 SetWindowLongW( test
, GWL_STYLE
, 0 );
164 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
165 DestroyWindow( test
);
168 test
= create_tool_window( WS_POPUP
, hwndMain
);
169 trace( "created owned popup %p\n", test
);
170 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
171 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
172 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
173 SetWindowLongW( test
, GWL_STYLE
, 0 );
174 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
175 DestroyWindow( test
);
177 /* top-level window owned by child (same as owned by top-level) */
178 test
= create_tool_window( 0, child
);
179 trace( "created top-level owned by child %p\n", test
);
180 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
181 DestroyWindow( test
);
183 /* popup owned by desktop (same as not owned) */
184 test
= create_tool_window( WS_POPUP
, desktop
);
185 trace( "created popup owned by desktop %p\n", test
);
186 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
187 DestroyWindow( test
);
189 /* popup owned by child (same as owned by top-level) */
190 test
= create_tool_window( WS_POPUP
, child
);
191 trace( "created popup owned by child %p\n", test
);
192 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
193 DestroyWindow( test
);
195 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
196 test
= create_tool_window( WS_POPUP
| WS_CHILD
, 0 );
197 trace( "created WS_CHILD popup %p\n", test
);
198 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
199 DestroyWindow( test
);
201 /* owned popup with WS_CHILD (same as WS_POPUP only) */
202 test
= create_tool_window( WS_POPUP
| WS_CHILD
, hwndMain
);
203 trace( "created owned WS_CHILD popup %p\n", test
);
204 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
205 DestroyWindow( test
);
207 /******************** parent changes *************************/
208 trace( "testing parent changes\n" );
211 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
212 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
213 ok( !ret
, "Set GWL_HWNDPARENT succeeded on desktop" );
214 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
215 ok( !SetParent( desktop
, hwndMain
), "SetParent succeeded on desktop" );
216 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
218 /* normal child window */
219 test
= create_tool_window( WS_CHILD
, hwndMain
);
220 trace( "created child %p\n", test
);
222 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
223 ok( ret
== hwndMain
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain
);
224 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
226 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
227 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
228 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
230 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)desktop
);
231 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
232 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
234 /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
235 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
236 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
237 check_parents( test
, desktop
, child
, desktop
, child
, test
, desktop
);
239 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
240 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
241 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
242 DestroyWindow( test
);
244 /* not owned top-level window */
245 test
= create_tool_window( 0, 0 );
246 trace( "created top-level %p\n", test
);
248 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
249 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
250 check_parents( test
, desktop
, hwndMain2
, 0, hwndMain2
, test
, test
);
252 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
253 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
254 check_parents( test
, desktop
, child
, 0, child
, test
, test
);
256 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
257 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
258 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
259 DestroyWindow( test
);
261 /* not owned popup */
262 test
= create_tool_window( WS_POPUP
, 0 );
263 trace( "created popup %p\n", test
);
265 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
266 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
267 check_parents( test
, desktop
, hwndMain2
, hwndMain2
, hwndMain2
, test
, hwndMain2
);
269 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
270 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
271 check_parents( test
, desktop
, child
, child
, child
, test
, hwndMain
);
273 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
274 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
275 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
276 DestroyWindow( test
);
278 /* normal child window */
279 test
= create_tool_window( WS_CHILD
, hwndMain
);
280 trace( "created child %p\n", test
);
282 ret
= SetParent( test
, desktop
);
283 ok( ret
== hwndMain
, "SetParent return value %p expected %p", ret
, hwndMain
);
284 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
286 ret
= SetParent( test
, child
);
287 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
288 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
290 ret
= SetParent( test
, hwndMain2
);
291 ok( ret
== child
, "SetParent return value %p expected %p", ret
, child
);
292 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
293 DestroyWindow( test
);
295 /* not owned top-level window */
296 test
= create_tool_window( 0, 0 );
297 trace( "created top-level %p\n", test
);
299 ret
= SetParent( test
, child
);
300 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
301 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
302 DestroyWindow( test
);
305 test
= create_tool_window( WS_POPUP
, hwndMain2
);
306 trace( "created owned popup %p\n", test
);
308 ret
= SetParent( test
, child
);
309 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
310 check_parents( test
, child
, child
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
312 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (ULONG_PTR
)hwndMain
);
313 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
314 check_parents( test
, hwndMain
, hwndMain
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
315 DestroyWindow( test
);
317 /**************** test owner destruction *******************/
319 /* owned child popup */
320 owner
= create_tool_window( 0, 0 );
321 test
= create_tool_window( WS_POPUP
, owner
);
322 trace( "created owner %p and popup %p\n", owner
, test
);
323 ret
= SetParent( test
, child
);
324 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
325 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
326 /* window is now child of 'child' but owned by 'owner' */
327 DestroyWindow( owner
);
328 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
329 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
330 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
333 /* owned top-level popup */
334 owner
= create_tool_window( 0, 0 );
335 test
= create_tool_window( WS_POPUP
, owner
);
336 trace( "created owner %p and popup %p\n", owner
, test
);
337 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
338 DestroyWindow( owner
);
339 ok( !IsWindow(test
), "Window %p not destroyed by owner destruction", test
);
341 /* top-level popup owned by child */
342 owner
= create_tool_window( WS_CHILD
, hwndMain2
);
343 test
= create_tool_window( WS_POPUP
, 0 );
344 trace( "created owner %p and popup %p\n", owner
, test
);
345 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (ULONG_PTR
)owner
);
346 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
347 check_parents( test
, desktop
, owner
, owner
, owner
, test
, hwndMain2
);
348 DestroyWindow( owner
);
349 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
350 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
351 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
355 DestroyWindow(child
);
359 static BOOL
RegisterWindowClasses(void)
364 cls
.lpfnWndProc
= DefWindowProcA
;
367 cls
.hInstance
= GetModuleHandleA(0);
369 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
370 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
371 cls
.lpszMenuName
= NULL
;
372 cls
.lpszClassName
= "MainWindowClass";
374 if(!RegisterClassA(&cls
)) return FALSE
;
377 cls
.lpfnWndProc
= DefWindowProcA
;
380 cls
.hInstance
= GetModuleHandleA(0);
382 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
383 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
384 cls
.lpszMenuName
= NULL
;
385 cls
.lpszClassName
= "ToolWindowClass";
387 if(!RegisterClassA(&cls
)) return FALSE
;
395 pGetAncestor
= (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
397 if (!RegisterWindowClasses()) assert(0);
399 hwndMain
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
400 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
401 WS_MAXIMIZEBOX
| WS_POPUP
,
404 hwndMain2
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
405 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
406 WS_MAXIMIZEBOX
| WS_POPUP
,