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"
34 #ifndef SPI_GETDESKWALLPAPER
35 #define SPI_GETDESKWALLPAPER 0x0073
38 #define LONG_PTR INT_PTR
39 #define ULONG_PTR UINT_PTR
41 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
43 static HWND hwndMain, hwndMain2;
45 /* check the values returned by the various parent/owner functions on a given window */
46 static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_parent,
47 HWND gw_owner, HWND ga_root, HWND ga_root_owner )
53 res = pGetAncestor( hwnd, GA_PARENT );
54 ok( res == ga_parent, "Wrong result for GA_PARENT %p expected %p", res, ga_parent );
56 res = (HWND)GetWindowLongA( hwnd, GWL_HWNDPARENT );
57 ok( res == gwl_parent, "Wrong result for GWL_HWNDPARENT %p expected %p", res, gwl_parent );
58 res = GetParent( hwnd );
59 ok( res == get_parent, "Wrong result for GetParent %p expected %p", res, get_parent );
60 res = GetWindow( hwnd, GW_OWNER );
61 ok( res == gw_owner, "Wrong result for GW_OWNER %p expected %p", res, gw_owner );
64 res = pGetAncestor( hwnd, GA_ROOT );
65 ok( res == ga_root, "Wrong result for GA_ROOT %p expected %p", res, ga_root );
66 res = pGetAncestor( hwnd, GA_ROOTOWNER );
67 ok( res == ga_root_owner, "Wrong result for GA_ROOTOWNER %p expected %p", res, ga_root_owner );
72 static HWND create_tool_window( LONG style, HWND parent )
74 HWND ret = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style,
75 0, 0, 100, 100, parent, 0, 0, NULL );
76 ok( ret != 0, "Creation failed" );
80 /* test parent and owner values for various combinations */
81 static void test_parent_owner(void)
84 HWND test, owner, ret;
85 HWND desktop = GetDesktopWindow();
86 HWND child = create_tool_window( WS_CHILD, hwndMain );
88 trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
90 /* child without parent, should fail */
91 test = CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
92 WS_CHILD, 0, 0, 100, 100, 0, 0, 0, NULL );
93 ok( !test, "WS_CHILD without parent created" );
96 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
97 style = GetWindowLongA( desktop, GWL_STYLE );
98 ok( !SetWindowLongA( desktop, GWL_STYLE, WS_POPUP ), "Set GWL_STYLE on desktop succeeded" );
99 ok( !SetWindowLongA( desktop, GWL_STYLE, 0 ), "Set GWL_STYLE on desktop succeeded" );
100 ok( GetWindowLongA( desktop, GWL_STYLE ) == style, "Desktop style changed" );
102 /* normal child window */
103 test = create_tool_window( WS_CHILD, hwndMain );
104 trace( "created child %p\n", test );
105 check_parents( test, hwndMain, hwndMain, hwndMain, 0, hwndMain, hwndMain );
106 SetWindowLongA( test, GWL_STYLE, 0 );
107 check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
108 SetWindowLongA( test, GWL_STYLE, WS_POPUP );
109 check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
110 SetWindowLongA( test, GWL_STYLE, WS_POPUP|WS_CHILD );
111 check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
112 SetWindowLongA( test, GWL_STYLE, WS_CHILD );
113 DestroyWindow( test );
115 /* child of desktop */
116 test = create_tool_window( WS_CHILD, desktop );
117 trace( "created child of desktop %p\n", test );
118 check_parents( test, desktop, 0, desktop, 0, test, desktop );
119 SetWindowLongA( test, GWL_STYLE, WS_POPUP );
120 check_parents( test, desktop, 0, 0, 0, test, test );
121 SetWindowLongA( test, GWL_STYLE, 0 );
122 check_parents( test, desktop, 0, 0, 0, test, test );
123 DestroyWindow( test );
126 test = create_tool_window( WS_CHILD, child );
127 trace( "created child of child %p\n", test );
128 check_parents( test, child, child, child, 0, hwndMain, hwndMain );
129 SetWindowLongA( test, GWL_STYLE, 0 );
130 check_parents( test, child, child, 0, 0, hwndMain, test );
131 SetWindowLongA( test, GWL_STYLE, WS_POPUP );
132 check_parents( test, child, child, 0, 0, hwndMain, test );
133 DestroyWindow( test );
135 /* not owned top-level window */
136 test = create_tool_window( 0, 0 );
137 trace( "created top-level %p\n", test );
138 check_parents( test, desktop, 0, 0, 0, test, test );
139 SetWindowLongA( test, GWL_STYLE, WS_POPUP );
140 check_parents( test, desktop, 0, 0, 0, test, test );
141 SetWindowLongA( test, GWL_STYLE, WS_CHILD );
142 check_parents( test, desktop, 0, desktop, 0, test, desktop );
143 DestroyWindow( test );
145 /* owned top-level window */
146 test = create_tool_window( 0, hwndMain );
147 trace( "created owned top-level %p\n", test );
148 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
149 SetWindowLongA( test, GWL_STYLE, WS_POPUP );
150 check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
151 SetWindowLongA( test, GWL_STYLE, WS_CHILD );
152 check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
153 DestroyWindow( test );
155 /* not owned popup */
156 test = create_tool_window( WS_POPUP, 0 );
157 trace( "created popup %p\n", test );
158 check_parents( test, desktop, 0, 0, 0, test, test );
159 SetWindowLongA( test, GWL_STYLE, WS_CHILD );
160 check_parents( test, desktop, 0, desktop, 0, test, desktop );
161 SetWindowLongA( test, GWL_STYLE, 0 );
162 check_parents( test, desktop, 0, 0, 0, test, test );
163 DestroyWindow( test );
166 test = create_tool_window( WS_POPUP, hwndMain );
167 trace( "created owned popup %p\n", test );
168 check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
169 SetWindowLongA( test, GWL_STYLE, WS_CHILD );
170 check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
171 SetWindowLongA( test, GWL_STYLE, 0 );
172 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
173 DestroyWindow( test );
175 /* top-level window owned by child (same as owned by top-level) */
176 test = create_tool_window( 0, child );
177 trace( "created top-level owned by child %p\n", test );
178 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
179 DestroyWindow( test );
181 /* popup owned by desktop (same as not owned) */
182 test = create_tool_window( WS_POPUP, desktop );
183 trace( "created popup owned by desktop %p\n", test );
184 check_parents( test, desktop, 0, 0, 0, test, test );
185 DestroyWindow( test );
187 /* popup owned by child (same as owned by top-level) */
188 test = create_tool_window( WS_POPUP, child );
189 trace( "created popup owned by child %p\n", test );
190 check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
191 DestroyWindow( test );
193 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
194 test = create_tool_window( WS_POPUP | WS_CHILD, 0 );
195 trace( "created WS_CHILD popup %p\n", test );
196 check_parents( test, desktop, 0, 0, 0, test, test );
197 DestroyWindow( test );
199 /* owned popup with WS_CHILD (same as WS_POPUP only) */
200 test = create_tool_window( WS_POPUP | WS_CHILD, hwndMain );
201 trace( "created owned WS_CHILD popup %p\n", test );
202 check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
203 DestroyWindow( test );
205 /******************** parent changes *************************/
206 trace( "testing parent changes\n" );
209 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
210 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
211 ok( !ret, "Set GWL_HWNDPARENT succeeded on desktop" );
212 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
213 ok( !SetParent( desktop, hwndMain ), "SetParent succeeded on desktop" );
214 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
216 /* normal child window */
217 test = create_tool_window( WS_CHILD, hwndMain );
218 trace( "created child %p\n", test );
220 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
221 ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain );
222 check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
224 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child );
225 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
226 check_parents( test, child, child, child, 0, hwndMain, hwndMain );
228 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)desktop );
229 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
230 check_parents( test, desktop, 0, desktop, 0, test, desktop );
232 /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
233 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child );
234 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
235 check_parents( test, desktop, child, desktop, child, test, desktop );
237 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 );
238 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
239 check_parents( test, desktop, 0, desktop, 0, test, desktop );
240 DestroyWindow( test );
242 /* not owned top-level window */
243 test = create_tool_window( 0, 0 );
244 trace( "created top-level %p\n", test );
246 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
247 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
248 check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
250 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child );
251 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
252 check_parents( test, desktop, child, 0, child, test, test );
254 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 );
255 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
256 check_parents( test, desktop, 0, 0, 0, test, test );
257 DestroyWindow( test );
259 /* not owned popup */
260 test = create_tool_window( WS_POPUP, 0 );
261 trace( "created popup %p\n", test );
263 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
264 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
265 check_parents( test, desktop, hwndMain2, hwndMain2, hwndMain2, test, hwndMain2 );
267 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child );
268 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
269 check_parents( test, desktop, child, child, child, test, hwndMain );
271 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 );
272 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
273 check_parents( test, desktop, 0, 0, 0, test, test );
274 DestroyWindow( test );
276 /* normal child window */
277 test = create_tool_window( WS_CHILD, hwndMain );
278 trace( "created child %p\n", test );
280 ret = SetParent( test, desktop );
281 ok( ret == hwndMain, "SetParent return value %p expected %p", ret, hwndMain );
282 check_parents( test, desktop, 0, desktop, 0, test, desktop );
284 ret = SetParent( test, child );
285 ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
286 check_parents( test, child, child, child, 0, hwndMain, hwndMain );
288 ret = SetParent( test, hwndMain2 );
289 ok( ret == child, "SetParent return value %p expected %p", ret, child );
290 check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
291 DestroyWindow( test );
293 /* not owned top-level window */
294 test = create_tool_window( 0, 0 );
295 trace( "created top-level %p\n", test );
297 ret = SetParent( test, child );
298 ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
299 check_parents( test, child, child, 0, 0, hwndMain, test );
300 DestroyWindow( test );
303 test = create_tool_window( WS_POPUP, hwndMain2 );
304 trace( "created owned popup %p\n", test );
306 ret = SetParent( test, child );
307 ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
308 check_parents( test, child, child, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
310 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (ULONG_PTR)hwndMain );
311 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
312 check_parents( test, hwndMain, hwndMain, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
313 DestroyWindow( test );
315 /**************** test owner destruction *******************/
317 /* owned child popup */
318 owner = create_tool_window( 0, 0 );
319 test = create_tool_window( WS_POPUP, owner );
320 trace( "created owner %p and popup %p\n", owner, test );
321 ret = SetParent( test, child );
322 ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
323 check_parents( test, child, child, owner, owner, hwndMain, owner );
324 /* window is now child of 'child' but owned by 'owner' */
325 DestroyWindow( owner );
326 ok( IsWindow(test), "Window %p destroyed by owner destruction", test );
327 check_parents( test, child, child, owner, owner, hwndMain, owner );
328 ok( !IsWindow(owner), "Owner %p not destroyed", owner );
331 /* owned top-level popup */
332 owner = create_tool_window( 0, 0 );
333 test = create_tool_window( WS_POPUP, owner );
334 trace( "created owner %p and popup %p\n", owner, test );
335 check_parents( test, desktop, owner, owner, owner, test, owner );
336 DestroyWindow( owner );
337 ok( !IsWindow(test), "Window %p not destroyed by owner destruction", test );
339 /* top-level popup owned by child */
340 owner = create_tool_window( WS_CHILD, hwndMain2 );
341 test = create_tool_window( WS_POPUP, 0 );
342 trace( "created owner %p and popup %p\n", owner, test );
343 ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (ULONG_PTR)owner );
344 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
345 check_parents( test, desktop, owner, owner, owner, test, hwndMain2 );
346 DestroyWindow( owner );
347 ok( IsWindow(test), "Window %p destroyed by owner destruction", test );
348 ok( !IsWindow(owner), "Owner %p not destroyed", owner );
349 check_parents( test, desktop, owner, owner, owner, test, owner );
353 DestroyWindow(child);
357 static BOOL RegisterWindowClasses(void)
362 cls.lpfnWndProc = DefWindowProcA;
365 cls.hInstance = GetModuleHandleA(0);
367 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
368 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
369 cls.lpszMenuName = NULL;
370 cls.lpszClassName = "MainWindowClass";
372 if(!RegisterClassA(&cls)) return FALSE;
375 cls.lpfnWndProc = DefWindowProcA;
378 cls.hInstance = GetModuleHandleA(0);
380 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
381 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
382 cls.lpszMenuName = NULL;
383 cls.lpszClassName = "ToolWindowClass";
385 if(!RegisterClassA(&cls)) return FALSE;
393 pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
395 if (!RegisterWindowClasses()) assert(0);
397 hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
398 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
399 WS_MAXIMIZEBOX | WS_POPUP,
402 hwndMain2 = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
403 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
404 WS_MAXIMIZEBOX | WS_POPUP,