Updated the generated tests.
[wine] / dlls / user / tests / win.c
1 /*
2  * Unit tests for window handling
3  *
4  * Copyright 2002 Bill Medland
5  * Copyright 2002 Alexandre Julliard
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include "wine/test.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30
31 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
32
33 static HWND hwndMain, hwndMain2;
34
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 )
38 {
39     HWND res;
40
41     if (pGetAncestor)
42     {
43         res = pGetAncestor( hwnd, GA_PARENT );
44         ok( res == ga_parent, "Wrong result for GA_PARENT %p expected %p", res, ga_parent );
45     }
46     res = (HWND)GetWindowLongW( hwnd, GWL_HWNDPARENT );
47     ok( res == gwl_parent, "Wrong result for GWL_HWNDPARENT %p expected %p", res, gwl_parent );
48     res = GetParent( hwnd );
49     ok( res == get_parent, "Wrong result for GetParent %p expected %p", res, get_parent );
50     res = GetWindow( hwnd, GW_OWNER );
51     ok( res == gw_owner, "Wrong result for GW_OWNER %p expected %p", res, gw_owner );
52     if (pGetAncestor)
53     {
54         res = pGetAncestor( hwnd, GA_ROOT );
55         ok( res == ga_root, "Wrong result for GA_ROOT %p expected %p", res, ga_root );
56         res = pGetAncestor( hwnd, GA_ROOTOWNER );
57         ok( res == ga_root_owner, "Wrong result for GA_ROOTOWNER %p expected %p", res, ga_root_owner );
58     }
59 }
60
61
62 static HWND create_tool_window( LONG style, HWND parent )
63 {
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" );
67     return ret;
68 }
69
70 /* test parent and owner values for various combinations */
71 static void test_parent_owner(void)
72 {
73     LONG style;
74     HWND test, owner, ret;
75     HWND desktop = GetDesktopWindow();
76     HWND child = create_tool_window( WS_CHILD, hwndMain );
77
78     trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
79
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" );
84
85     /* desktop window */
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" );
91
92     /* normal child window */
93     test = create_tool_window( WS_CHILD, hwndMain );
94     trace( "created child %p\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 );
104
105     /* child of desktop */
106     test = create_tool_window( WS_CHILD, desktop );
107     trace( "created child of desktop %p\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 );
114
115     /* child of child */
116     test = create_tool_window( WS_CHILD, child );
117     trace( "created child of child %p\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 );
124
125     /* not owned top-level window */
126     test = create_tool_window( 0, 0 );
127     trace( "created top-level %p\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 );
134
135     /* owned top-level window */
136     test = create_tool_window( 0, hwndMain );
137     trace( "created owned top-level %p\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 );
144
145     /* not owned popup */
146     test = create_tool_window( WS_POPUP, 0 );
147     trace( "created popup %p\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 );
154
155     /* owned popup */
156     test = create_tool_window( WS_POPUP, hwndMain );
157     trace( "created owned popup %p\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 );
164
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 %p\n", test );
168     check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
169     DestroyWindow( test );
170
171     /* popup owned by desktop (same as not owned) */
172     test = create_tool_window( WS_POPUP, desktop );
173     trace( "created popup owned by desktop %p\n", test );
174     check_parents( test, desktop, 0, 0, 0, test, test );
175     DestroyWindow( test );
176
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 %p\n", test );
180     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
181     DestroyWindow( test );
182
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 %p\n", test );
186     check_parents( test, desktop, 0, 0, 0, test, test );
187     DestroyWindow( test );
188
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 %p\n", test );
192     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
193     DestroyWindow( test );
194
195     /******************** parent changes *************************/
196     trace( "testing parent changes\n" );
197
198     /* desktop window */
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 );
205
206     /* normal child window */
207     test = create_tool_window( WS_CHILD, hwndMain );
208     trace( "created child %p\n", test );
209
210     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
211     ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain );
212     check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
213
214     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)child );
215     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
216     check_parents( test, child, child, child, 0, hwndMain, hwndMain );
217
218     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)desktop );
219     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
220     check_parents( test, desktop, 0, desktop, 0, test, desktop );
221
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 %p expected 0", ret );
225     check_parents( test, desktop, child, desktop, child, test, desktop );
226
227     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, 0 );
228     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
229     check_parents( test, desktop, 0, desktop, 0, test, desktop );
230     DestroyWindow( test );
231
232     /* not owned top-level window */
233     test = create_tool_window( 0, 0 );
234     trace( "created top-level %p\n", test );
235
236     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
237     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
238     check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
239
240     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)child );
241     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
242     check_parents( test, desktop, child, 0, child, test, test );
243
244     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, 0 );
245     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
246     check_parents( test, desktop, 0, 0, 0, test, test );
247     DestroyWindow( test );
248
249     /* not owned popup */
250     test = create_tool_window( WS_POPUP, 0 );
251     trace( "created popup %p\n", test );
252
253     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 );
254     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
255     check_parents( test, desktop, hwndMain2, hwndMain2, hwndMain2, test, hwndMain2 );
256
257     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (LONG_PTR)child );
258     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p", ret, hwndMain2 );
259     check_parents( test, desktop, child, child, child, test, hwndMain );
260
261     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, 0 );
262     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
263     check_parents( test, desktop, 0, 0, 0, test, test );
264     DestroyWindow( test );
265
266     /* normal child window */
267     test = create_tool_window( WS_CHILD, hwndMain );
268     trace( "created child %p\n", test );
269
270     ret = SetParent( test, desktop );
271     ok( ret == hwndMain, "SetParent return value %p expected %p", ret, hwndMain );
272     check_parents( test, desktop, 0, desktop, 0, test, desktop );
273
274     ret = SetParent( test, child );
275     ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
276     check_parents( test, child, child, child, 0, hwndMain, hwndMain );
277
278     ret = SetParent( test, hwndMain2 );
279     ok( ret == child, "SetParent return value %p expected %p", ret, child );
280     check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
281     DestroyWindow( test );
282
283     /* not owned top-level window */
284     test = create_tool_window( 0, 0 );
285     trace( "created top-level %p\n", test );
286
287     ret = SetParent( test, child );
288     ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
289     check_parents( test, child, child, 0, 0, hwndMain, test );
290     DestroyWindow( test );
291
292     /* owned popup */
293     test = create_tool_window( WS_POPUP, hwndMain2 );
294     trace( "created owned popup %p\n", test );
295
296     ret = SetParent( test, child );
297     ok( ret == desktop, "SetParent return value %p expected %p", ret, desktop );
298     check_parents( test, child, child, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
299
300     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (ULONG_PTR)hwndMain );
301     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p", ret, child );
302     check_parents( test, hwndMain, hwndMain, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
303     DestroyWindow( test );
304
305     /**************** test owner destruction *******************/
306
307     /* owned child popup */
308     owner = create_tool_window( 0, 0 );
309     test = create_tool_window( WS_POPUP, owner );
310     trace( "created owner %p and popup %p\n", owner, test );
311     ret = SetParent( test, child );
312     ok( ret == desktop, "SetParent return value %p expected %p", 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 %p destroyed by owner destruction", test );
317     check_parents( test, child, child, owner, owner, hwndMain, owner );
318     ok( !IsWindow(owner), "Owner %p not destroyed", owner );
319     DestroyWindow(test);
320
321     /* owned top-level 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     check_parents( test, desktop, owner, owner, owner, test, owner );
326     DestroyWindow( owner );
327     ok( !IsWindow(test), "Window %p not destroyed by owner destruction", test );
328
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 %p and popup %p\n", owner, test );
333     ret = (HWND)SetWindowLongW( test, GWL_HWNDPARENT, (ULONG_PTR)owner );
334     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0", ret );
335     check_parents( test, desktop, owner, owner, owner, test, hwndMain2 );
336     DestroyWindow( owner );
337     ok( IsWindow(test), "Window %p destroyed by owner destruction", test );
338     ok( !IsWindow(owner), "Owner %p not destroyed", owner );
339     check_parents( test, desktop, owner, owner, owner, test, owner );
340     DestroyWindow(test);
341
342     /* final cleanup */
343     DestroyWindow(child);
344 }
345
346
347 static BOOL RegisterWindowClasses(void)
348 {
349     WNDCLASSA cls;
350
351     cls.style = 0;
352     cls.lpfnWndProc = DefWindowProcA;
353     cls.cbClsExtra = 0;
354     cls.cbWndExtra = 0;
355     cls.hInstance = GetModuleHandleA(0);
356     cls.hIcon = 0;
357     cls.hCursor = LoadCursorA(0, IDC_ARROWA);
358     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
359     cls.lpszMenuName = NULL;
360     cls.lpszClassName = "MainWindowClass";
361
362     if(!RegisterClassA(&cls)) return FALSE;
363
364     cls.style = 0;
365     cls.lpfnWndProc = DefWindowProcA;
366     cls.cbClsExtra = 0;
367     cls.cbWndExtra = 0;
368     cls.hInstance = GetModuleHandleA(0);
369     cls.hIcon = 0;
370     cls.hCursor = LoadCursorA(0, IDC_ARROWA);
371     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
372     cls.lpszMenuName = NULL;
373     cls.lpszClassName = "ToolWindowClass";
374
375     if(!RegisterClassA(&cls)) return FALSE;
376
377     return TRUE;
378 }
379
380
381 START_TEST(win)
382 {
383     pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
384
385     if (!RegisterWindowClasses()) assert(0);
386
387     hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
388                                WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
389                                WS_MAXIMIZEBOX | WS_POPUP,
390                                100, 100, 200, 200,
391                                0, 0, 0, NULL);
392     hwndMain2 = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window 2",
393                                 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
394                                 WS_MAXIMIZEBOX | WS_POPUP,
395                                 100, 100, 200, 200,
396                                 0, 0, 0, NULL);
397     assert( hwndMain );
398     assert( hwndMain2 );
399
400     test_parent_owner();
401 }