~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/tests/win.c

Version: ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Unit tests for window handling
  3  *
  4  * Copyright 2002 Bill Medland
  5  * Copyright 2002 Alexandre Julliard
  6  * Copyright 2003 Dmitry Timoshkov
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Lesser General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2.1 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * Lesser General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public
 19  * License along with this library; if not, write to the Free Software
 20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  */
 22 
 23 /* To get ICON_SMALL2 with the MSVC headers */
 24 #define _WIN32_WINNT 0x0501
 25 
 26 #include <assert.h>
 27 #include <stdlib.h>
 28 #include <stdarg.h>
 29 #include <stdio.h>
 30 
 31 #include "windef.h"
 32 #include "winbase.h"
 33 #include "wingdi.h"
 34 #include "winuser.h"
 35 
 36 #include "wine/test.h"
 37 
 38 #ifndef SPI_GETDESKWALLPAPER
 39 #define SPI_GETDESKWALLPAPER 0x0073
 40 #endif
 41 
 42 #define LONG_PTR INT_PTR
 43 #define ULONG_PTR UINT_PTR
 44 
 45 void dump_region(HRGN hrgn);
 46 
 47 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
 48 static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
 49 static UINT (WINAPI *pGetWindowModuleFileNameA)(HWND,LPSTR,UINT);
 50 static BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF*,BYTE*,DWORD*);
 51 static BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
 52 static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
 53 static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
 54 
 55 static BOOL test_lbuttondown_flag;
 56 static HWND hwndMessage;
 57 static HWND hwndMain, hwndMain2;
 58 static HHOOK hhook;
 59 
 60 static const char* szAWRClass = "Winsize";
 61 static HMENU hmenu;
 62 static DWORD our_pid;
 63 
 64 #define COUNTOF(arr) (sizeof(arr)/sizeof(arr[0]))
 65 
 66 static void dump_minmax_info( const MINMAXINFO *minmax )
 67 {
 68     trace("Reserved=%d,%d MaxSize=%d,%d MaxPos=%d,%d MinTrack=%d,%d MaxTrack=%d,%d\n",
 69           minmax->ptReserved.x, minmax->ptReserved.y,
 70           minmax->ptMaxSize.x, minmax->ptMaxSize.y,
 71           minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
 72           minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
 73           minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
 74 }
 75 
 76 /* try to make sure pending X events have been processed before continuing */
 77 static void flush_events( BOOL remove_messages )
 78 {
 79     MSG msg;
 80     int diff = 200;
 81     int min_timeout = 50;
 82     DWORD time = GetTickCount() + diff;
 83 
 84     while (diff > 0)
 85     {
 86         if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
 87         if (remove_messages)
 88             while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
 89         diff = time - GetTickCount();
 90         min_timeout = 10;
 91     }
 92 }
 93 
 94 /* check the values returned by the various parent/owner functions on a given window */
 95 static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_parent,
 96                            HWND gw_owner, HWND ga_root, HWND ga_root_owner )
 97 {
 98     HWND res;
 99 
100     if (pGetAncestor)
101     {
102         res = pGetAncestor( hwnd, GA_PARENT );
103         ok( res == ga_parent, "Wrong result for GA_PARENT %p expected %p\n", res, ga_parent );
104     }
105     res = (HWND)GetWindowLongPtrA( hwnd, GWLP_HWNDPARENT );
106     ok( res == gwl_parent, "Wrong result for GWL_HWNDPARENT %p expected %p\n", res, gwl_parent );
107     res = GetParent( hwnd );
108     ok( res == get_parent, "Wrong result for GetParent %p expected %p\n", res, get_parent );
109     res = GetWindow( hwnd, GW_OWNER );
110     ok( res == gw_owner, "Wrong result for GW_OWNER %p expected %p\n", res, gw_owner );
111     if (pGetAncestor)
112     {
113         res = pGetAncestor( hwnd, GA_ROOT );
114         ok( res == ga_root, "Wrong result for GA_ROOT %p expected %p\n", res, ga_root );
115         res = pGetAncestor( hwnd, GA_ROOTOWNER );
116         ok( res == ga_root_owner, "Wrong result for GA_ROOTOWNER %p expected %p\n", res, ga_root_owner );
117     }
118 }
119 
120 static BOOL CALLBACK EnumChildProc( HWND hwndChild, LPARAM lParam)
121 {
122     (*(LPINT)lParam)++;
123     trace("EnumChildProc on %p\n", hwndChild);
124     if (*(LPINT)lParam > 1) return FALSE;
125     return TRUE;
126 }
127 
128 /* will search for the given window */
129 static BOOL CALLBACK EnumChildProc1( HWND hwndChild, LPARAM lParam)
130 {
131     trace("EnumChildProc1 on %p\n", hwndChild);
132     if ((HWND)lParam == hwndChild) return FALSE;
133     return TRUE;
134 }
135 
136 static HWND create_tool_window( LONG style, HWND parent )
137 {
138     HWND ret = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style,
139                                0, 0, 100, 100, parent, 0, 0, NULL );
140     ok( ret != 0, "Creation failed\n" );
141     return ret;
142 }
143 
144 /* test parent and owner values for various combinations */
145 static void test_parent_owner(void)
146 {
147     LONG style;
148     HWND test, owner, ret;
149     HWND desktop = GetDesktopWindow();
150     HWND child = create_tool_window( WS_CHILD, hwndMain );
151     INT  numChildren;
152 
153     trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
154 
155     /* child without parent, should fail */
156     SetLastError(0xdeadbeef);
157     test = CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
158                            WS_CHILD, 0, 0, 100, 100, 0, 0, 0, NULL );
159     ok( GetLastError() == ERROR_TLW_WITH_WSCHILD, "CreateWindowExA should call SetLastError\n" );
160     ok( !test, "WS_CHILD without parent created\n" );
161 
162     /* desktop window */
163     check_parents( desktop, 0, 0, 0, 0, 0, 0 );
164     style = GetWindowLongA( desktop, GWL_STYLE );
165     ok( !SetWindowLongA( desktop, GWL_STYLE, WS_POPUP ), "Set GWL_STYLE on desktop succeeded\n" );
166     ok( !SetWindowLongA( desktop, GWL_STYLE, 0 ), "Set GWL_STYLE on desktop succeeded\n" );
167     ok( GetWindowLongA( desktop, GWL_STYLE ) == style, "Desktop style changed\n" );
168 
169     /* normal child window */
170     test = create_tool_window( WS_CHILD, hwndMain );
171     trace( "created child %p\n", test );
172     check_parents( test, hwndMain, hwndMain, hwndMain, 0, hwndMain, hwndMain );
173     SetWindowLongA( test, GWL_STYLE, 0 );
174     check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
175     SetWindowLongA( test, GWL_STYLE, WS_POPUP );
176     check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
177     SetWindowLongA( test, GWL_STYLE, WS_POPUP|WS_CHILD );
178     check_parents( test, hwndMain, hwndMain, 0, 0, hwndMain, test );
179     SetWindowLongA( test, GWL_STYLE, WS_CHILD );
180     DestroyWindow( test );
181 
182     /* normal child window with WS_MAXIMIZE */
183     test = create_tool_window( WS_CHILD | WS_MAXIMIZE, hwndMain );
184     DestroyWindow( test );
185 
186     /* normal child window with WS_THICKFRAME */
187     test = create_tool_window( WS_CHILD | WS_THICKFRAME, hwndMain );
188     DestroyWindow( test );
189 
190     /* popup window with WS_THICKFRAME */
191     test = create_tool_window( WS_POPUP | WS_THICKFRAME, hwndMain );
192     DestroyWindow( test );
193 
194     /* child of desktop */
195     test = create_tool_window( WS_CHILD, desktop );
196     trace( "created child of desktop %p\n", test );
197     check_parents( test, desktop, 0, desktop, 0, test, desktop );
198     SetWindowLongA( test, GWL_STYLE, WS_POPUP );
199     check_parents( test, desktop, 0, 0, 0, test, test );
200     SetWindowLongA( test, GWL_STYLE, 0 );
201     check_parents( test, desktop, 0, 0, 0, test, test );
202     DestroyWindow( test );
203 
204     /* child of desktop with WS_MAXIMIZE */
205     test = create_tool_window( WS_CHILD | WS_MAXIMIZE, desktop );
206     DestroyWindow( test );
207 
208     /* child of desktop with WS_MINIMIZE */
209     test = create_tool_window( WS_CHILD | WS_MINIMIZE, desktop );
210     DestroyWindow( test );
211 
212     /* child of child */
213     test = create_tool_window( WS_CHILD, child );
214     trace( "created child of child %p\n", test );
215     check_parents( test, child, child, child, 0, hwndMain, hwndMain );
216     SetWindowLongA( test, GWL_STYLE, 0 );
217     check_parents( test, child, child, 0, 0, hwndMain, test );
218     SetWindowLongA( test, GWL_STYLE, WS_POPUP );
219     check_parents( test, child, child, 0, 0, hwndMain, test );
220     DestroyWindow( test );
221 
222     /* child of child with WS_MAXIMIZE */
223     test = create_tool_window( WS_CHILD | WS_MAXIMIZE, child );
224     DestroyWindow( test );
225 
226     /* child of child with WS_MINIMIZE */
227     test = create_tool_window( WS_CHILD | WS_MINIMIZE, child );
228     DestroyWindow( test );
229 
230     /* not owned top-level window */
231     test = create_tool_window( 0, 0 );
232     trace( "created top-level %p\n", test );
233     check_parents( test, desktop, 0, 0, 0, test, test );
234     SetWindowLongA( test, GWL_STYLE, WS_POPUP );
235     check_parents( test, desktop, 0, 0, 0, test, test );
236     SetWindowLongA( test, GWL_STYLE, WS_CHILD );
237     check_parents( test, desktop, 0, desktop, 0, test, desktop );
238     DestroyWindow( test );
239 
240     /* not owned top-level window with WS_MAXIMIZE */
241     test = create_tool_window( WS_MAXIMIZE, 0 );
242     DestroyWindow( test );
243 
244     /* owned top-level window */
245     test = create_tool_window( 0, hwndMain );
246     trace( "created owned top-level %p\n", test );
247     check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
248     SetWindowLongA( test, GWL_STYLE, WS_POPUP );
249     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
250     SetWindowLongA( test, GWL_STYLE, WS_CHILD );
251     check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
252     DestroyWindow( test );
253 
254     /* owned top-level window with WS_MAXIMIZE */
255     test = create_tool_window( WS_MAXIMIZE, hwndMain );
256     DestroyWindow( test );
257 
258     /* not owned popup */
259     test = create_tool_window( WS_POPUP, 0 );
260     trace( "created popup %p\n", test );
261     check_parents( test, desktop, 0, 0, 0, test, test );
262     SetWindowLongA( test, GWL_STYLE, WS_CHILD );
263     check_parents( test, desktop, 0, desktop, 0, test, desktop );
264     SetWindowLongA( test, GWL_STYLE, 0 );
265     check_parents( test, desktop, 0, 0, 0, test, test );
266     DestroyWindow( test );
267 
268     /* not owned popup with WS_MAXIMIZE */
269     test = create_tool_window( WS_POPUP | WS_MAXIMIZE, 0 );
270     DestroyWindow( test );
271 
272     /* owned popup */
273     test = create_tool_window( WS_POPUP, hwndMain );
274     trace( "created owned popup %p\n", test );
275     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
276     SetWindowLongA( test, GWL_STYLE, WS_CHILD );
277     check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
278     SetWindowLongA( test, GWL_STYLE, 0 );
279     check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
280     DestroyWindow( test );
281 
282     /* owned popup with WS_MAXIMIZE */
283     test = create_tool_window( WS_POPUP | WS_MAXIMIZE, hwndMain );
284     DestroyWindow( test );
285 
286     /* top-level window owned by child (same as owned by top-level) */
287     test = create_tool_window( 0, child );
288     trace( "created top-level owned by child %p\n", test );
289     check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
290     DestroyWindow( test );
291 
292     /* top-level window owned by child (same as owned by top-level) with WS_MAXIMIZE */
293     test = create_tool_window( WS_MAXIMIZE, child );
294     DestroyWindow( test );
295 
296     /* popup owned by desktop (same as not owned) */
297     test = create_tool_window( WS_POPUP, desktop );
298     trace( "created popup owned by desktop %p\n", test );
299     check_parents( test, desktop, 0, 0, 0, test, test );
300     DestroyWindow( test );
301 
302     /* popup owned by desktop (same as not owned) with WS_MAXIMIZE */
303     test = create_tool_window( WS_POPUP | WS_MAXIMIZE, desktop );
304     DestroyWindow( test );
305 
306     /* popup owned by child (same as owned by top-level) */
307     test = create_tool_window( WS_POPUP, child );
308     trace( "created popup owned by child %p\n", test );
309     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
310     DestroyWindow( test );
311 
312     /* popup owned by child (same as owned by top-level) with WS_MAXIMIZE */
313     test = create_tool_window( WS_POPUP | WS_MAXIMIZE, child );
314     DestroyWindow( test );
315 
316     /* not owned popup with WS_CHILD (same as WS_POPUP only) */
317     test = create_tool_window( WS_POPUP | WS_CHILD, 0 );
318     trace( "created WS_CHILD popup %p\n", test );
319     check_parents( test, desktop, 0, 0, 0, test, test );
320     DestroyWindow( test );
321 
322     /* not owned popup with WS_CHILD | WS_MAXIMIZE (same as WS_POPUP only) */
323     test = create_tool_window( WS_POPUP | WS_CHILD | WS_MAXIMIZE, 0 );
324     DestroyWindow( test );
325 
326     /* owned popup with WS_CHILD (same as WS_POPUP only) */
327     test = create_tool_window( WS_POPUP | WS_CHILD, hwndMain );
328     trace( "created owned WS_CHILD popup %p\n", test );
329     check_parents( test, desktop, hwndMain, hwndMain, hwndMain, test, hwndMain );
330     DestroyWindow( test );
331 
332     /* owned popup with WS_CHILD (same as WS_POPUP only) with WS_MAXIMIZE */
333     test = create_tool_window( WS_POPUP | WS_CHILD | WS_MAXIMIZE, hwndMain );
334     DestroyWindow( test );
335 
336     /******************** parent changes *************************/
337     trace( "testing parent changes\n" );
338 
339     /* desktop window */
340     check_parents( desktop, 0, 0, 0, 0, 0, 0 );
341     if (0)
342     {
343     /* this test succeeds on NT but crashes on win9x systems */
344     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 );
345     ok( !ret, "Set GWL_HWNDPARENT succeeded on desktop\n" );
346     check_parents( desktop, 0, 0, 0, 0, 0, 0 );
347     ok( !SetParent( desktop, hwndMain ), "SetParent succeeded on desktop\n" );
348     check_parents( desktop, 0, 0, 0, 0, 0, 0 );
349     }
350     /* normal child window */
351     test = create_tool_window( WS_CHILD, hwndMain );
352     trace( "created child %p\n", test );
353 
354     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 );
355     ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain );
356     check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
357 
358     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
359     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
360     check_parents( test, child, child, child, 0, hwndMain, hwndMain );
361 
362     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)desktop );
363     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
364     check_parents( test, desktop, 0, desktop, 0, test, desktop );
365 
366     /* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */
367     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
368     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
369     check_parents( test, desktop, child, desktop, child, test, desktop );
370 
371     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 );
372     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
373     check_parents( test, desktop, 0, desktop, 0, test, desktop );
374     DestroyWindow( test );
375 
376     /* not owned top-level window */
377     test = create_tool_window( 0, 0 );
378     trace( "created top-level %p\n", test );
379 
380     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 );
381     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
382     check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
383 
384     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
385     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
386     check_parents( test, desktop, child, 0, child, test, test );
387 
388     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 );
389     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
390     check_parents( test, desktop, 0, 0, 0, test, test );
391     DestroyWindow( test );
392 
393     /* not owned popup */
394     test = create_tool_window( WS_POPUP, 0 );
395     trace( "created popup %p\n", test );
396 
397     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 );
398     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
399     check_parents( test, desktop, hwndMain2, hwndMain2, hwndMain2, test, hwndMain2 );
400 
401     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
402     ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
403     check_parents( test, desktop, child, child, child, test, hwndMain );
404 
405     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 );
406     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
407     check_parents( test, desktop, 0, 0, 0, test, test );
408     DestroyWindow( test );
409 
410     /* normal child window */
411     test = create_tool_window( WS_CHILD, hwndMain );
412     trace( "created child %p\n", test );
413 
414     ret = SetParent( test, desktop );
415     ok( ret == hwndMain, "SetParent return value %p expected %p\n", ret, hwndMain );
416     check_parents( test, desktop, 0, desktop, 0, test, desktop );
417 
418     ret = SetParent( test, child );
419     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
420     check_parents( test, child, child, child, 0, hwndMain, hwndMain );
421 
422     ret = SetParent( test, hwndMain2 );
423     ok( ret == child, "SetParent return value %p expected %p\n", ret, child );
424     check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
425     DestroyWindow( test );
426 
427     /* not owned top-level window */
428     test = create_tool_window( 0, 0 );
429     trace( "created top-level %p\n", test );
430 
431     ret = SetParent( test, child );
432     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
433     check_parents( test, child, child, 0, 0, hwndMain, test );
434     DestroyWindow( test );
435 
436     /* owned popup */
437     test = create_tool_window( WS_POPUP, hwndMain2 );
438     trace( "created owned popup %p\n", test );
439 
440     ret = SetParent( test, child );
441     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
442     check_parents( test, child, child, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
443 
444     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (ULONG_PTR)hwndMain );
445     ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
446     check_parents( test, hwndMain, hwndMain, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
447     DestroyWindow( test );
448 
449     /**************** test owner destruction *******************/
450 
451     /* owned child popup */
452     owner = create_tool_window( 0, 0 );
453     test = create_tool_window( WS_POPUP, owner );
454     trace( "created owner %p and popup %p\n", owner, test );
455     ret = SetParent( test, child );
456     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
457     check_parents( test, child, child, owner, owner, hwndMain, owner );
458     /* window is now child of 'child' but owned by 'owner' */
459     DestroyWindow( owner );
460     ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
461     /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
462      * while Win95, Win2k, WinXP do.
463      */
464     /*check_parents( test, child, child, owner, owner, hwndMain, owner );*/
465     ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
466     DestroyWindow(test);
467 
468     /* owned top-level popup */
469     owner = create_tool_window( 0, 0 );
470     test = create_tool_window( WS_POPUP, owner );
471     trace( "created owner %p and popup %p\n", owner, test );
472     check_parents( test, desktop, owner, owner, owner, test, owner );
473     DestroyWindow( owner );
474     ok( !IsWindow(test), "Window %p not destroyed by owner destruction\n", test );
475 
476     /* top-level popup owned by child */
477     owner = create_tool_window( WS_CHILD, hwndMain2 );
478     test = create_tool_window( WS_POPUP, 0 );
479     trace( "created owner %p and popup %p\n", owner, test );
480     ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (ULONG_PTR)owner );
481     ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
482     check_parents( test, desktop, owner, owner, owner, test, hwndMain2 );
483     DestroyWindow( owner );
484     ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
485     ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
486     /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
487      * while Win95, Win2k, WinXP do.
488      */
489     /*check_parents( test, desktop, owner, owner, owner, test, owner );*/
490     DestroyWindow(test);
491 
492     /* final cleanup */
493     DestroyWindow(child);
494 
495 
496     owner = create_tool_window( WS_OVERLAPPED, 0 );
497     test = create_tool_window( WS_POPUP, desktop );
498 
499     ok( !GetWindow( test, GW_OWNER ), "Wrong owner window\n" );
500     numChildren = 0;
501     ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
502         "EnumChildWindows should have returned FALSE\n" );
503     ok( numChildren == 0, "numChildren should be 0 got %d\n", numChildren );
504 
505     SetWindowLongA( test, GWL_STYLE, (GetWindowLongA( test, GWL_STYLE ) & ~WS_POPUP) | WS_CHILD );
506     ret = SetParent( test, owner );
507     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
508 
509     numChildren = 0;
510     ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
511         "EnumChildWindows should have returned TRUE\n" );
512     ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
513 
514     child = create_tool_window( WS_CHILD, owner );
515     numChildren = 0;
516     ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
517         "EnumChildWindows should have returned FALSE\n" );
518     ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
519     DestroyWindow( child );
520 
521     child = create_tool_window( WS_VISIBLE | WS_OVERLAPPEDWINDOW, owner );
522     ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
523     numChildren = 0;
524     ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
525         "EnumChildWindows should have returned TRUE\n" );
526     ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
527 
528     ret = SetParent( child, owner );
529     ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
530     ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
531     numChildren = 0;
532     ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
533         "EnumChildWindows should have returned FALSE\n" );
534     ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
535 
536     ret = SetParent( child, NULL );
537     ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
538     ok( ret == owner, "SetParent return value %p expected %p\n", ret, owner );
539     numChildren = 0;
540     ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
541         "EnumChildWindows should have returned TRUE\n" );
542     ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
543 
544     /* even GW_OWNER == owner it's still a desktop's child */
545     ok( !EnumChildWindows( desktop, EnumChildProc1, (LPARAM)child ),
546         "EnumChildWindows should have found %p and returned FALSE\n", child );
547 
548     DestroyWindow( child );
549     child = create_tool_window( WS_VISIBLE | WS_OVERLAPPEDWINDOW, NULL );
550 
551     ok( !EnumChildWindows( desktop, EnumChildProc1, (LPARAM)child ),
552         "EnumChildWindows should have found %p and returned FALSE\n", child );
553 
554     DestroyWindow( child );
555     DestroyWindow( test );
556     DestroyWindow( owner );
557 }
558 
559 
560 static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
561 {
562     switch (msg)
563     {
564         case WM_GETMINMAXINFO:
565         {
566             MINMAXINFO* minmax = (MINMAXINFO *)lparam;
567 
568             trace("hwnd %p, WM_GETMINMAXINFO, %08lx, %08lx\n", hwnd, wparam, lparam);
569             dump_minmax_info( minmax );
570             SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021);
571             break;
572         }
573         case WM_WINDOWPOSCHANGING:
574         {
575             BOOL is_win9x = GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == 0;
576             WINDOWPOS *winpos = (WINDOWPOS *)lparam;
577             trace("main: WM_WINDOWPOSCHANGING\n");
578             trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
579                    winpos->hwnd, winpos->hwndInsertAfter,
580                    winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
581             if (!(winpos->flags & SWP_NOMOVE))
582             {
583                 ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
584                 ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
585             }
586             /* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
587             if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
588             {
589                 ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
590                 ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
591             }
592             break;
593         }
594         case WM_WINDOWPOSCHANGED:
595         {
596             RECT rc1, rc2;
597             WINDOWPOS *winpos = (WINDOWPOS *)lparam;
598             trace("main: WM_WINDOWPOSCHANGED\n");
599             trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
600                    winpos->hwnd, winpos->hwndInsertAfter,
601                    winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
602             ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
603             ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
604 
605             ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
606             ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
607 
608             GetWindowRect(hwnd, &rc1);
609             trace("window: (%d,%d)-(%d,%d)\n", rc1.left, rc1.top, rc1.right, rc1.bottom);
610             SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
611             /* note: winpos coordinates are relative to parent */
612             MapWindowPoints(GetParent(hwnd), 0, (LPPOINT)&rc2, 2);
613             trace("pos: (%d,%d)-(%d,%d)\n", rc2.left, rc2.top, rc2.right, rc2.bottom);
614             if (0)
615             {
616             /* Uncomment this once the test succeeds in all cases */
617             ok(EqualRect(&rc1, &rc2), "rects do not match\n");
618             }
619 
620             GetClientRect(hwnd, &rc2);
621             DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)&rc1);
622             MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
623             ok(EqualRect(&rc1, &rc2), "rects do not match (%d,%d-%d,%d) / (%d,%d-%d,%d)\n",
624                rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom );
625             break;
626         }
627         case WM_NCCREATE:
628         {
629             BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
630             CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
631 
632             trace("WM_NCCREATE: hwnd %p, parent %p, style %08x\n", hwnd, cs->hwndParent, cs->style);
633             if (got_getminmaxinfo)
634                 trace("%p got WM_GETMINMAXINFO\n", hwnd);
635 
636             if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
637                 ok(got_getminmaxinfo, "main: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
638             else
639                 ok(!got_getminmaxinfo, "main: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
640             break;
641         }
642         case WM_COMMAND:
643             if (test_lbuttondown_flag)
644             {
645                 ShowWindow((HWND)wparam, SW_SHOW);
646                 flush_events( FALSE );
647             }
648             break;
649     }
650 
651     return DefWindowProcA(hwnd, msg, wparam, lparam);
652 }
653 
654 static LRESULT WINAPI tool_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
655 {
656     switch (msg)
657     {
658         case WM_GETMINMAXINFO:
659         {
660             MINMAXINFO* minmax = (MINMAXINFO *)lparam;
661 
662             trace("hwnd %p, WM_GETMINMAXINFO, %08lx, %08lx\n", hwnd, wparam, lparam);
663             dump_minmax_info( minmax );
664             SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021);
665             break;
666         }
667         case WM_NCCREATE:
668         {
669             BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
670             CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
671 
672             trace("WM_NCCREATE: hwnd %p, parent %p, style %08x\n", hwnd, cs->hwndParent, cs->style);
673             if (got_getminmaxinfo)
674                 trace("%p got WM_GETMINMAXINFO\n", hwnd);
675 
676             if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
677                 ok(got_getminmaxinfo, "tool: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
678             else
679                 ok(!got_getminmaxinfo, "tool: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
680             break;
681         }
682     }
683 
684     return DefWindowProcA(hwnd, msg, wparam, lparam);
685 }
686 
687 static BOOL RegisterWindowClasses(void)