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
26 #include "wine/test.h"
31 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
33 static HWND hwndMain
, hwndMain2
;
35 /* check the values returned by the various parent/owner functions on a given window */
36 static void check_parents( HWND hwnd
, HWND ga_parent
, HWND gwl_parent
, HWND get_parent
,
37 HWND gw_owner
, HWND ga_root
, HWND ga_root_owner
)
43 res
= pGetAncestor( hwnd
, GA_PARENT
);
44 ok( res
== ga_parent
, "Wrong result for GA_PARENT %x expected %x", res
, ga_parent
);
46 res
= (HWND
)GetWindowLongW( hwnd
, GWL_HWNDPARENT
);
47 ok( res
== gwl_parent
, "Wrong result for GWL_HWNDPARENT %x expected %x", res
, gwl_parent
);
48 res
= GetParent( hwnd
);
49 ok( res
== get_parent
, "Wrong result for GetParent %x expected %x", res
, get_parent
);
50 res
= GetWindow( hwnd
, GW_OWNER
);
51 ok( res
== gw_owner
, "Wrong result for GW_OWNER %x expected %x", res
, gw_owner
);
54 res
= pGetAncestor( hwnd
, GA_ROOT
);
55 ok( res
== ga_root
, "Wrong result for GA_ROOT %x expected %x", res
, ga_root
);
56 res
= pGetAncestor( hwnd
, GA_ROOTOWNER
);
57 ok( res
== ga_root_owner
, "Wrong result for GA_ROOTOWNER %x expected %x", res
, ga_root_owner
);
62 static HWND
create_tool_window( LONG style
, HWND parent
)
64 HWND ret
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style
,
65 0, 0, 100, 100, parent
, 0, 0, NULL
);
66 ok( ret
!= 0, "Creation failed" );
70 /* test parent and owner values for various combinations */
71 static void test_parent_owner(void)
74 HWND test
, owner
, ret
;
75 HWND desktop
= GetDesktopWindow();
76 HWND child
= create_tool_window( WS_CHILD
, hwndMain
);
78 trace( "main window %x main2 %x desktop %x child %x\n", hwndMain
, hwndMain2
, desktop
, child
);
80 /* child without parent, should fail */
81 test
= CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
82 WS_CHILD
, 0, 0, 100, 100, 0, 0, 0, NULL
);
83 ok( !test
, "WS_CHILD without parent created" );
86 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
87 style
= GetWindowLongW( desktop
, GWL_STYLE
);
88 ok( !SetWindowLongW( desktop
, GWL_STYLE
, WS_POPUP
), "Set GWL_STYLE on desktop succeeded" );
89 ok( !SetWindowLongW( desktop
, GWL_STYLE
, 0 ), "Set GWL_STYLE on desktop succeeded" );
90 ok( GetWindowLongW( desktop
, GWL_STYLE
) == style
, "Desktop style changed" );
92 /* normal child window */
93 test
= create_tool_window( WS_CHILD
, hwndMain
);
94 trace( "created child %x\n", test
);
95 check_parents( test
, hwndMain
, hwndMain
, hwndMain
, 0, hwndMain
, hwndMain
);
96 SetWindowLongW( test
, GWL_STYLE
, 0 );
97 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
98 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
99 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
100 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
|WS_CHILD
);
101 check_parents( test
, hwndMain
, hwndMain
, 0, 0, hwndMain
, test
);
102 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
103 DestroyWindow( test
);
105 /* child of desktop */
106 test
= create_tool_window( WS_CHILD
, desktop
);
107 trace( "created child of desktop %x\n", test
);
108 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
109 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
110 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
111 SetWindowLongW( test
, GWL_STYLE
, 0 );
112 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
113 DestroyWindow( test
);
116 test
= create_tool_window( WS_CHILD
, child
);
117 trace( "created child of child %x\n", test
);
118 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
119 SetWindowLongW( test
, GWL_STYLE
, 0 );
120 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
121 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
122 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
123 DestroyWindow( test
);
125 /* not owned top-level window */
126 test
= create_tool_window( 0, 0 );
127 trace( "created top-level %x\n", test
);
128 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
129 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
130 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
131 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
132 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
133 DestroyWindow( test
);
135 /* owned top-level window */
136 test
= create_tool_window( 0, hwndMain
);
137 trace( "created owned top-level %x\n", test
);
138 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
139 SetWindowLongW( test
, GWL_STYLE
, WS_POPUP
);
140 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
141 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
142 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
143 DestroyWindow( test
);
145 /* not owned popup */
146 test
= create_tool_window( WS_POPUP
, 0 );
147 trace( "created popup %x\n", test
);
148 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
149 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
150 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
151 SetWindowLongW( test
, GWL_STYLE
, 0 );
152 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
153 DestroyWindow( test
);
156 test
= create_tool_window( WS_POPUP
, hwndMain
);
157 trace( "created owned popup %x\n", test
);
158 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
159 SetWindowLongW( test
, GWL_STYLE
, WS_CHILD
);
160 check_parents( test
, desktop
, hwndMain
, desktop
, hwndMain
, test
, desktop
);
161 SetWindowLongW( test
, GWL_STYLE
, 0 );
162 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
163 DestroyWindow( test
);
165 /* top-level window owned by child (same as owned by top-level) */
166 test
= create_tool_window( 0, child
);
167 trace( "created top-level owned by child %x\n", test
);
168 check_parents( test
, desktop
, hwndMain
, 0, hwndMain
, test
, test
);
169 DestroyWindow( test
);
171 /* popup owned by desktop (same as not owned) */
172 test
= create_tool_window( WS_POPUP
, desktop
);
173 trace( "created popup owned by desktop %x\n", test
);
174 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
175 DestroyWindow( test
);
177 /* popup owned by child (same as owned by top-level) */
178 test
= create_tool_window( WS_POPUP
, child
);
179 trace( "created popup owned by child %x\n", test
);
180 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
181 DestroyWindow( test
);
183 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
184 test
= create_tool_window( WS_POPUP
| WS_CHILD
, 0 );
185 trace( "created WS_CHILD popup %x\n", test
);
186 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
187 DestroyWindow( test
);
189 /* owned popup with WS_CHILD (same as WS_POPUP only) */
190 test
= create_tool_window( WS_POPUP
| WS_CHILD
, hwndMain
);
191 trace( "created owned WS_CHILD popup %x\n", test
);
192 check_parents( test
, desktop
, hwndMain
, hwndMain
, hwndMain
, test
, hwndMain
);
193 DestroyWindow( test
);
195 /******************** parent changes *************************/
196 trace( "testing parent changes\n" );
199 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
200 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
201 ok( !ret
, "Set GWL_HWNDPARENT succeeded on desktop" );
202 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
203 ok( !SetParent( desktop
, hwndMain
), "SetParent succeeded on desktop" );
204 check_parents( desktop
, 0, 0, 0, 0, 0, 0 );
206 /* normal child window */
207 test
= create_tool_window( WS_CHILD
, hwndMain
);
208 trace( "created child %x\n", test
);
210 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
211 ok( ret
== hwndMain
, "GWL_HWNDPARENT return value %x expected %x", ret
, hwndMain
);
212 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
214 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
215 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %x expected %x", ret
, hwndMain2
);
216 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
218 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)desktop
);
219 ok( ret
== child
, "GWL_HWNDPARENT return value %x expected %x", ret
, child
);
220 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
222 /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
223 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
224 ok( ret
== 0, "GWL_HWNDPARENT return value %x expected %x", ret
, 0 );
225 check_parents( test
, desktop
, child
, desktop
, child
, test
, desktop
);
227 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
228 ok( ret
== child
, "GWL_HWNDPARENT return value %x expected %x", ret
, child
);
229 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
230 DestroyWindow( test
);
232 /* not owned top-level window */
233 test
= create_tool_window( 0, 0 );
234 trace( "created top-level %x\n", test
);
236 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
237 ok( ret
== 0, "GWL_HWNDPARENT return value %x expected %x", ret
, 0 );
238 check_parents( test
, desktop
, hwndMain2
, 0, hwndMain2
, test
, test
);
240 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
241 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %x expected %x", ret
, hwndMain2
);
242 check_parents( test
, desktop
, child
, 0, child
, test
, test
);
244 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
245 ok( ret
== child
, "GWL_HWNDPARENT return value %x expected %x", ret
, child
);
246 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
247 DestroyWindow( test
);
249 /* not owned popup */
250 test
= create_tool_window( WS_POPUP
, 0 );
251 trace( "created popup %x\n", test
);
253 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)hwndMain2
);
254 ok( ret
== 0, "GWL_HWNDPARENT return value %x expected %x", ret
, 0 );
255 check_parents( test
, desktop
, hwndMain2
, hwndMain2
, hwndMain2
, test
, hwndMain2
);
257 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (LONG_PTR
)child
);
258 ok( ret
== hwndMain2
, "GWL_HWNDPARENT return value %x expected %x", ret
, hwndMain2
);
259 check_parents( test
, desktop
, child
, child
, child
, test
, hwndMain
);
261 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, 0 );
262 ok( ret
== child
, "GWL_HWNDPARENT return value %x expected %x", ret
, child
);
263 check_parents( test
, desktop
, 0, 0, 0, test
, test
);
264 DestroyWindow( test
);
266 /* normal child window */
267 test
= create_tool_window( WS_CHILD
, hwndMain
);
268 trace( "created child %x\n", test
);
270 ret
= SetParent( test
, desktop
);
271 ok( ret
== hwndMain
, "SetParent return value %x expected %x", ret
, hwndMain
);
272 check_parents( test
, desktop
, 0, desktop
, 0, test
, desktop
);
274 ret
= SetParent( test
, child
);
275 ok( ret
== desktop
, "SetParent return value %x expected %x", ret
, desktop
);
276 check_parents( test
, child
, child
, child
, 0, hwndMain
, hwndMain
);
278 ret
= SetParent( test
, hwndMain2
);
279 ok( ret
== child
, "SetParent return value %x expected %x", ret
, child
);
280 check_parents( test
, hwndMain2
, hwndMain2
, hwndMain2
, 0, hwndMain2
, hwndMain2
);
281 DestroyWindow( test
);
283 /* not owned top-level window */
284 test
= create_tool_window( 0, 0 );
285 trace( "created top-level %x\n", test
);
287 ret
= SetParent( test
, child
);
288 ok( ret
== desktop
, "SetParent return value %x expected %x", ret
, desktop
);
289 check_parents( test
, child
, child
, 0, 0, hwndMain
, test
);
290 DestroyWindow( test
);
293 test
= create_tool_window( WS_POPUP
, hwndMain2
);
294 trace( "created owned popup %x\n", test
);
296 ret
= SetParent( test
, child
);
297 ok( ret
== desktop
, "SetParent return value %x expected %x", ret
, desktop
);
298 check_parents( test
, child
, child
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
300 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (ULONG_PTR
)hwndMain
);
301 ok( ret
== child
, "GWL_HWNDPARENT return value %x expected %x", ret
, child
);
302 check_parents( test
, hwndMain
, hwndMain
, hwndMain2
, hwndMain2
, hwndMain
, hwndMain2
);
303 DestroyWindow( test
);
305 /**************** test owner destruction *******************/
307 /* owned child popup */
308 owner
= create_tool_window( 0, 0 );
309 test
= create_tool_window( WS_POPUP
, owner
);
310 trace( "created owner %x and popup %x\n", owner
, test
);
311 ret
= SetParent( test
, child
);
312 ok( ret
== desktop
, "SetParent return value %x expected %x", ret
, desktop
);
313 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
314 /* window is now child of 'child' but owned by 'owner' */
315 DestroyWindow( owner
);
316 ok( IsWindow(test
), "Window %x destroyed by owner destruction", test
);
317 check_parents( test
, child
, child
, owner
, owner
, hwndMain
, owner
);
318 ok( !IsWindow(owner
), "Owner %x not destroyed", owner
);
321 /* owned top-level popup */
322 owner
= create_tool_window( 0, 0 );
323 test
= create_tool_window( WS_POPUP
, owner
);
324 trace( "created owner %x and popup %x\n", owner
, test
);
325 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
326 DestroyWindow( owner
);
327 ok( !IsWindow(test
), "Window %x not destroyed by owner destruction", test
);
329 /* top-level popup owned by child */
330 owner
= create_tool_window( WS_CHILD
, hwndMain2
);
331 test
= create_tool_window( WS_POPUP
, 0 );
332 trace( "created owner %x and popup %x\n", owner
, test
);
333 ret
= (HWND
)SetWindowLongW( test
, GWL_HWNDPARENT
, (ULONG_PTR
)owner
);
334 ok( ret
== 0, "GWL_HWNDPARENT return value %x expected %x", ret
, 0 );
335 check_parents( test
, desktop
, owner
, owner
, owner
, test
, hwndMain2
);
336 DestroyWindow( owner
);
337 ok( IsWindow(test
), "Window %x destroyed by owner destruction", test
);
338 ok( !IsWindow(owner
), "Owner %x not destroyed", owner
);
339 check_parents( test
, desktop
, owner
, owner
, owner
, test
, owner
);
343 DestroyWindow(child
);
347 static BOOL
RegisterWindowClasses(void)
352 cls
.lpfnWndProc
= DefWindowProcA
;
355 cls
.hInstance
= GetModuleHandleA(0);
357 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
358 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
359 cls
.lpszMenuName
= NULL
;
360 cls
.lpszClassName
= "MainWindowClass";
362 if(!RegisterClassA(&cls
)) return FALSE
;
365 cls
.lpfnWndProc
= DefWindowProcA
;
368 cls
.hInstance
= GetModuleHandleA(0);
370 cls
.hCursor
= LoadCursorA(0, IDC_ARROWA
);
371 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
372 cls
.lpszMenuName
= NULL
;
373 cls
.lpszClassName
= "ToolWindowClass";
375 if(!RegisterClassA(&cls
)) return FALSE
;
383 pGetAncestor
= (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
385 if (!RegisterWindowClasses()) assert(0);
387 hwndMain
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
388 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
389 WS_MAXIMIZEBOX
| WS_POPUP
,
392 hwndMain2
= CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
393 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
394 WS_MAXIMIZEBOX
| WS_POPUP
,