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
32 #include "wine/test.h"
35 # define IDC_ARROWA IDC_ARROW
38 #ifndef SPI_GETDESKWALLPAPER
39 #define SPI_GETDESKWALLPAPER 0x0073
42 #define LONG_PTR INT_PTR
43 #define ULONG_PTR UINT_PTR
45 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
47 static HWND hwndMain
, hwndMain2
;
49 /* check the values returned by the various parent/owner functions on a given window */
50 static void check_parents( HWND hwnd
, HWND ga_parent
, HWND gwl_parent
, HWND get_parent
,
51 HWND gw_owner
, HWND ga_root
, HWND ga_root_owner
)
57 res
= pGetAncestor( hwnd
, GA_PARENT
);
58 ok( res
== ga_parent
, "Wrong result for GA_PARENT %p expected %p", res
, ga_parent
);
60 res
= (HWND
)GetWindowLongA( hwnd
, GWL_HWNDPARENT
);
61 ok( res
== gwl_parent
, "Wrong result for GWL_HWNDPARENT %p expected %p", res
, gwl_parent
);
62 res
= GetParent( hwnd
);
63 ok( res
== get_parent
, "Wrong result for GetParent %p expected %p", res
, get_parent
);
64 res
= GetWindow( hwnd
, GW_OWNER
);
65 ok( res
== gw_owner
, "Wrong result for GW_OWNER %p expected %p", res
, gw_owner
);
68 res
= pGetAncestor( hwnd
, GA_ROOT
);
69 ok( res
== ga_root
, "Wrong result for GA_ROOT %p expected %p", res
, ga_root
);
70 res
= pGetAncestor( hwnd
, GA_ROOTOWNER
);
71 ok( res
== ga_root_owner
, "Wrong result for GA_ROOTOWNER %p expected %p", res
, ga_root_owner
);
76 static HWND
create_tool_window( LONG style
, HWND parent
)
78 HWND ret
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style
,
79 0, 0, 100, 100, parent
, 0, 0, NULL
);
80 ok( ret
!= 0, "Creation failed" );
84 /* test parent and owner values for various combinations */
85 static void test_parent_owner(void)
88 HWND test
, owner
, ret
;
89 HWND desktop
= GetDesktopWindow();
90 HWND child
= create_tool_window( WS_CHILD
, hwndMain
);
92 trace( "main window %p main2 %p desktop %p child %p\n", hwndMain
, hwndMain2
, desktop
, child
);
94 /* child without parent, should fail */
95 test
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
96 WS_CHILD
, 0, 0, 100, 100, 0, 0, 0, NULL
);
97 ok( !test
, "WS_CHILD without parent created" );
100 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
101 style
= GetWindowLongA( desktop
, GWL_STYLE
);
102 ok( !SetWindowLongA( desktop
, GWL_STYLE
, WS_POPUP
), "Set GWL_STYLE on desktop succeeded" );
103 ok( !SetWindowLongA( desktop
, GWL_STYLE
, 0 ), "Set GWL_STYLE on desktop succeeded" );
104 ok( GetWindowLongA( desktop
, GWL_STYLE
) == style
, "Desktop style changed" );
106 /* normal child window */
107 test
= create_tool_window( WS_CHILD
, hwndMain
);
108 trace( "created child %p\n", test
);
109 check_parents( test
, hwndMain
, hwndMain
, hwndMain
, 0, hwndMain
, hwndMain
);
110 SetWindowLongA( test
, GWL_STYLE
, 0 );
111 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
112 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
113 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
114 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
|WS_CHILD
);
115 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
116 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
117 DestroyWindow( test
);
119 /* child of desktop */
120 test
= create_tool_window( WS_CHILD
, desktop
);
121 trace( "created child of desktop %p\n", test
);
122 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
123 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
124 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
125 SetWindowLongA( test
, GWL_STYLE
, 0 );
126 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
127 DestroyWindow( test
);
130 test
= create_tool_window( WS_CHILD
, child
);
131 trace( "created child of child %p\n", test
);
132 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
133 SetWindowLongA( test
, GWL_STYLE
, 0 );
134 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
135 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
136 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
137 DestroyWindow( test
);
139 /* not owned top-level window */
140 test
= create_tool_window( 0, 0 );
141 trace( "created top-level %p\n", test
);
142 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
143 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
144 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
145 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
146 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
147 DestroyWindow( test
);
149 /* owned top-level window */
150 test
= create_tool_window( 0, hwndMain
);
151 trace( "created owned top-level %p\n", test
);
152 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
153 SetWindowLongA( test
, GWL_STYLE
, WS_POPUP
);
154 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
155 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
156 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
157 DestroyWindow( test
);
159 /* not owned popup */
160 test
= create_tool_window( WS_POPUP
, 0 );
161 trace( "created popup %p\n", test
);
162 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
163 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
164 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
165 SetWindowLongA( test
, GWL_STYLE
, 0 );
166 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
167 DestroyWindow( test
);
170 test
= create_tool_window( WS_POPUP
, hwndMain
);
171 trace( "created owned popup %p\n", test
);
172 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
173 SetWindowLongA( test
, GWL_STYLE
, WS_CHILD
);
174 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
175 SetWindowLongA( test
, GWL_STYLE
, 0 );
176 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
177 DestroyWindow( test
);
179 /* top-level window owned by child (same as owned by top-level) */
180 test
= create_tool_window( 0, child
);
181 trace( "created top-level owned by child %p\n", test
);
182 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
183 DestroyWindow( test
);
185 /* popup owned by desktop (same as not owned) */
186 test
= create_tool_window( WS_POPUP
, desktop
);
187 trace( "created popup owned by desktop %p\n", test
);
188 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
189 DestroyWindow( test
);
191 /* popup owned by child (same as owned by top-level) */
192 test
= create_tool_window( WS_POPUP
, child
);
193 trace( "created popup owned by child %p\n", test
);
194 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
195 DestroyWindow( test
);
197 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
198 test
= create_tool_window( WS_POPUP
| WS_CHILD
, 0 );
199 trace( "created WS_CHILD popup %p\n", test
);
200 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
201 DestroyWindow( test
);
203 /* owned popup with WS_CHILD (same as WS_POPUP only) */
204 test
= create_tool_window( WS_POPUP
| WS_CHILD
, hwndMain
);
205 trace( "created owned WS_CHILD popup %p\n", test
);
206 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
207 DestroyWindow( test
);
209 /******************** parent changes *************************/
210 trace( "testing parent changes\n" );
213 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
214 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
215 ok( !ret
, "Set GWL_HWNDPARENT succeeded on desktop" );
216 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
217 ok( !SetParent( desktop
, hwndMain
), "SetParent succeeded on desktop" );
218 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
220 /* normal child window */
221 test
= create_tool_window( WS_CHILD
, hwndMain
);
222 trace( "created child %p\n", test
);
224 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
225 ok( ret
== hwndMain
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain
);
226 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
228 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
229 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
230 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
232 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)desktop
);
233 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
234 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
236 /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
237 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
238 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
239 check_parents( test
, desktop
, child
, desktop
, child
, test
, desktop
);
241 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
242 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
243 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
244 DestroyWindow( test
);
246 /* not owned top-level window */
247 test
= create_tool_window( 0, 0 );
248 trace( "created top-level %p\n", test
);
250 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
251 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
252 check_parents( test
, desktop
, hwndMain2
, 0, hwndMain2
, test
, test
);
254 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
255 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
256 check_parents( test
, desktop
, child
, 0, child
, test
, test
);
258 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
259 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
260 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
261 DestroyWindow( test
);
263 /* not owned popup */
264 test
= create_tool_window( WS_POPUP
, 0 );
265 trace( "created popup %p\n", test
);
267 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
268 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
269 check_parents( test
, desktop
, hwndMain2
, hwndMain2
, hwndMain2
, test
, hwndMain2
);
271 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
272 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %p expected %p", ret
, hwndMain2
);
273 check_parents( test
, desktop
, child
, child
, child
, test
, hwndMain
);
275 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, 0 );
276 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
277 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
278 DestroyWindow( test
);
280 /* normal child window */
281 test
= create_tool_window( WS_CHILD
, hwndMain
);
282 trace( "created child %p\n", test
);
284 ret
= SetParent( test
, desktop
);
285 ok( ret
== hwndMain
, "SetParent return value %p expected %p", ret
, hwndMain
);
286 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
288 ret
= SetParent( test
, child
);
289 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
290 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
292 ret
= SetParent( test
, hwndMain2
);
293 ok( ret
== child
, "SetParent return value %p expected %p", ret
, child
);
294 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
295 DestroyWindow( test
);
297 /* not owned top-level window */
298 test
= create_tool_window( 0, 0 );
299 trace( "created top-level %p\n", test
);
301 ret
= SetParent( test
, child
);
302 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
303 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
304 DestroyWindow( test
);
307 test
= create_tool_window( WS_POPUP
, hwndMain2
);
308 trace( "created owned popup %p\n", test
);
310 ret
= SetParent( test
, child
);
311 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
312 check_parents( test
, child
, child
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
314 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (ULONG_PTR
)hwndMain
);
315 ok( ret
== child
, "GWL_HWNDPARENT return value %p expected %p", ret
, child
);
316 check_parents( test
, hwndMain
, hwndMain
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
317 DestroyWindow( test
);
319 /**************** test owner destruction *******************/
321 /* owned child popup */
322 owner
= create_tool_window( 0, 0 );
323 test
= create_tool_window( WS_POPUP
, owner
);
324 trace( "created owner %p and popup %p\n", owner
, test
);
325 ret
= SetParent( test
, child
);
326 ok( ret
== desktop
, "SetParent return value %p expected %p", ret
, desktop
);
327 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
328 /* window is now child of 'child' but owned by 'owner' */
329 DestroyWindow( owner
);
330 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
331 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
332 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
335 /* owned top-level popup */
336 owner
= create_tool_window( 0, 0 );
337 test
= create_tool_window( WS_POPUP
, owner
);
338 trace( "created owner %p and popup %p\n", owner
, test
);
339 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
340 DestroyWindow( owner
);
341 ok( !IsWindow(test
), "Window %p not destroyed by owner destruction", test
);
343 /* top-level popup owned by child */
344 owner
= create_tool_window( WS_CHILD
, hwndMain2
);
345 test
= create_tool_window( WS_POPUP
, 0 );
346 trace( "created owner %p and popup %p\n", owner
, test
);
347 ret
= (HWND
)SetWindowLongA( test
, GWL_HWNDPARENT
, (ULONG_PTR
)owner
);
348 ok( ret
== 0, "GWL_HWNDPARENT return value %p expected 0", ret
);
349 check_parents( test
, desktop
, owner
, owner
, owner
, test
, hwndMain2
);
350 DestroyWindow( owner
);
351 ok( IsWindow(test
), "Window %p destroyed by owner destruction", test
);
352 ok( !IsWindow(owner
), "Owner %p not destroyed", owner
);
353 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
357 DestroyWindow(child
);
361 static BOOL
RegisterWindowClasses(void)
366 cls
.lpfnWndProc
= DefWindowProcA
;
369 cls
.hInstance
= GetModuleHandleA(0);
371 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
372 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
373 cls
.lpszMenuName
= NULL
;
374 cls
.lpszClassName
= "MainWindowClass";
376 if(!RegisterClassA(&cls
)) return FALSE
;
379 cls
.lpfnWndProc
= DefWindowProcA
;
382 cls
.hInstance
= GetModuleHandleA(0);
384 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
385 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
386 cls
.lpszMenuName
= NULL
;
387 cls
.lpszClassName
= "ToolWindowClass";
389 if(!RegisterClassA(&cls
)) return FALSE
;
397 pGetAncestor
= (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
399 if (!RegisterWindowClasses()) assert(0);
401 hwndMain
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
402 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
403 WS_MAXIMIZEBOX
| WS_POPUP
,
406 hwndMain2
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
407 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
408 WS_MAXIMIZEBOX
| WS_POPUP
,