ReactOS  0.4.14-dev-49-gfb4591c
win.c
Go to the documentation of this file.
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 #include "precomp.h"
24 
25 #ifndef SPI_GETDESKWALLPAPER
26 #define SPI_GETDESKWALLPAPER 0x0073
27 #endif
28 
29 #ifndef WM_SYSTIMER
30 #define WM_SYSTIMER 0x0118
31 #endif
32 
33 #define LONG_PTR INT_PTR
34 #define ULONG_PTR UINT_PTR
35 
36 void dump_region(HRGN hrgn);
37 
38 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
39 static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
40 static UINT (WINAPI *pGetWindowModuleFileNameA)(HWND,LPSTR,UINT);
41 static BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF*,BYTE*,DWORD*);
42 static BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
43 static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
44 static BOOL (WINAPI *pUpdateLayeredWindowIndirect)(HWND,const UPDATELAYEREDWINDOWINFO*);
45 static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
46 static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
47 static int (WINAPI *pGetWindowRgnBox)(HWND,LPRECT);
48 static BOOL (WINAPI *pGetGUIThreadInfo)(DWORD, GUITHREADINFO*);
49 static BOOL (WINAPI *pGetProcessDefaultLayout)( DWORD *layout );
50 static BOOL (WINAPI *pSetProcessDefaultLayout)( DWORD layout );
51 static BOOL (WINAPI *pFlashWindow)( HWND hwnd, BOOL bInvert );
52 static BOOL (WINAPI *pFlashWindowEx)( PFLASHWINFO pfwi );
53 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
54 static DWORD (WINAPI *pGetLayout)(HDC hdc);
55 static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn);
56 
62 static HHOOK hhook;
64 
65 static const char* szAWRClass = "Winsize";
66 static HMENU hmenu;
67 static DWORD our_pid;
68 
69 static BOOL is_win9x = FALSE;
70 
71 #define COUNTOF(arr) (sizeof(arr)/sizeof(arr[0]))
72 
73 static void dump_minmax_info( const MINMAXINFO *minmax )
74 {
75  trace("Reserved=%d,%d MaxSize=%d,%d MaxPos=%d,%d MinTrack=%d,%d MaxTrack=%d,%d\n",
76  minmax->ptReserved.x, minmax->ptReserved.y,
77  minmax->ptMaxSize.x, minmax->ptMaxSize.y,
78  minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
79  minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
80  minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
81 }
82 
83 /* try to make sure pending X events have been processed before continuing */
84 static void flush_events( BOOL remove_messages )
85 {
86  MSG msg;
87  int diff = 200;
88  int min_timeout = 100;
89  DWORD time = GetTickCount() + diff;
90 
91  while (diff > 0)
92  {
93  if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
94  if (remove_messages)
95  while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
96  diff = time - GetTickCount();
97  min_timeout = 50;
98  }
99 }
100 
102 {
103  DWORD end_time = GetTickCount() + timeout;
104  MSG msg;
105 
106  do {
108  return TRUE;
109  while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
111  timeout = end_time - GetTickCount();
112  }while(timeout > 0);
113 
114  return FALSE;
115 }
116 
117 /* check the values returned by the various parent/owner functions on a given window */
118 static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_parent,
119  HWND gw_owner, HWND ga_root, HWND ga_root_owner )
120 {
121  HWND res;
122 
123  if (pGetAncestor)
124  {
125  res = pGetAncestor( hwnd, GA_PARENT );
126  ok( res == ga_parent, "Wrong result for GA_PARENT %p expected %p\n", res, ga_parent );
127  }
129  ok( res == gwl_parent, "Wrong result for GWL_HWNDPARENT %p expected %p\n", res, gwl_parent );
130  res = GetParent( hwnd );
131  ok( res == get_parent, "Wrong result for GetParent %p expected %p\n", res, get_parent );
132  res = GetWindow( hwnd, GW_OWNER );
133  ok( res == gw_owner, "Wrong result for GW_OWNER %p expected %p\n", res, gw_owner );
134  if (pGetAncestor)
135  {
136  res = pGetAncestor( hwnd, GA_ROOT );
137  ok( res == ga_root, "Wrong result for GA_ROOT %p expected %p\n", res, ga_root );
138  res = pGetAncestor( hwnd, GA_ROOTOWNER );
139  ok( res == ga_root_owner, "Wrong result for GA_ROOTOWNER %p expected %p\n", res, ga_root_owner );
140  }
141 }
142 
143 #define check_wnd_state(a,b,c,d) check_wnd_state_(__FILE__,__LINE__,a,b,c,d)
144 static void check_wnd_state_(const char *file, int line,
145  HWND active, HWND foreground, HWND focus, HWND capture)
146 {
147  ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
148  /* only check foreground if it belongs to the current thread */
149  /* foreground can be moved to a different app pretty much at any time */
150  if (foreground && GetForegroundWindow() &&
152  ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
153  ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
154  ok_(file, line)(capture == GetCapture(), "GetCapture() = %p\n", GetCapture());
155 }
156 
157 /* same as above but without capture test */
158 #define check_active_state(a,b,c) check_active_state_(__FILE__,__LINE__,a,b,c)
159 static void check_active_state_(const char *file, int line,
160  HWND active, HWND foreground, HWND focus)
161 {
162  ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
163  /* only check foreground if it belongs to the current thread */
164  /* foreground can be moved to a different app pretty much at any time */
165  if (foreground && GetForegroundWindow() &&
167  ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
168  ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
169 }
170 
172 {
173  /* these are always ignored */
174  return (message >= 0xc000 ||
175  message == WM_GETICON ||
176  message == WM_GETOBJECT ||
177  message == WM_TIMER ||
178  message == WM_SYSTIMER ||
179  message == WM_TIMECHANGE ||
181 }
182 
184 {
185  (*(LPINT)lParam)++;
186  trace("EnumChildProc on %p\n", hwndChild);
187  if (*(LPINT)lParam > 1) return FALSE;
188  return TRUE;
189 }
190 
191 /* will search for the given window */
193 {
194  trace("EnumChildProc1 on %p\n", hwndChild);
195  if ((HWND)lParam == hwndChild) return FALSE;
196  return TRUE;
197 }
198 
200 {
201  HWND ret = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style,
202  0, 0, 100, 100, parent, 0, 0, NULL );
203  ok( ret != 0, "Creation failed\n" );
204  return ret;
205 }
206 
207 /* test parent and owner values for various combinations */
208 static void test_parent_owner(void)
209 {
210  LONG style;
211  HWND test, owner, ret;
212  HWND desktop = GetDesktopWindow();
214  INT numChildren;
215 
216  trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
217 
218  /* child without parent, should fail */
219  SetLastError(0xdeadbeef);
220  test = CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
221  WS_CHILD, 0, 0, 100, 100, 0, 0, 0, NULL );
222  ok( !test, "WS_CHILD without parent created\n" );
224  broken(GetLastError() == 0xdeadbeef), /* win9x */
225  "CreateWindowExA error %u\n", GetLastError() );
226 
227  /* desktop window */
228  check_parents( desktop, 0, 0, 0, 0, 0, 0 );
229  style = GetWindowLongA( desktop, GWL_STYLE );
230  ok( !SetWindowLongA( desktop, GWL_STYLE, WS_POPUP ), "Set GWL_STYLE on desktop succeeded\n" );
231  ok( !SetWindowLongA( desktop, GWL_STYLE, 0 ), "Set GWL_STYLE on desktop succeeded\n" );
232  ok( GetWindowLongA( desktop, GWL_STYLE ) == style, "Desktop style changed\n" );
233 
234  /* normal child window */
236  trace( "created child %p\n", test );
245  DestroyWindow( test );
246 
247  /* normal child window with WS_MAXIMIZE */
249  DestroyWindow( test );
250 
251  /* normal child window with WS_THICKFRAME */
253  DestroyWindow( test );
254 
255  /* popup window with WS_THICKFRAME */
257  DestroyWindow( test );
258 
259  /* child of desktop */
260  test = create_tool_window( WS_CHILD, desktop );
261  trace( "created child of desktop %p\n", test );
262  check_parents( test, desktop, 0, desktop, 0, test, desktop );
264  check_parents( test, desktop, 0, 0, 0, test, test );
266  check_parents( test, desktop, 0, 0, 0, test, test );
267  DestroyWindow( test );
268 
269  /* child of desktop with WS_MAXIMIZE */
271  DestroyWindow( test );
272 
273  /* child of desktop with WS_MINIMIZE */
275  DestroyWindow( test );
276 
277  /* child of child */
279  trace( "created child of child %p\n", test );
282  check_parents( test, child, child, 0, 0, hwndMain, test );
284  check_parents( test, child, child, 0, 0, hwndMain, test );
285  DestroyWindow( test );
286 
287  /* child of child with WS_MAXIMIZE */
289  DestroyWindow( test );
290 
291  /* child of child with WS_MINIMIZE */
293  DestroyWindow( test );
294 
295  /* not owned top-level window */
296  test = create_tool_window( 0, 0 );
297  trace( "created top-level %p\n", test );
298  check_parents( test, desktop, 0, 0, 0, test, test );
300  check_parents( test, desktop, 0, 0, 0, test, test );
302  check_parents( test, desktop, 0, desktop, 0, test, desktop );
303  DestroyWindow( test );
304 
305  /* not owned top-level window with WS_MAXIMIZE */
307  DestroyWindow( test );
308 
309  /* owned top-level window */
311  trace( "created owned top-level %p\n", test );
312  check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
316  check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
317  DestroyWindow( test );
318 
319  /* owned top-level window with WS_MAXIMIZE */
321  DestroyWindow( test );
322 
323  /* not owned popup */
325  trace( "created popup %p\n", test );
326  check_parents( test, desktop, 0, 0, 0, test, test );
328  check_parents( test, desktop, 0, desktop, 0, test, desktop );
330  check_parents( test, desktop, 0, 0, 0, test, test );
331  DestroyWindow( test );
332 
333  /* not owned popup with WS_MAXIMIZE */
335  DestroyWindow( test );
336 
337  /* owned popup */
339  trace( "created owned popup %p\n", test );
342  check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
344  check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
345  DestroyWindow( test );
346 
347  /* owned popup with WS_MAXIMIZE */
349  DestroyWindow( test );
350 
351  /* top-level window owned by child (same as owned by top-level) */
352  test = create_tool_window( 0, child );
353  trace( "created top-level owned by child %p\n", test );
354  check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
355  DestroyWindow( test );
356 
357  /* top-level window owned by child (same as owned by top-level) with WS_MAXIMIZE */
359  DestroyWindow( test );
360 
361  /* popup owned by desktop (same as not owned) */
362  test = create_tool_window( WS_POPUP, desktop );
363  trace( "created popup owned by desktop %p\n", test );
364  check_parents( test, desktop, 0, 0, 0, test, test );
365  DestroyWindow( test );
366 
367  /* popup owned by desktop (same as not owned) with WS_MAXIMIZE */
369  DestroyWindow( test );
370 
371  /* popup owned by child (same as owned by top-level) */
373  trace( "created popup owned by child %p\n", test );
375  DestroyWindow( test );
376 
377  /* popup owned by child (same as owned by top-level) with WS_MAXIMIZE */
379  DestroyWindow( test );
380 
381  /* not owned popup with WS_CHILD (same as WS_POPUP only) */
383  trace( "created WS_CHILD popup %p\n", test );
384  check_parents( test, desktop, 0, 0, 0, test, test );
385  DestroyWindow( test );
386 
387  /* not owned popup with WS_CHILD | WS_MAXIMIZE (same as WS_POPUP only) */
389  DestroyWindow( test );
390 
391  /* owned popup with WS_CHILD (same as WS_POPUP only) */
393  trace( "created owned WS_CHILD popup %p\n", test );
395  DestroyWindow( test );
396 
397  /* owned popup with WS_CHILD (same as WS_POPUP only) with WS_MAXIMIZE */
399  DestroyWindow( test );
400 
401  /******************** parent changes *************************/
402  trace( "testing parent changes\n" );
403 
404  /* desktop window */
405  check_parents( desktop, 0, 0, 0, 0, 0, 0 );
406  if (0)
407  {
408  /* this test succeeds on NT but crashes on win9x systems */
410  ok( !ret, "Set GWL_HWNDPARENT succeeded on desktop\n" );
411  check_parents( desktop, 0, 0, 0, 0, 0, 0 );
412  ok( !SetParent( desktop, hwndMain ), "SetParent succeeded on desktop\n" );
413  check_parents( desktop, 0, 0, 0, 0, 0, 0 );
414  }
415  /* normal child window */
417  trace( "created child %p\n", test );
418 
420  ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain );
422 
424  ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
426 
428  ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
429  check_parents( test, desktop, 0, desktop, 0, test, desktop );
430 
431  /* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */
432  if (!is_win9x)
433  {
435  ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
436  check_parents( test, desktop, 0, desktop, 0, test, desktop );
437  }
438  else
439  win_skip("Test creates circular window tree under Win9x/WinMe\n" );
440 
442  ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
443  check_parents( test, desktop, child, desktop, child, test, desktop );
444 
446  ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
447  check_parents( test, desktop, 0, desktop, 0, test, desktop );
448  DestroyWindow( test );
449 
450  /* not owned top-level window */
451  test = create_tool_window( 0, 0 );
452  trace( "created top-level %p\n", test );
453 
455  ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
456  check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
457 
459  ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
460  check_parents( test, desktop, child, 0, child, test, test );
461 
463  ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
464  check_parents( test, desktop, 0, 0, 0, test, test );
465  DestroyWindow( test );
466 
467  /* not owned popup */
469  trace( "created popup %p\n", test );
470 
472  ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
474 
476  ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
477  check_parents( test, desktop, child, child, child, test, hwndMain );
478 
480  ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
481  check_parents( test, desktop, 0, 0, 0, test, test );
482  DestroyWindow( test );
483 
484  /* normal child window */
486  trace( "created child %p\n", test );
487 
488  ret = SetParent( test, desktop );
489  ok( ret == hwndMain, "SetParent return value %p expected %p\n", ret, hwndMain );
490  check_parents( test, desktop, 0, desktop, 0, test, desktop );
491 
492  ret = SetParent( test, child );
493  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
495 
496  ret = SetParent( test, hwndMain2 );
497  ok( ret == child, "SetParent return value %p expected %p\n", ret, child );
499  DestroyWindow( test );
500 
501  /* not owned top-level window */
502  test = create_tool_window( 0, 0 );
503  trace( "created top-level %p\n", test );
504 
505  ret = SetParent( test, child );
506  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
507  check_parents( test, child, child, 0, 0, hwndMain, test );
508 
509  if (!is_win9x)
510  {
511  ShowWindow( test, SW_SHOW );
512  ret = SetParent( test, test );
513  ok( ret == NULL, "SetParent return value %p expected %p\n", ret, NULL );
514  ok( GetWindowLongA( test, GWL_STYLE ) & WS_VISIBLE, "window is not visible after SetParent\n" );
515  check_parents( test, child, child, 0, 0, hwndMain, test );
516  }
517  else
518  win_skip( "Test crashes on Win9x/WinMe\n" );
519  DestroyWindow( test );
520 
521  /* owned popup */
523  trace( "created owned popup %p\n", test );
524 
525  ret = SetParent( test, child );
526  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
528 
530  ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
532  DestroyWindow( test );
533 
534  /**************** test owner destruction *******************/
535 
536  /* owned child popup */
537  owner = create_tool_window( 0, 0 );
538  test = create_tool_window( WS_POPUP, owner );
539  trace( "created owner %p and popup %p\n", owner, test );
540  ret = SetParent( test, child );
541  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
542  check_parents( test, child, child, owner, owner, hwndMain, owner );
543  /* window is now child of 'child' but owned by 'owner' */
544  DestroyWindow( owner );
545  ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
546  /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
547  * while Win95, Win2k, WinXP do.
548  */
549  /*check_parents( test, child, child, owner, owner, hwndMain, owner );*/
550  ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
552 
553  /* owned top-level popup */
554  owner = create_tool_window( 0, 0 );
555  test = create_tool_window( WS_POPUP, owner );
556  trace( "created owner %p and popup %p\n", owner, test );
557  check_parents( test, desktop, owner, owner, owner, test, owner );
558  DestroyWindow( owner );
559  ok( !IsWindow(test), "Window %p not destroyed by owner destruction\n", test );
560 
561  /* top-level popup owned by child */
564  trace( "created owner %p and popup %p\n", owner, test );
566  ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
567  check_parents( test, desktop, owner, owner, owner, test, hwndMain2 );
568  DestroyWindow( owner );
569  ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
570  ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
571  /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
572  * while Win95, Win2k, WinXP do.
573  */
574  /*check_parents( test, desktop, owner, owner, owner, test, owner );*/
576 
577  /* final cleanup */
579 
580 
581  owner = create_tool_window( WS_OVERLAPPED, 0 );
582  test = create_tool_window( WS_POPUP, desktop );
583 
584  ok( !GetWindow( test, GW_OWNER ), "Wrong owner window\n" );
585  numChildren = 0;
586  ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
587  "EnumChildWindows should have returned FALSE\n" );
588  ok( numChildren == 0, "numChildren should be 0 got %d\n", numChildren );
589 
591  ret = SetParent( test, owner );
592  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
593 
594  numChildren = 0;
595  ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
596  "EnumChildWindows should have returned TRUE\n" );
597  ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
598 
599  child = create_tool_window( WS_CHILD, owner );
600  numChildren = 0;
601  ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
602  "EnumChildWindows should have returned FALSE\n" );
603  ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
604  DestroyWindow( child );
605 
607  ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
608  numChildren = 0;
609  ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
610  "EnumChildWindows should have returned TRUE\n" );
611  ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
612 
613  ret = SetParent( child, owner );
614  ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
615  ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
616  numChildren = 0;
617  ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
618  "EnumChildWindows should have returned FALSE\n" );
619  ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
620 
621  ret = SetParent( child, NULL );
622  ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
623  ok( ret == owner, "SetParent return value %p expected %p\n", ret, owner );
624  numChildren = 0;
625  ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
626  "EnumChildWindows should have returned TRUE\n" );
627  ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
628 
629  /* even GW_OWNER == owner it's still a desktop's child */
631  "EnumChildWindows should have found %p and returned FALSE\n", child );
632 
633  DestroyWindow( child );
635 
637  "EnumChildWindows should have found %p and returned FALSE\n", child );
638 
639  DestroyWindow( child );
640  DestroyWindow( test );
641  DestroyWindow( owner );
642 
643  /* Test that owner window takes into account WS_CHILD flag even if parent is set by SetParent. */
644  owner = create_tool_window( WS_VISIBLE | WS_OVERLAPPEDWINDOW, desktop );
645  SetParent(owner, hwndMain);
646  check_parents( owner, hwndMain, hwndMain, NULL, NULL, hwndMain, owner );
648  check_parents( test, desktop, owner, NULL, owner, test, test );
649  DestroyWindow( owner );
650  DestroyWindow( test );
651 
652  owner = create_tool_window( WS_VISIBLE | WS_CHILD, desktop );
653  SetParent(owner, hwndMain);
656  check_parents( test, desktop, hwndMain, NULL, hwndMain, test, test );
657  DestroyWindow( owner );
658  DestroyWindow( test );
659 
660  owner = create_tool_window( WS_VISIBLE | WS_POPUP | WS_CHILD, desktop );
661  SetParent(owner, hwndMain);
662  check_parents( owner, hwndMain, hwndMain, NULL, NULL, hwndMain, owner );
664  check_parents( test, desktop, owner, NULL, owner, test, test );
665  DestroyWindow( owner );
666  DestroyWindow( test );
667 }
668 
670 {
671  (*(LPINT)lParam)++;
672  if (*(LPINT)lParam > 2) return FALSE;
673  return TRUE;
674 }
675 static DWORD CALLBACK enum_thread( void *arg )
676 {
677  INT count;
678  HWND hwnd[3];
679  BOOL ret;
680  MSG msg;
681 
682  if (pGetGUIThreadInfo)
683  {
685  info.cbSize = sizeof(info);
686  ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
687  ok( ret || broken(!ret), /* win9x */
688  "GetGUIThreadInfo failed without message queue\n" );
689  SetLastError( 0xdeadbeef );
690  info.cbSize = sizeof(info) + 1;
691  ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
692  ok( !ret, "GetGUIThreadInfo succeeded with wrong size\n" );
694  broken(GetLastError() == 0xdeadbeef), /* win9x */
695  "wrong error %u\n", GetLastError() );
696  }
697 
698  PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ); /* make sure we have a message queue */
699 
700  count = 0;
702  ok( ret, "EnumThreadWindows should have returned TRUE\n" );
703  ok( count == 0, "count should be 0 got %d\n", count );
704 
705  hwnd[0] = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", WS_POPUP,
706  0, 0, 100, 100, 0, 0, 0, NULL );
707  count = 0;
709  ok( ret, "EnumThreadWindows should have returned TRUE\n" );
710  if (count != 2) /* Vista gives us two windows for the price of one */
711  {
712  ok( count == 1, "count should be 1 got %d\n", count );
713  hwnd[2] = CreateWindowExA(0, "ToolWindowClass", "Tool window 2", WS_POPUP,
714  0, 0, 100, 100, 0, 0, 0, NULL );
715  }
716  else hwnd[2] = 0;
717 
718  hwnd[1] = CreateWindowExA(0, "ToolWindowClass", "Tool window 3", WS_POPUP,
719  0, 0, 100, 100, 0, 0, 0, NULL );
720  count = 0;
722  ok( !ret, "EnumThreadWindows should have returned FALSE\n" );
723  ok( count == 3, "count should be 3 got %d\n", count );
724 
725  if (hwnd[2]) DestroyWindow(hwnd[2]);
726  DestroyWindow(hwnd[1]);
727  DestroyWindow(hwnd[0]);
728  return 0;
729 }
730 
731 /* test EnumThreadWindows in a separate thread */
732 static void test_enum_thread_windows(void)
733 {
734  DWORD id;
735  HANDLE handle = CreateThread( NULL, 0, enum_thread, 0, 0, &id );
736  ok( !WaitForSingleObject( handle, 10000 ), "wait failed\n" );
737  CloseHandle( handle );
738 }
739 
741 {
742  BOOL enabled; /* when 1 bypasses default procedure */
743  char *buff; /* expected text buffer pointer */
744  WCHAR *buffW; /* same, for W test */
746 
748 {
749  switch (msg)
750  {
751  case WM_GETMINMAXINFO:
752  {
753  SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021);
754  break;
755  }
757  {
758  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
759  if (!(winpos->flags & SWP_NOMOVE))
760  {
761  ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
762  ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
763  }
764  /* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
765  if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
766  {
767  ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
768  winpos->cx == 32768, /* win7 doesn't truncate */
769  "bad winpos->cx %d\n", winpos->cx);
770  ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
771  winpos->cy == 40000, /* win7 doesn't truncate */
772  "bad winpos->cy %d\n", winpos->cy);
773  }
774  break;
775  }
776  case WM_WINDOWPOSCHANGED:
777  {
778  RECT rc1, rc2;
779  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
780  ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
781  ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
782 
783  ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
784  winpos->cx == 32768, /* win7 doesn't truncate */
785  "bad winpos->cx %d\n", winpos->cx);
786  ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
787  winpos->cy == 40000, /* win7 doesn't truncate */
788  "bad winpos->cy %d\n", winpos->cy);
789 
790  GetWindowRect(hwnd, &rc1);
791  SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
792  /* note: winpos coordinates are relative to parent */
794  if (0)
795  {
796  /* Uncomment this once the test succeeds in all cases */
797  ok(EqualRect(&rc1, &rc2), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc1),
799 
802  MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
803  ok(EqualRect(&rc1, &rc2), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc1),
805  }
806  break;
807  }
808  case WM_NCCREATE:
809  {
810  BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
812 
813  if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
814  ok(got_getminmaxinfo, "main: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
815  else
816  ok(!got_getminmaxinfo, "main: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
817  break;
818  }
819  case WM_COMMAND:
821  {
823  flush_events( FALSE );
824  }
825  break;
826  case WM_GETTEXT:
828  if (g_wm_gettext_override.enabled)
829  {
830  char *text = (char*)lparam;
831  ok(g_wm_gettext_override.buff == text, "expected buffer %p, got %p\n", g_wm_gettext_override.buff, text);
832  ok(*text == 0, "expected empty string buffer %x\n", *text);
833  return 0;
834  }
835  break;
836  case WM_SETTEXT:
838  break;
839  case WM_ACTIVATEAPP:
840  if (wparam) app_activated = TRUE;
841  else app_deactivated = TRUE;
842  break;
843  }
844 
845  return DefWindowProcA(hwnd, msg, wparam, lparam);
846 }
847 
849 {
850  switch (msg)
851  {
852  case WM_GETTEXT:
854  if (g_wm_gettext_override.enabled)
855  {
856  WCHAR *text = (WCHAR*)lparam;
857  ok(g_wm_gettext_override.buffW == text, "expected buffer %p, got %p\n", g_wm_gettext_override.buffW, text);
858  ok(*text == 0, "expected empty string buffer %x\n", *text);
859  return 0;
860  }
861  break;
862  }
863 
864  return DefWindowProcA(hwnd, msg, wparam, lparam);
865 }
866 
868 {
869  switch (msg)
870  {
871  case WM_GETMINMAXINFO:
872  {
873  SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021);
874  break;
875  }
876  case WM_NCCREATE:
877  {
878  BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
880 
881  if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
882  ok(got_getminmaxinfo, "tool: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
883  else
884  ok(!got_getminmaxinfo, "tool: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
885  break;
886  }
887  }
888 
889  return DefWindowProcA(hwnd, msg, wparam, lparam);
890 }
891 
892 static const WCHAR mainclassW[] = {'M','a','i','n','W','i','n','d','o','w','C','l','a','s','s','W',0};
893 
895 {
896  WNDCLASSW clsW;
897  WNDCLASSA cls;
898 
899  cls.style = CS_DBLCLKS;
901  cls.cbClsExtra = 0;
902  cls.cbWndExtra = 0;
903  cls.hInstance = GetModuleHandleA(0);
904  cls.hIcon = 0;
905  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
907  cls.lpszMenuName = NULL;
908  cls.lpszClassName = "MainWindowClass";
909 
910  if(!RegisterClassA(&cls)) return FALSE;
911 
912  clsW.style = CS_DBLCLKS;
914  clsW.cbClsExtra = 0;
915  clsW.cbWndExtra = 0;
916  clsW.hInstance = GetModuleHandleA(0);
917  clsW.hIcon = 0;
918  clsW.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
920  clsW.lpszMenuName = NULL;
921  clsW.lpszClassName = mainclassW;
922 
923  if(!RegisterClassW(&clsW)) return FALSE;
924 
925  cls.style = 0;
927  cls.cbClsExtra = 0;
928  cls.cbWndExtra = 0;
929  cls.hInstance = GetModuleHandleA(0);
930  cls.hIcon = 0;
931  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
933  cls.lpszMenuName = NULL;
934  cls.lpszClassName = "ToolWindowClass";
935 
936  if(!RegisterClassA(&cls)) return FALSE;
937 
938  return TRUE;
939 }
940 
941 static void verify_window_info(const char *hook, HWND hwnd, const WINDOWINFO *info)
942 {
943  RECT rcWindow, rcClient;
944  DWORD status;
945 
946  ok(IsWindow(hwnd), "bad window handle %p in hook %s\n", hwnd, hook);
947 
948  GetWindowRect(hwnd, &rcWindow);
949  ok(EqualRect(&rcWindow, &info->rcWindow), "wrong rcWindow for %p in hook %s\n", hwnd, hook);
950 
951  GetClientRect(hwnd, &rcClient);
952  /* translate to screen coordinates */
953  MapWindowPoints(hwnd, 0, (LPPOINT)&rcClient, 2);
954  ok(EqualRect(&rcClient, &info->rcClient), "wrong rcClient for %p in hook %s\n", hwnd, hook);
955 
956  ok(info->dwStyle == (DWORD)GetWindowLongA(hwnd, GWL_STYLE),
957  "wrong dwStyle: %08x != %08x for %p in hook %s\n",
958  info->dwStyle, GetWindowLongA(hwnd, GWL_STYLE), hwnd, hook);
959  /* Windows reports some undocumented exstyles in WINDOWINFO, but
960  * doesn't return them in GetWindowLong(hwnd, GWL_EXSTYLE).
961  */
962  ok((info->dwExStyle & ~0xe0000800) == (DWORD)GetWindowLongA(hwnd, GWL_EXSTYLE),
963  "wrong dwExStyle: %08x != %08x for %p in hook %s\n",
964  info->dwExStyle, GetWindowLongA(hwnd, GWL_EXSTYLE), hwnd, hook);
966  if (GetForegroundWindow())
967  ok(info->dwWindowStatus == status, "wrong dwWindowStatus: %04x != %04x active %p fg %p in hook %s\n",
968  info->dwWindowStatus, status, GetActiveWindow(), GetForegroundWindow(), hook);
969 
970  /* win2k and XP return broken border info in GetWindowInfo most of
971  * the time, so there is no point in testing it.
972  */
973 if (0)
974 {
975  UINT border;
976  ok(info->cxWindowBorders == (unsigned)(rcClient.left - rcWindow.left),
977  "wrong cxWindowBorders %d != %d\n", info->cxWindowBorders, rcClient.left - rcWindow.left);
978  border = min(rcWindow.bottom - rcClient.bottom, rcClient.top - rcWindow.top);
979  ok(info->cyWindowBorders == border,
980  "wrong cyWindowBorders %d != %d\n", info->cyWindowBorders, border);
981 }
982  ok(info->atomWindowType == GetClassLongA(hwnd, GCW_ATOM), "wrong atomWindowType for %p in hook %s\n",
983  hwnd, hook);
984  ok(info->wCreatorVersion == 0x0400 /* NT4, Win2000, XP, Win2003 */ ||
985  info->wCreatorVersion == 0x0500 /* Vista */,
986  "wrong wCreatorVersion %04x for %p in hook %s\n", info->wCreatorVersion, hwnd, hook);
987 }
988 
989 static void FixedAdjustWindowRectEx(RECT* rc, LONG style, BOOL menu, LONG exstyle)
990 {
991  AdjustWindowRectEx(rc, style, menu, exstyle);
992  /* AdjustWindowRectEx does not include scroll bars */
993  if (style & WS_VSCROLL)
994  {
995  if(exstyle & WS_EX_LEFTSCROLLBAR)
997  else
999  }
1000  if (style & WS_HSCROLL)
1002 }
1003 
1004 /* reimplement it to check that the Wine algorithm gives the correct result */
1005 static void wine_AdjustWindowRectEx( RECT *rect, LONG style, BOOL menu, LONG exStyle )
1006 {
1007  int adjust;
1008 
1009  if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
1011  {
1012  adjust = 1; /* for the outer frame always present */
1013  }
1014  else
1015  {
1016  adjust = 0;
1017  if ((exStyle & WS_EX_DLGMODALFRAME) ||
1018  (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
1019  }
1020  if (style & WS_THICKFRAME)
1021  adjust += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); /* The resize border */
1022  if ((style & (WS_BORDER|WS_DLGFRAME)) ||
1023  (exStyle & WS_EX_DLGMODALFRAME))
1024  adjust++; /* The other border */
1025 
1026  InflateRect (rect, adjust, adjust);
1027 
1028  if ((style & WS_CAPTION) == WS_CAPTION)
1029  {
1030  if (exStyle & WS_EX_TOOLWINDOW)
1032  else
1034  }
1035  if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
1036 
1037  if (exStyle & WS_EX_CLIENTEDGE)
1039 
1040  if (style & WS_VSCROLL)
1041  {
1042  if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
1044  else
1045  rect->right += GetSystemMetrics(SM_CXVSCROLL);
1046  }
1047  if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
1048 }
1049 
1051 {
1052  DWORD style, exstyle;
1053  RECT rc_window, rc_client, rc;
1054  BOOL menu;
1055  LRESULT ret;
1056 
1058  exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1059  menu = !(style & WS_CHILD) && GetMenu(hwnd) != 0;
1060 
1061  GetWindowRect(hwnd, &rc_window);
1062  GetClientRect(hwnd, &rc_client);
1063 
1064  /* avoid some cases when things go wrong */
1065  if (IsRectEmpty(&rc_window) || IsRectEmpty(&rc_client) ||
1066  rc_window.right > 32768 || rc_window.bottom > 32768) return;
1067 
1068  rc = rc_client;
1069  MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
1070  FixedAdjustWindowRectEx(&rc, style, menu, exstyle);
1071 
1072  ok(EqualRect(&rc, &rc_window),
1073  "window rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, win=%s, calc=%s\n",
1074  style, exstyle, menu, wine_dbgstr_rect(&rc_window), wine_dbgstr_rect(&rc));
1075 
1076  rc = rc_client;
1077  MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
1078  wine_AdjustWindowRectEx(&rc, style, menu, exstyle);
1079  ok(EqualRect(&rc, &rc_window),
1080  "window rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, win=%s, calc=%s\n",
1081  style, exstyle, menu, wine_dbgstr_rect(&rc_window), wine_dbgstr_rect(&rc));
1082 
1083 
1084  rc = rc_window;
1086  MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
1087  ok(EqualRect(&rc, &rc_client),
1088  "client rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d client=%s, calc=%s\n",
1089  style, exstyle, menu, wine_dbgstr_rect(&rc_client), wine_dbgstr_rect(&rc));
1090 
1091  /* NULL rectangle shouldn't crash */
1093  ok(ret == 0, "NULL rectangle returned %ld instead of 0\n", ret);
1094 
1095  /* Win9x doesn't like WM_NCCALCSIZE with synthetic data and crashes */;
1096  if (is_win9x)
1097  return;
1098 
1099  /* and now test AdjustWindowRectEx and WM_NCCALCSIZE on synthetic data */
1100  SetRect(&rc_client, 0, 0, 250, 150);
1101  rc_window = rc_client;
1102  MapWindowPoints(hwnd, 0, (LPPOINT)&rc_window, 2);
1103  FixedAdjustWindowRectEx(&rc_window, style, menu, exstyle);
1104 
1105  rc = rc_window;
1107  MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
1108  ok(EqualRect(&rc, &rc_client),
1109  "synthetic rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, client=%s, calc=%s\n",
1110  style, exstyle, menu, wine_dbgstr_rect(&rc_client), wine_dbgstr_rect(&rc));
1111 }
1112 
1114 {
1115  static const char *CBT_code_name[10] = {
1116  "HCBT_MOVESIZE",
1117  "HCBT_MINMAX",
1118  "HCBT_QS",
1119  "HCBT_CREATEWND",
1120  "HCBT_DESTROYWND",
1121  "HCBT_ACTIVATE",
1122  "HCBT_CLICKSKIPPED",
1123  "HCBT_KEYSKIPPED",
1124  "HCBT_SYSCOMMAND",
1125  "HCBT_SETFOCUS" };
1126  const char *code_name = (nCode >= 0 && nCode <= HCBT_SETFOCUS) ? CBT_code_name[nCode] : "Unknown";
1127  HWND hwnd = (HWND)wParam;
1128 
1129  switch (nCode)
1130  {
1131  case HCBT_CREATEWND:
1132  {
1133  static const RECT rc_null;
1134  RECT rc;
1135  LONG style;
1136  CBT_CREATEWNDA *createwnd = (CBT_CREATEWNDA *)lParam;
1137  ok(createwnd->hwndInsertAfter == HWND_TOP, "hwndInsertAfter should be always HWND_TOP\n");
1138 
1139  if (pGetWindowInfo)
1140  {
1141  WINDOWINFO info;
1142  info.cbSize = sizeof(WINDOWINFO);
1143  ok(pGetWindowInfo(hwnd, &info), "GetWindowInfo should not fail\n");
1144  verify_window_info(code_name, hwnd, &info);
1145  }
1146 
1147  /* WS_VISIBLE should be turned off yet */
1148  style = createwnd->lpcs->style & ~WS_VISIBLE;
1150  "style of hwnd and style in the CREATESTRUCT do not match: %08x != %08x\n",
1152 
1153  if (0)
1154  {
1155  /* Uncomment this once the test succeeds in all cases */
1156  if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
1157  {
1159  "wrong result from GetParent %p: message window %p\n",
1161  }
1162  else
1163  ok(!GetParent(hwnd), "GetParent should return 0 at this point\n");
1164 
1165  ok(!GetWindow(hwnd, GW_OWNER), "GW_OWNER should be set to 0 at this point\n");
1166  }
1167  if (0)
1168  {
1169  /* while NT assigns GW_HWNDFIRST/LAST some values at this point,
1170  * Win9x still has them set to 0.
1171  */
1172  ok(GetWindow(hwnd, GW_HWNDFIRST) != 0, "GW_HWNDFIRST should not be set to 0 at this point\n");
1173  ok(GetWindow(hwnd, GW_HWNDLAST) != 0, "GW_HWNDLAST should not be set to 0 at this point\n");
1174  }
1175  ok(!GetWindow(hwnd, GW_HWNDPREV), "GW_HWNDPREV should be set to 0 at this point\n");
1176  ok(!GetWindow(hwnd, GW_HWNDNEXT), "GW_HWNDNEXT should be set to 0 at this point\n");
1177 
1178  if (0)
1179  {
1180  /* Uncomment this once the test succeeds in all cases */
1181  if (pGetAncestor)
1182  {
1183  ok(pGetAncestor(hwnd, GA_PARENT) == hwndMessage, "GA_PARENT should be set to hwndMessage at this point\n");
1184  ok(pGetAncestor(hwnd, GA_ROOT) == hwnd,
1185  "GA_ROOT is set to %p, expected %p\n", pGetAncestor(hwnd, GA_ROOT), hwnd);
1186 
1187  if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
1188  ok(pGetAncestor(hwnd, GA_ROOTOWNER) == hwndMessage,
1189  "GA_ROOTOWNER should be set to hwndMessage at this point\n");
1190  else
1191  ok(pGetAncestor(hwnd, GA_ROOTOWNER) == hwnd,
1192  "GA_ROOTOWNER is set to %p, expected %p\n", pGetAncestor(hwnd, GA_ROOTOWNER), hwnd);
1193  }
1194 
1195  ok(GetWindowRect(hwnd, &rc), "GetWindowRect failed\n");
1196  ok(EqualRect(&rc, &rc_null), "window rect should be set to 0 HCBT_CREATEWND\n");
1197  ok(GetClientRect(hwnd, &rc), "GetClientRect failed\n");
1198  ok(EqualRect(&rc, &rc_null), "client rect should be set to 0 on HCBT_CREATEWND\n");
1199  }
1200  break;
1201  }
1202  case HCBT_MOVESIZE:
1203  case HCBT_MINMAX:
1204  case HCBT_ACTIVATE:
1205  if (pGetWindowInfo && IsWindow(hwnd))
1206  {
1207  WINDOWINFO info;
1208 
1209  /* Win98 actually does check the info.cbSize and doesn't allow
1210  * it to be anything except sizeof(WINDOWINFO), while Win95, Win2k,
1211  * WinXP do not check it at all.
1212  */
1213  info.cbSize = sizeof(WINDOWINFO);
1214  ok(pGetWindowInfo(hwnd, &info), "GetWindowInfo should not fail\n");
1215  verify_window_info(code_name, hwnd, &info);
1216  }
1217  break;
1218  /* window state is undefined */
1219  case HCBT_SETFOCUS:
1220  case HCBT_DESTROYWND:
1221  break;
1222  default:
1223  break;
1224  }
1225 
1226  return CallNextHookEx(hhook, nCode, wParam, lParam);
1227 }
1228 
1229 static void test_shell_window(void)
1230 {
1231  BOOL ret;
1232  DWORD error;
1233  HMODULE hinst, hUser32;
1235  HWND hwnd1, hwnd2, hwnd3, hwnd4, hwnd5;
1236  HWND shellWindow, nextWnd;
1237 
1238  if (is_win9x)
1239  {
1240  win_skip("Skipping shell window test on Win9x\n");
1241  return;
1242  }
1243 
1244  shellWindow = GetShellWindow();
1246  hUser32 = GetModuleHandleA("user32");
1247 
1248  SetShellWindow = (void *)GetProcAddress(hUser32, "SetShellWindow");
1249 
1250  trace("previous shell window: %p\n", shellWindow);
1251 
1252  if (shellWindow) {
1253  DWORD pid;
1254  HANDLE hProcess;
1255 
1256  GetWindowThreadProcessId(shellWindow, &pid);
1258  if (!hProcess)
1259  {
1260  skip( "cannot get access to shell process\n" );
1261  return;
1262  }
1263 
1264  SetLastError(0xdeadbeef);
1265  ret = DestroyWindow(shellWindow);
1266  error = GetLastError();
1267 
1268  ok(!ret, "DestroyWindow(shellWindow)\n");
1269  /* passes on Win XP, but not on Win98 */
1270  ok(error==ERROR_ACCESS_DENIED || error == 0xdeadbeef,
1271  "got %u after DestroyWindow(shellWindow)\n", error);
1272 
1273  /* close old shell instance */
1275  ok(ret, "termination of previous shell process failed: GetLastError()=%d\n", GetLastError());
1276  WaitForSingleObject(hProcess, INFINITE); /* wait for termination */
1278  }
1279 
1280  hwnd1 = CreateWindowExA(0, "#32770", "TEST1", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 100, 100, 300, 200, 0, 0, hinst, 0);
1281  trace("created window 1: %p\n", hwnd1);
1282 
1283  ret = SetShellWindow(hwnd1);
1284  ok(ret, "first call to SetShellWindow(hwnd1)\n");
1285  shellWindow = GetShellWindow();
1286  ok(shellWindow==hwnd1, "wrong shell window: %p\n", shellWindow);
1287 
1288  ret = SetShellWindow(hwnd1);
1289  ok(!ret, "second call to SetShellWindow(hwnd1)\n");
1290 
1291  ret = SetShellWindow(0);
1292  error = GetLastError();
1293  /* passes on Win XP, but not on Win98
1294  ok(!ret, "reset shell window by SetShellWindow(0)\n");
1295  ok(error==ERROR_INVALID_WINDOW_HANDLE, "ERROR_INVALID_WINDOW_HANDLE after SetShellWindow(0)\n"); */
1296 
1297  ret = SetShellWindow(hwnd1);
1298  /* passes on Win XP, but not on Win98
1299  ok(!ret, "third call to SetShellWindow(hwnd1)\n"); */
1300 
1302  ret = (GetWindowLongA(hwnd1,GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
1303  ok(!ret, "SetWindowExStyle(hwnd1, WS_EX_TOPMOST)\n");
1304 
1305  ret = DestroyWindow(hwnd1);
1306  ok(ret, "DestroyWindow(hwnd1)\n");
1307 
1308  hwnd2 = CreateWindowExA(WS_EX_TOPMOST, "#32770", "TEST2", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 150, 250, 300, 200, 0, 0, hinst, 0);
1309  trace("created window 2: %p\n", hwnd2);
1310  ret = SetShellWindow(hwnd2);
1311  ok(!ret, "SetShellWindow(hwnd2) with WS_EX_TOPMOST\n");
1312 
1313  hwnd3 = CreateWindowExA(0, "#32770", "TEST3", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 200, 400, 300, 200, 0, 0, hinst, 0);
1314  trace("created window 3: %p\n", hwnd3);
1315 
1316  hwnd4 = CreateWindowExA(0, "#32770", "TEST4", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 250, 500, 300, 200, 0, 0, hinst, 0);
1317  trace("created window 4: %p\n", hwnd4);
1318 
1319  nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1320  ok(nextWnd==hwnd3, "wrong next window for hwnd4: %p - expected hwnd3\n", nextWnd);
1321 
1322  ret = SetShellWindow(hwnd4);
1323  ok(ret, "SetShellWindow(hwnd4)\n");
1324  shellWindow = GetShellWindow();
1325  ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4\n", shellWindow);
1326 
1327  nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1328  ok(nextWnd==0, "wrong next window for hwnd4: %p - expected 0\n", nextWnd);
1329 
1330  ret = SetWindowPos(hwnd4, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1331  ok(ret, "SetWindowPos(hwnd4, HWND_TOPMOST)\n");
1332 
1333  ret = SetWindowPos(hwnd4, hwnd3, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1334  ok(ret, "SetWindowPos(hwnd4, hwnd3\n");
1335 
1336  ret = SetShellWindow(hwnd3);
1337  ok(!ret, "SetShellWindow(hwnd3)\n");
1338  shellWindow = GetShellWindow();
1339  ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4\n", shellWindow);
1340 
1341  hwnd5 = CreateWindowExA(0, "#32770", "TEST5", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 300, 600, 300, 200, 0, 0, hinst, 0);
1342  trace("created window 5: %p\n", hwnd5);
1343  ret = SetWindowPos(hwnd4, hwnd5, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1344  ok(ret, "SetWindowPos(hwnd4, hwnd5)\n");
1345 
1346  todo_wine
1347  {
1348  nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1349  ok(nextWnd==0, "wrong next window for hwnd4 after SetWindowPos(): %p - expected 0\n", nextWnd);
1350  }
1351 
1352  /* destroy test windows */
1353  DestroyWindow(hwnd2);
1354  DestroyWindow(hwnd3);
1355  DestroyWindow(hwnd4);
1356  DestroyWindow(hwnd5);
1357 }
1358 
1359 /************** MDI test ****************/
1360 
1361 static char mdi_lParam_test_message[] = "just a test string";
1362 
1364 {
1365  MDICREATESTRUCTA mdi_cs;
1366  HWND mdi_child, hwnd, exp_hwnd;
1367  INT_PTR id;
1368  static const WCHAR classW[] = {'M','D','I','_','c','h','i','l','d','_','C','l','a','s','s','_','1',0};
1369  static const WCHAR titleW[] = {'M','D','I',' ','c','h','i','l','d',0};
1370  BOOL isWin9x = FALSE;
1371  HMENU frame_menu = GetMenu(parent);
1372 
1373  ok(frame_menu != NULL, "Frame window didn't have a menu\n");
1374 
1375  mdi_cs.szClass = "MDI_child_Class_1";
1376  mdi_cs.szTitle = "MDI child";
1377  mdi_cs.hOwner = GetModuleHandleA(NULL);
1378  mdi_cs.x = CW_USEDEFAULT;
1379  mdi_cs.y = CW_USEDEFAULT;
1380  mdi_cs.cx = CW_USEDEFAULT;
1381  mdi_cs.cy = CW_USEDEFAULT;
1382  mdi_cs.style = 0;
1384  mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1385  ok(mdi_child != 0, "MDI child creation failed\n");
1386  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1387  ok(id == first_id, "wrong child id %ld\n", id);
1389  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1390  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1391  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1392  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1393 
1394  mdi_cs.style = 0x7fffffff; /* without WS_POPUP */
1395  mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1396  ok(mdi_child != 0, "MDI child creation failed\n");
1397  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1398  ok(id == first_id, "wrong child id %ld\n", id);
1400  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1401  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1402  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1403 
1404  mdi_cs.style = 0xffffffff; /* with WS_POPUP */
1405  mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1407  {
1408  ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1409  }
1410  else
1411  {
1412  ok(mdi_child != 0, "MDI child creation failed\n");
1413  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1414  ok(id == first_id, "wrong child id %ld\n", id);
1416  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1417  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1418  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1419  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1420  }
1421 
1422  /* test MDICREATESTRUCT A<->W mapping */
1423  /* MDICREATESTRUCTA and MDICREATESTRUCTW have the same layout */
1424  mdi_cs.style = 0;
1425  mdi_cs.szClass = (LPCSTR)classW;
1426  mdi_cs.szTitle = (LPCSTR)titleW;
1427  SetLastError(0xdeadbeef);
1428  mdi_child = (HWND)SendMessageW(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1429  if (!mdi_child)
1430  {
1432  isWin9x = TRUE;
1433  else
1434  ok(mdi_child != 0, "MDI child creation failed\n");
1435  }
1436  else
1437  {
1438  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1439  ok(id == first_id, "wrong child id %ld\n", id);
1441  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1442  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1443  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1444  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1445  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1446  }
1447 
1448  mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1449  0,
1454  ok(mdi_child != 0, "MDI child creation failed\n");
1455  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1456  ok(id == first_id, "wrong child id %ld\n", id);
1458  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1459  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1460  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1461  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1462  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1463 
1464  mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1465  0x7fffffff, /* without WS_POPUP */
1470  ok(mdi_child != 0, "MDI child creation failed\n");
1471  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1472  ok(id == first_id, "wrong child id %ld\n", id);
1474  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1475  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1476  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1477  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1478 
1479  mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1480  0xffffffff, /* with WS_POPUP */
1486  {
1487  ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1488  }
1489  else
1490  {
1491  ok(mdi_child != 0, "MDI child creation failed\n");
1492  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1493  ok(id == first_id, "wrong child id %ld\n", id);
1495  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1496  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1497  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1498  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1499  }
1500 
1501  /* test MDICREATESTRUCT A<->W mapping */
1502  SetLastError(0xdeadbeef);
1503  mdi_child = CreateMDIWindowW(classW, titleW,
1504  0,
1509  if (!mdi_child)
1510  {
1512  isWin9x = TRUE;
1513  else
1514  ok(mdi_child != 0, "MDI child creation failed\n");
1515  }
1516  else
1517  {
1518  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1519  ok(id == first_id, "wrong child id %ld\n", id);
1521  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1522  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1523  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1524  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1525  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1526  }
1527 
1528  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1529  0,
1534  ok(mdi_child != 0, "MDI child creation failed\n");
1535  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1536  ok(id == first_id, "wrong child id %ld\n", id);
1538  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1539  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1540  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1541  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1542  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1543 
1544  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1545  WS_MAXIMIZE,
1550  ok(mdi_child != 0, "MDI child creation failed\n");
1551  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1552  ok(id == first_id, "wrong child id %ld\n", id);
1554  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1555  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1557  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1558  else
1559  ok(GetMenuItemCount(frame_menu) == 4, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1560  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1561  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1562 
1563  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1564  0x7fffffff, /* without WS_POPUP */
1569  ok(mdi_child != 0, "MDI child creation failed\n");
1570  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1571  ok(id == first_id, "wrong child id %ld\n", id);
1573  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1574  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1575  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1576  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1577 
1578  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1579  0xffffffff, /* with WS_POPUP */
1585  {
1586  ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1587  }
1588  else
1589  {
1590  ok(mdi_child != 0, "MDI child creation failed\n");
1591  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1592  ok(id == first_id, "wrong child id %ld\n", id);
1594  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1595  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1596  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1597  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1598  }
1599 
1600  /* test MDICREATESTRUCT A<->W mapping */
1601  SetLastError(0xdeadbeef);
1603  0,
1608  if (!mdi_child)
1609  {
1611  isWin9x = TRUE;
1612  else
1613  ok(mdi_child != 0, "MDI child creation failed\n");
1614  }
1615  else
1616  {
1617  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1618  ok(id == first_id, "wrong child id %ld\n", id);
1620  exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1621  ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1622  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1623  SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
1624  ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1625  }
1626 
1627  /* This test fails on Win9x */
1628  if (!isWin9x)
1629  {
1630  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_2", "MDI child",
1631  WS_CHILD,
1636  ok(!mdi_child, "WS_EX_MDICHILD with a not MDIClient parent should fail\n");
1637  }
1638 
1639  mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1640  WS_CHILD, /* without WS_POPUP */
1645  ok(mdi_child != 0, "MDI child creation failed\n");
1646  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1647  ok(id == 0, "wrong child id %ld\n", id);
1648  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1650  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1651  DestroyWindow(mdi_child);
1652 
1653  mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1654  WS_CHILD | WS_POPUP, /* with WS_POPUP */
1659  ok(mdi_child != 0, "MDI child creation failed\n");
1660  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1661  ok(id == 0, "wrong child id %ld\n", id);
1663  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1664  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1665  DestroyWindow(mdi_child);
1666 
1667  /* maximized child */
1668  mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1674  ok(mdi_child != 0, "MDI child creation failed\n");
1675  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1676  ok(id == 0, "wrong child id %ld\n", id);
1678  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1679  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1680  DestroyWindow(mdi_child);
1681 
1682  trace("Creating maximized child with a caption\n");
1683  mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1689  ok(mdi_child != 0, "MDI child creation failed\n");
1690  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1691  ok(id == 0, "wrong child id %ld\n", id);
1693  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1694  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1695  DestroyWindow(mdi_child);
1696 
1697  trace("Creating maximized child with a caption and a thick frame\n");
1698  mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1704  ok(mdi_child != 0, "MDI child creation failed\n");
1705  id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1706  ok(id == 0, "wrong child id %ld\n", id);
1708  ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1709  ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1710  DestroyWindow(mdi_child);
1711 }
1712 
1714 {
1715  HWND child_1, child_2, child_3, child_4;
1716  HWND stack[4];
1718 
1719  cs.szClass = "MDI_child_Class_1";
1720  cs.szTitle = "MDI child";
1721  cs.hOwner = GetModuleHandleA(0);
1722  cs.x = CW_USEDEFAULT;
1723  cs.y = CW_USEDEFAULT;
1724  cs.cx = CW_USEDEFAULT;
1725  cs.cy = CW_USEDEFAULT;
1726  cs.style = 0;
1727  cs.lParam = (LPARAM)mdi_lParam_test_message;
1728 
1729  child_1 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1730  ok(child_1 != 0, "expected child_1 to be non NULL\n");
1731  child_2 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1732  ok(child_2 != 0, "expected child_2 to be non NULL\n");
1733  child_3 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1734  ok(child_3 != 0, "expected child_3 to be non NULL\n");
1735  child_4 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1736  ok(child_4 != 0, "expected child_4 to be non NULL\n");
1737 
1739  stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1740  stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1741  stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1742  trace("Initial MDI child stack: %p->%p->%p->%p\n", stack[0], stack[1], stack[2], stack[3]);
1743  ok(stack[0] == child_4 && stack[1] == child_3 &&
1744  stack[2] == child_2 && stack[3] == child_1,
1745  "Unexpected initial order, should be: %p->%p->%p->%p\n",
1746  child_4, child_3, child_2, child_1);
1747 
1748  trace("Activate child next to %p\n", child_3);
1749  SendMessageA(mdi_client, WM_MDINEXT, (WPARAM)child_3, 0);
1750 
1752  stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1753  stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1754  stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1755  ok(stack[0] == child_2 && stack[1] == child_4 &&
1756  stack[2] == child_1 && stack[3] == child_3,
1757  "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n",
1758  child_2, child_4, child_1, child_3, stack[0], stack[1], stack[2], stack[3]);
1759 
1760  trace("Activate child previous to %p\n", child_1);
1761  SendMessageA(mdi_client, WM_MDINEXT, (WPARAM)child_1, 1);
1762 
1764  stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1765  stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1766  stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1767  ok(stack[0] == child_4 && stack[1] == child_2 &&
1768  stack[2] == child_1 && stack[3] == child_3,
1769  "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n",
1770  child_4, child_2, child_1, child_3, stack[0], stack[1], stack[2], stack[3]);
1771 
1772  DestroyWindow(child_1);
1773  DestroyWindow(child_2);
1774  DestroyWindow(child_3);
1775  DestroyWindow(child_4);
1776 }
1777 
1778 /**********************************************************************
1779  * MDI_ChildGetMinMaxInfo (copied from windows/mdi.c)
1780  *
1781  * Note: The rule here is that client rect of the maximized MDI child
1782  * is equal to the client rect of the MDI client window.
1783  */
1785 {
1786  RECT rect;
1787 
1788  GetClientRect( client, &rect );
1791 
1792  rect.right -= rect.left;
1793  rect.bottom -= rect.top;
1794  lpMinMax->ptMaxSize.x = rect.right;
1795  lpMinMax->ptMaxSize.y = rect.bottom;
1796 
1797  lpMinMax->ptMaxPosition.x = rect.left;
1798  lpMinMax->ptMaxPosition.y = rect.top;
1799 
1800  trace("max rect %s\n", wine_dbgstr_rect(&rect));
1801 }
1802 
1804 {
1805  switch (msg)
1806  {
1807  case WM_NCCREATE:
1808  case WM_CREATE:
1809  {
1811  MDICREATESTRUCTA *mdi_cs = cs->lpCreateParams;
1812 
1813  ok(cs->dwExStyle & WS_EX_MDICHILD, "WS_EX_MDICHILD should be set\n");
1814  ok(mdi_cs->lParam == (LPARAM)mdi_lParam_test_message, "wrong mdi_cs->lParam\n");
1815 
1816  ok(!lstrcmpA(cs->lpszClass, "MDI_child_Class_1"), "wrong class name\n");
1817  ok(!lstrcmpA(cs->lpszClass, mdi_cs->szClass), "class name does not match\n");
1818  ok(!lstrcmpA(cs->lpszName, "MDI child"), "wrong title\n");
1819  ok(!lstrcmpA(cs->lpszName, mdi_cs->szTitle), "title does not match\n");
1820  ok(cs->hInstance == mdi_cs->hOwner, "%p != %p\n", cs->hInstance, mdi_cs->hOwner);
1821 
1822  /* MDICREATESTRUCT should have original values */
1823  ok(mdi_cs->style == 0 || mdi_cs->style == 0x7fffffff || mdi_cs->style == 0xffffffff || mdi_cs->style == WS_MAXIMIZE,
1824  "mdi_cs->style does not match (%08x)\n", mdi_cs->style);
1825  ok(mdi_cs->x == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->x);
1826  ok(mdi_cs->y == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->y);
1827  ok(mdi_cs->cx == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->cx);
1828  ok(mdi_cs->cy == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->cy);
1829 
1830  /* CREATESTRUCT should have fixed values */
1831  ok(cs->x != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->x);
1832  ok(cs->y != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->y);
1833 
1834  /* cx/cy == CW_USEDEFAULT are translated to NOT zero values */
1835  ok(cs->cx != CW_USEDEFAULT && cs->cx != 0, "%d == CW_USEDEFAULT\n", cs->cx);
1836  ok(cs->cy != CW_USEDEFAULT && cs->cy != 0, "%d == CW_USEDEFAULT\n", cs->cy);
1837 
1838  ok(!(cs->style & WS_POPUP), "WS_POPUP is not allowed\n");
1839 
1840  if (GetWindowLongA(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
1841  {
1842  LONG style = mdi_cs->style | WS_CHILD | WS_CLIPSIBLINGS;
1843  ok(cs->style == style,
1844  "cs->style does not match (%08x)\n", cs->style);
1845  }
1846  else
1847  {
1848  LONG style = mdi_cs->style;
1849  style &= ~WS_POPUP;
1852  ok(cs->style == style,
1853  "cs->style does not match (%08x)\n", cs->style);
1854  }
1855  break;
1856  }
1857 
1858  case WM_GETMINMAXINFO:
1859  {
1861  RECT rc;
1862  MINMAXINFO *minmax = (MINMAXINFO *)lparam;
1863  MINMAXINFO my_minmax;
1864  LONG style, exstyle;
1865 
1867  exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1868 
1869  GetClientRect(client, &rc);
1870 
1871  GetClientRect(client, &rc);
1872  if ((style & WS_CAPTION) == WS_CAPTION)
1873  style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1874  AdjustWindowRectEx(&rc, style, 0, exstyle);
1875  trace("MDI child: calculated max window size = (%d x %d)\n", rc.right-rc.left, rc.bottom-rc.top);
1876  dump_minmax_info( minmax );
1877 
1878  ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %d != %d\n",
1879  minmax->ptMaxSize.x, rc.right - rc.left);
1880  ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %d != %d\n",
1881  minmax->ptMaxSize.y, rc.bottom - rc.top);
1882 
1884 
1885  trace("DefMDIChildProc returned:\n");
1886  dump_minmax_info( minmax );
1887 
1888  MDI_ChildGetMinMaxInfo(client, hwnd, &my_minmax);
1889  ok(minmax->ptMaxSize.x == my_minmax.ptMaxSize.x, "default width of maximized child %d != %d\n",
1890  minmax->ptMaxSize.x, my_minmax.ptMaxSize.x);
1891  ok(minmax->ptMaxSize.y == my_minmax.ptMaxSize.y, "default height of maximized child %d != %d\n",
1892  minmax->ptMaxSize.y, my_minmax.ptMaxSize.y);
1893 
1894  return 1;
1895  }
1896 
1897  case WM_MDIACTIVATE:
1898  {
1899  HWND active, client = GetParent(hwnd);
1900  /*trace("%p WM_MDIACTIVATE %08x %08lx\n", hwnd, wparam, lparam);*/
1901  active = (HWND)SendMessageA(client, WM_MDIGETACTIVE, 0, 0);
1902  if (hwnd == (HWND)lparam) /* if we are being activated */
1903  ok (active == (HWND)lparam, "new active %p != active %p\n", (HWND)lparam, active);
1904  else
1905  ok (active == (HWND)wparam, "old active %p != active %p\n", (HWND)wparam, active);
1906  break;
1907  }
1908  }
1909  return DefMDIChildProcA(hwnd, msg, wparam, lparam);
1910 }
1911 
1913 {
1914  switch (msg)
1915  {
1916  case WM_NCCREATE:
1917  case WM_CREATE:
1918  {
1920 
1921  trace("%s: x %d, y %d, cx %d, cy %d\n", (msg == WM_NCCREATE) ? "WM_NCCREATE" : "WM_CREATE",
1922  cs->x, cs->y, cs->cx, cs->cy);
1923 
1924  ok(!(cs->dwExStyle & WS_EX_MDICHILD), "WS_EX_MDICHILD should not be set\n");
1925  ok(cs->lpCreateParams == mdi_lParam_test_message, "wrong cs->lpCreateParams\n");
1926 
1927  ok(!lstrcmpA(cs->lpszClass, "MDI_child_Class_2"), "wrong class name\n");
1928  ok(!lstrcmpA(cs->lpszName, "MDI child"), "wrong title\n");
1929 
1930  /* CREATESTRUCT should have fixed values */
1931  /* For some reason Win9x doesn't translate cs->x from CW_USEDEFAULT,
1932  while NT does. */
1933  /*ok(cs->x != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->x);*/
1934  ok(cs->y != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->y);
1935 
1936  /* cx/cy == CW_USEDEFAULT are translated to 0 */
1937  /* For some reason Win98 doesn't translate cs->cx from CW_USEDEFAULT,
1938  while Win95, Win2k, WinXP do. */
1939  /*ok(cs->cx == 0, "%d != 0\n", cs->cx);*/
1940  ok(cs->cy == 0, "%d != 0\n", cs->cy);
1941  break;
1942  }
1943 
1944  case WM_GETMINMAXINFO:
1945  {
1947  RECT rc;
1948  MINMAXINFO *minmax = (MINMAXINFO *)lparam;
1949  LONG style, exstyle;
1950 
1952  exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1953 
1954  GetClientRect(parent, &rc);
1955  trace("WM_GETMINMAXINFO: parent %p client size = (%d x %d)\n", parent, rc.right, rc.bottom);
1956 
1957  GetClientRect(parent, &rc);
1958  if ((style & WS_CAPTION) == WS_CAPTION)
1959  style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1960  AdjustWindowRectEx(&rc, style, 0, exstyle);
1961  dump_minmax_info( minmax );
1962 
1963  ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %d != %d\n",
1964  minmax->ptMaxSize.x, rc.right - rc.left);
1965  ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %d != %d\n",
1966  minmax->ptMaxSize.y, rc.bottom - rc.top);
1967  break;
1968  }
1969 
1970  case WM_WINDOWPOSCHANGED:
1971  {
1972  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
1973  RECT rc1, rc2;
1974 
1975  GetWindowRect(hwnd, &rc1);
1976  SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
1977  /* note: winpos coordinates are relative to parent */
1979  ok(EqualRect(&rc1, &rc2), "rects do not match, window=%s pos=%s\n",
1981  GetWindowRect(hwnd, &rc1);
1982  GetClientRect(hwnd, &rc2);
1984  MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
1985  ok(EqualRect(&rc1, &rc2), "rects do not match, window=%s client=%s\n",
1987  }
1988  /* fall through */
1989  case WM_WINDOWPOSCHANGING:
1990  {
1991  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
1992  WINDOWPOS my_winpos = *winpos;
1993 
1994  trace("%s: %p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
1995  (msg == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED",
1996  winpos->hwnd, winpos->hwndInsertAfter,
1997  winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
1998 
2000 
2001  ok(!memcmp(&my_winpos, winpos, sizeof(WINDOWPOS)),
2002  "DefWindowProc should not change WINDOWPOS: %p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2003  winpos->hwnd, winpos->hwndInsertAfter,
2004  winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2005 
2006  return 1;
2007  }
2008  }
2009  return DefWindowProcA(hwnd, msg, wparam, lparam);
2010 }
2011 
2013 {
2014  static HWND mdi_client;
2015 
2016  switch (msg)
2017  {
2018  case WM_CREATE:
2019  return 1;
2020 
2021  case WM_WINDOWPOSCHANGED:
2022  {
2023  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
2024  RECT rc1, rc2;
2025 
2026  GetWindowRect(hwnd, &rc1);
2027  trace("window: %s\n", wine_dbgstr_rect(&rc1));
2028  SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
2029  /* note: winpos coordinates are relative to parent */
2031  trace("pos: %s\n", wine_dbgstr_rect(&rc2));
2032  ok(EqualRect(&rc1, &rc2), "rects do not match\n");
2033 
2034  GetWindowRect(hwnd, &rc1);
2035  GetClientRect(hwnd, &rc2);
2037  MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
2038  ok(EqualRect(&rc1, &rc2), "rects do not match\n");
2039  }
2040  /* fall through */
2041  case WM_WINDOWPOSCHANGING:
2042  {
2043  WINDOWPOS *winpos = (WINDOWPOS *)lparam;
2044  WINDOWPOS my_winpos = *winpos;
2045 
2046  trace("%s\n", (msg == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2047  trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2048  winpos->hwnd, winpos->hwndInsertAfter,
2049  winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2050 
2052 
2053  trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2054  winpos->hwnd, winpos->hwndInsertAfter,
2055  winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2056 
2057  ok(!memcmp(&my_winpos, winpos, sizeof(WINDOWPOS)),
2058  "DefWindowProc should not change WINDOWPOS values\n");
2059 
2060  return 1;
2061  }
2062 
2063  case WM_CLOSE:
2064  PostQuitMessage(0);
2065  break;
2066  }
2068 }
2069 
2071 {
2072  WNDCLASSA cls;
2073 
2074  cls.style = 0;
2076  cls.cbClsExtra = 0;
2077  cls.cbWndExtra = 0;
2078  cls.hInstance = GetModuleHandleA(0);
2079  cls.hIcon = 0;
2080  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
2082  cls.lpszMenuName = NULL;
2083  cls.lpszClassName = "MDI_parent_Class";
2084  if(!RegisterClassA(&cls)) return FALSE;
2085 
2087  cls.lpszClassName = "MDI_child_Class_1";
2088  if(!RegisterClassA(&cls)) return FALSE;
2089 
2091  cls.lpszClassName = "MDI_child_Class_2";
2092  if(!RegisterClassA(&cls)) return FALSE;
2093 
2094  return TRUE;
2095 }
2096 
2097 static void test_mdi(void)
2098 {
2099  static const DWORD style[] = { 0, WS_HSCROLL, WS_VSCROLL, WS_HSCROLL | WS_VSCROLL };
2100  HWND mdi_hwndMain, mdi_client, mdi_child;
2101  CLIENTCREATESTRUCT client_cs;
2102  RECT rc;
2103  DWORD i;
2104  MSG msg;
2105  HMENU frame_menu, child_menu;
2106 
2107  if (!mdi_RegisterWindowClasses()) assert(0);
2108 
2109  mdi_hwndMain = CreateWindowExA(0, "MDI_parent_Class", "MDI parent window",
2111  WS_MAXIMIZEBOX /*| WS_VISIBLE*/,
2112  100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
2113  GetDesktopWindow(), 0,
2115  assert(mdi_hwndMain);
2116 
2117  frame_menu = CreateMenu();
2118 
2119  GetClientRect(mdi_hwndMain, &rc);
2120 
2121  client_cs.hWindowMenu = 0;
2122  client_cs.idFirstChild = 1;
2123 
2124  for (i = 0; i < sizeof(style)/sizeof(style[0]); i++)
2125  {
2126  SCROLLINFO si;
2127  BOOL ret, gotit;
2128 
2129  mdi_client = CreateWindowExA(0, "mdiclient", NULL,
2130  WS_CHILD | style[i],
2131  0, 0, rc.right, rc.bottom,
2132  mdi_hwndMain, 0, 0, &client_cs);
2133  ok(mdi_client != 0, "MDI client creation failed\n");
2134 
2135  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
2136  0,
2139  mdi_client, 0, 0,
2141  ok(mdi_child != 0, "MDI child creation failed\n");
2142 
2143  SendMessageW(mdi_child, WM_SIZE, SIZE_MAXIMIZED, 0);
2144  SetMenu(mdi_hwndMain, frame_menu);
2145 
2146  ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child maximize, but has %u\n",
2147  GetMenuItemCount(frame_menu));
2148 
2149  child_menu = CreateMenu();
2150  SendMessageW(mdi_client, WM_MDISETMENU, 0, (LPARAM)child_menu);
2151 
2152  ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after WM_MDISETMENU, but has %u\n",
2153  GetMenuItemCount(frame_menu));
2154 
2155  SendMessageW(mdi_child, WM_SIZE, SIZE_RESTORED, 0);
2156 
2157  ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child restored, but has %u items\n",
2158  GetMenuItemCount(frame_menu));
2159 
2160  SetMenu(mdi_hwndMain, NULL);
2161 
2162  si.cbSize = sizeof(si);
2163  si.fMask = SIF_ALL;
2165  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2166  {
2167  ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2168  ok(si.nPage == 0, "expected 0\n");
2169  ok(si.nPos == 0, "expected 0\n");
2170  ok(si.nTrackPos == 0, "expected 0\n");
2171  ok(si.nMin == 0, "expected 0\n");
2172  ok(si.nMax == 100, "expected 100\n");
2173  }
2174  else
2175  ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2176 
2178  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2179  {
2180  ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2181  ok(si.nPage == 0, "expected 0\n");
2182  ok(si.nPos == 0, "expected 0\n");
2183  ok(si.nTrackPos == 0, "expected 0\n");
2184  ok(si.nMin == 0, "expected 0\n");
2185  ok(si.nMax == 100, "expected 100\n");
2186  }
2187  else
2188  ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2189 
2190  SetWindowPos(mdi_child, 0, -100, -100, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
2191 
2192  si.cbSize = sizeof(si);
2193  si.fMask = SIF_ALL;
2195  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2196  {
2197  ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2198  ok(si.nPage == 0, "expected 0\n");
2199  ok(si.nPos == 0, "expected 0\n");
2200  ok(si.nTrackPos == 0, "expected 0\n");
2201  ok(si.nMin == 0, "expected 0\n");
2202  ok(si.nMax == 100, "expected 100\n");
2203  }
2204  else
2205  ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2206 
2208  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2209  {
2210  ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2211  ok(si.nPage == 0, "expected 0\n");
2212  ok(si.nPos == 0, "expected 0\n");
2213  ok(si.nTrackPos == 0, "expected 0\n");
2214  ok(si.nMin == 0, "expected 0\n");
2215  ok(si.nMax == 100, "expected 100\n");
2216  }
2217  else
2218  ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2219 
2220  gotit = FALSE;
2221  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2222  {
2223  if (msg.message == WM_MOUSEMOVE || msg.message == WM_PAINT)
2224  {
2226  continue;
2227  }
2228 
2229  if (msg.message == 0x003f) /* WM_MDICALCCHILDSCROLL ??? */
2230  {
2231  ok(msg.hwnd == mdi_client, "message 0x003f should be posted to mdiclient\n");
2232  gotit = TRUE;
2233  }
2234  else
2235  ok(msg.hwnd != mdi_client, "message %04x should not be posted to mdiclient\n", msg.message);
2237  }
2238  ok(gotit, "message 0x003f should appear after SetWindowPos\n");
2239 
2240  si.cbSize = sizeof(si);
2241  si.fMask = SIF_ALL;
2243  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2244  {
2245  ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2246 todo_wine
2247  ok(si.nPage != 0, "expected !0\n");
2248  ok(si.nPos == 0, "expected 0\n");
2249  ok(si.nTrackPos == 0, "expected 0\n");
2250  ok(si.nMin != 0, "expected !0\n");
2251  ok(si.nMax != 100, "expected !100\n");
2252  }
2253  else
2254  ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2255 
2257  if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2258  {
2259  ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2260 todo_wine
2261  ok(si.nPage != 0, "expected !0\n");
2262  ok(si.nPos == 0, "expected 0\n");
2263  ok(si.nTrackPos == 0, "expected 0\n");
2264  ok(si.nMin != 0, "expected !0\n");
2265  ok(si.nMax != 100, "expected !100\n");
2266  }
2267  else
2268  ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2269 
2270  DestroyMenu(child_menu);
2271  DestroyWindow(mdi_child);
2273  }
2274 
2275  SetMenu(mdi_hwndMain, frame_menu);
2276 
2277  mdi_client = CreateWindowExA(0, "mdiclient", NULL,
2278  WS_CHILD,
2279  0, 0, rc.right, rc.bottom,
2280  mdi_hwndMain, 0, 0, &client_cs);
2281  ok(mdi_client != 0, "MDI client creation failed\n");
2282 
2283  mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
2284  0,
2287  mdi_client, 0, 0,
2289  ok(mdi_child != 0, "MDI child creation failed\n");
2290 
2291  SendMessageW(mdi_child, WM_SIZE, SIZE_MAXIMIZED, 0);
2292  ok(GetMenuItemCount(frame_menu) == 4, "Frame menu should have 4 items after child maximize, but has %u\n",
2293  GetMenuItemCount(frame_menu));
2294 
2295  child_menu = CreateMenu();
2296  SendMessageW(mdi_client, WM_MDISETMENU, 0, (LPARAM)child_menu);
2297 
2298  ok(GetMenuItemCount(frame_menu) == 4, "Frame menu should have 4 items after WM_MDISETMENU, but has %u\n",
2299  GetMenuItemCount(frame_menu));
2300 
2301  SendMessageW(mdi_child, WM_SIZE, SIZE_RESTORED, 0);
2302 
2303  ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child restored, but has %u items\n",
2304  GetMenuItemCount(frame_menu));
2305 
2306  DestroyMenu(child_menu);
2307  DestroyWindow(mdi_child);
2309 
2310  /* MDIClient without MDIS_ALLCHILDSTYLES */
2311  mdi_client = CreateWindowExA(0, "mdiclient",
2312  NULL,
2313  WS_CHILD /*| WS_VISIBLE*/,
2314  /* tests depend on a not zero MDIClient size */
2315  0, 0, rc.right, rc.bottom,
2316  mdi_hwndMain, 0, GetModuleHandleA(NULL),
2317  &client_cs);
2318  assert(mdi_client);
2319  test_MDI_create(mdi_hwndMain, mdi_client, client_cs.idFirstChild);
2321 
2322  /* MDIClient with MDIS_ALLCHILDSTYLES */
2323  mdi_client = CreateWindowExA(0, "mdiclient",
2324  NULL,
2325  WS_CHILD | MDIS_ALLCHILDSTYLES /*| WS_VISIBLE*/,
2326  /* tests depend on a not zero MDIClient size */
2327  0, 0, rc.right, rc.bottom,
2328  mdi_hwndMain, 0, GetModuleHandleA(NULL),
2329  &client_cs);
2330  assert(mdi_client);
2331  test_MDI_create(mdi_hwndMain, mdi_client, client_cs.idFirstChild);
2333 
2334  /* Test child window stack management */
2335  mdi_client = CreateWindowExA(0, "mdiclient",
2336  NULL,
2337  WS_CHILD,
2338  0, 0, rc.right, rc.bottom,
2339  mdi_hwndMain, 0, GetModuleHandleA(NULL),
2340  &client_cs);
2341  assert(mdi_client);
2344 /*
2345  while(GetMessage(&msg, 0, 0, 0))
2346  {
2347  TranslateMessage(&msg);
2348  DispatchMessage(&msg);
2349  }
2350 */
2351  DestroyWindow(mdi_hwndMain);
2352 }
2353 
2354 static void test_icons(void)
2355 {
2356  WNDCLASSEXA cls;
2357  HWND hwnd;
2358  HICON icon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
2359  HICON icon2 = LoadIconA(0, (LPCSTR)IDI_QUESTION);
2360  HICON small_icon = LoadImageA(0, (LPCSTR)IDI_APPLICATION, IMAGE_ICON,
2362  HICON res;
2363 
2364  cls.cbSize = sizeof(cls);
2365  cls.style = 0;
2367  cls.cbClsExtra = 0;
2368  cls.cbWndExtra = 0;
2369  cls.hInstance = 0;
2370  cls.hIcon = LoadIconA(0, (LPCSTR)IDI_HAND);
2371  cls.hIconSm = small_icon;
2372  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
2374  cls.lpszMenuName = NULL;
2375  cls.lpszClassName = "IconWindowClass";
2376 
2377  RegisterClassExA(&cls);
2378 
2379  hwnd = CreateWindowExA(0, "IconWindowClass", "icon test", 0,
2380  100, 100, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL);
2381  assert( hwnd );
2382 
2383  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2384  ok( res == 0, "wrong big icon %p/0\n", res );
2385  res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon );
2386  ok( res == 0, "wrong previous big icon %p/0\n", res );
2387  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2388  ok( res == icon, "wrong big icon after set %p/%p\n", res, icon );
2389  res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon2 );
2390  ok( res == icon, "wrong previous big icon %p/%p\n", res, icon );
2391  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2392  ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
2393 
2394  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2395  ok( res == 0, "wrong small icon %p/0\n", res );
2396  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2397  ok( (res && res != small_icon && res != icon2) || broken(!res), "wrong small2 icon %p\n", res );
2398  res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)icon );
2399  ok( res == 0, "wrong previous small icon %p/0\n", res );
2400  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2401  ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );
2402  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2403  ok( res == icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, icon );
2404  res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)small_icon );
2405  ok( res == icon, "wrong previous small icon %p/%p\n", res, icon );
2406  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2407  ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );
2408  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2409  ok( res == small_icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, small_icon );
2410 
2411  /* make sure the big icon hasn't changed */
2412  res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2413  ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
2414 
2415  DestroyWindow( hwnd );
2416 }
2417 
2419 {
2420  if (msg == WM_NCCALCSIZE)
2421  {
2422  RECT *rect = (RECT *)lparam;
2423  /* first time around increase the rectangle, next time decrease it */
2424  if (rect->left == 100) InflateRect( rect, 10, 10 );
2425  else InflateRect( rect, -10, -10 );
2426  return 0;
2427  }
2428  return DefWindowProcA( hwnd, msg, wparam, lparam );
2429 }
2430 
2431 static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
2432 {
2433  RECT orig_win_rc, rect;
2435  HWND hwnd_grandchild, hwnd_child, hwnd_child2;
2436  HWND hwnd_desktop;
2437  RECT rc1, rc2;
2438  BOOL ret;
2439 
2440  SetRect(&rect, 111, 222, 333, 444);
2441  ok(!GetWindowRect(0, &rect), "GetWindowRect succeeded\n");
2442  ok(rect.left == 111 && rect.top == 222 && rect.right == 333 && rect.bottom == 444,
2443  "wrong window rect %s\n", wine_dbgstr_rect(&rect));
2444 
2445  SetRect(&rect, 111, 222, 333, 444);
2446  ok(!GetClientRect(0, &rect), "GetClientRect succeeded\n");
2447  ok(rect.left == 111 && rect.top == 222 && rect.right == 333 && rect.bottom == 444,
2448  "wrong window rect %s\n", wine_dbgstr_rect(&rect));
2449 
2450  GetWindowRect(hwnd, &orig_win_rc);
2451 
2453  ret = SetWindowPos(hwnd, 0, 100, 100, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
2454  ok(ret, "Got %d\n", ret);
2455  GetWindowRect( hwnd, &rect );
2456  ok( rect.left == 100 && rect.top == 100 && rect.right == 100 && rect.bottom == 100,
2457  "invalid window rect %s\n", wine_dbgstr_rect(&rect));
2458  GetClientRect( hwnd, &rect );
2459  MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
2460  ok( rect.left == 90 && rect.top == 90 && rect.right == 110 && rect.bottom == 110,
2461  "invalid client rect %s\n", wine_dbgstr_rect(&rect));
2462 
2463  ret = SetWindowPos(hwnd, 0, 200, 200, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
2464  ok(ret, "Got %d\n", ret);
2465  GetWindowRect( hwnd, &rect );
2466  ok( rect.left == 200 && rect.top == 200 && rect.right == 200 && rect.bottom == 200,
2467  "invalid window rect %s\n", wine_dbgstr_rect(&rect));
2468  GetClientRect( hwnd, &rect );
2469  MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
2470  ok( rect.left == 210 && rect.top == 210 && rect.right == 190 && rect.bottom == 190,
2471  "invalid client rect %s\n", wine_dbgstr_rect(&rect));
2472 
2473  ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
2474  orig_win_rc.right, orig_win_rc.bottom, 0);
2475  ok(ret, "Got %d\n", ret);
2477 
2478  /* Win9x truncates coordinates to 16-bit irrespectively */
2479  if (!is_win9x)
2480  {
2481  ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
2482  ok(ret, "Got %d\n", ret);
2483  ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
2484  ok(ret, "Got %d\n", ret);
2485 
2486  ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
2487  ok(ret, "Got %d\n", ret);
2488  ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
2489  ok(ret, "Got %d\n", ret);
2490  }
2491 
2492  ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
2493  orig_win_rc.right, orig_win_rc.bottom, 0);
2494  ok(ret, "Got %d\n", ret);
2495 
2496  ok(!(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
2498  ok(ret, "Got %d\n", ret);
2499  ok(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
2501  ok(ret, "Got %d\n", ret);
2502  ok(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
2504  ok(ret, "Got %d\n", ret);
2505  ok(!(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
2506 
2507  hwnd_desktop = GetDesktopWindow();
2508  ok(!!hwnd_desktop, "Failed to get hwnd_desktop window (%d).\n", GetLastError());
2509  hwnd_child = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd);
2510  ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2511  hwnd_grandchild = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd_child);
2512  ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2513  hwnd_child2 = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd);
2514  ok(!!hwnd_child2, "Failed to create second child window (%d)\n", GetLastError());
2515 
2516  ret = SetWindowPos(hwnd, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2517  ok(ret, "Got %d\n", ret);
2519 
2520  ret = SetWindowPos(hwnd2, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2521  ok(ret, "Got %d\n", ret);
2522  check_active_state(hwnd2, hwnd2, hwnd2);
2523 
2524  /* Returns TRUE also for windows that are not siblings */
2525  ret = SetWindowPos(hwnd_child, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2526  ok(ret, "Got %d\n", ret);
2527  check_active_state(hwnd2, hwnd2, hwnd2);
2528 
2529  ret = SetWindowPos(hwnd2, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2530  ok(ret, "Got %d\n", ret);
2531  check_active_state(hwnd2, hwnd2, hwnd2);
2532 
2533  /* Does not seem to do anything even without passing flags, still returns TRUE */
2534  GetWindowRect(hwnd_child, &rc1);
2535  ret = SetWindowPos(hwnd_child, hwnd2 , 1, 2, 3, 4, 0);
2536  ok(ret, "Got %d\n", ret);
2537  GetWindowRect(hwnd_child, &rc2);
2538  ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2539  check_active_state(hwnd2, hwnd2, hwnd2);
2540 
2541  /* Same thing the other way around. */
2542  GetWindowRect(hwnd2, &rc1);
2543  ret = SetWindowPos(hwnd2, hwnd_child, 1, 2, 3, 4, 0);
2544  ok(ret, "Got %d\n", ret);
2545  GetWindowRect(hwnd2, &rc2);
2546  ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2547  check_active_state(hwnd2, hwnd2, hwnd2);
2548 
2549  /* .. and with these windows. */
2550  GetWindowRect(hwnd_grandchild, &rc1);
2551  ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, 0);
2552  ok(ret, "Got %d\n", ret);
2553  GetWindowRect(hwnd_grandchild, &rc2);
2554  ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2555  check_active_state(hwnd2, hwnd2, hwnd2);
2556 
2557  /* Add SWP_NOZORDER and it will be properly resized. */
2558  GetWindowRect(hwnd_grandchild, &rc1);
2559  ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, SWP_NOZORDER);
2560  ok(ret, "Got %d\n", ret);
2561  GetWindowRect(hwnd_grandchild, &rc2);
2562  ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
2563  (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
2564  "(%d,%d)-(%d,%d) != %s\n", rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6,
2565  wine_dbgstr_rect(&rc2));
2566  check_active_state(hwnd2, hwnd2, hwnd2);
2567 
2568  /* Given a sibling window, the window is properly resized. */
2569  GetWindowRect(hwnd_child, &rc1);
2570  ret = SetWindowPos(hwnd_child, hwnd_child2, 1, 2, 3, 4, 0);
2571  ok(ret, "Got %d\n", ret);
2572  GetWindowRect(hwnd_child, &rc2);
2573  ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
2574  (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
2575  "(%d,%d)-(%d,%d) != %s\n", rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6,
2576  wine_dbgstr_rect(&rc2));
2577  check_active_state(hwnd2, hwnd2, hwnd2);
2578 
2579  /* Involving the desktop window changes things. */
2580  ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2581  ok(!ret, "Got %d\n", ret);
2582  check_active_state(hwnd2, hwnd2, hwnd2);
2583 
2584  GetWindowRect(hwnd_child, &rc1);
2585  ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, 0);
2586  ok(!ret, "Got %d\n", ret);
2587  GetWindowRect(hwnd_child, &rc2);
2588  ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2589  check_active_state(hwnd2, hwnd2, hwnd2);
2590 
2591  ret = SetWindowPos(hwnd_desktop, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2592  ok(!ret, "Got %d\n", ret);
2593  check_active_state(hwnd2, hwnd2, hwnd2);
2594 
2595  ret = SetWindowPos(hwnd_desktop, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2596  ok(!ret, "Got %d\n", ret);
2597  check_active_state(hwnd2, hwnd2, hwnd2);
2598 
2599  ret = SetWindowPos(hwnd, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2600  ok(!ret, "Got %d\n", ret);
2601  check_active_state(hwnd2, hwnd2, hwnd2);
2602 
2603  DestroyWindow(hwnd_grandchild);
2604  DestroyWindow(hwnd_child);
2605  DestroyWindow(hwnd_child2);
2606 
2607  hwnd_child = create_tool_window(WS_CHILD|WS_POPUP|WS_SYSMENU, hwnd2);
2608  ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2610  ok(ret, "Got %d\n", ret);
2611  flush_events( TRUE );
2612  todo_wine check_active_state(hwnd2, hwnd2, hwnd2);
2613  DestroyWindow(hwnd_child);
2614 }
2615 
2617 {
2618  HWND child;
2619  HMENU hMenu, ret;
2620  BOOL retok;
2621  DWORD style;
2622 
2623  hMenu = CreateMenu();
2624  assert(hMenu);
2625 
2626  ok(SetMenu(parent, hMenu), "SetMenu on a top level window should not fail\n");
2627  if (0)
2628  {
2629  /* fails on (at least) Wine, NT4, XP SP2 */
2631  }
2632  ret = GetMenu(parent);
2633  ok(ret == hMenu, "unexpected menu id %p\n", ret);
2634  /* test whether we can destroy a menu assigned to a window */
2635  retok = DestroyMenu(hMenu);
2636  ok( retok, "DestroyMenu error %d\n", GetLastError());
2637  retok = IsMenu(hMenu);
2638  ok(!retok || broken(retok) /* nt4 */, "menu handle should be not valid after DestroyMenu\n");
2639  ret = GetMenu(parent);
2640  /* This test fails on Win9x */
2641  if (!is_win9x)
2642  ok(ret == hMenu, "unexpected menu id %p\n", ret);
2643  ok(SetMenu(parent, 0), "SetMenu(0) on a top level window should not fail\n");
2645 
2646  hMenu = CreateMenu();
2647  assert(hMenu);
2648 
2649  /* parent */
2650  ret = GetMenu(parent);
2651  ok(ret == 0, "unexpected menu id %p\n", ret);
2652 
2653  ok(!SetMenu(parent, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
2655  ret = GetMenu(parent);
2656  ok(ret == 0, "unexpected menu id %p\n", ret);
2657 
2658  ok(SetMenu(parent, hMenu), "SetMenu on a top level window should not fail\n");
2659  if (0)
2660  {
2661  /* fails on (at least) Wine, NT4, XP SP2 */
2663  }
2664  ret = GetMenu(parent);
2665  ok(ret == hMenu, "unexpected menu id %p\n", ret);
2666 
2667  ok(SetMenu(parent, 0), "SetMenu(0) on a top level window should not fail\n");
2669  ret = GetMenu(parent);
2670  ok(ret == 0, "unexpected menu id %p\n", ret);
2671 
2672  /* child */
2673  child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, parent, (HMENU)10, 0, NULL);
2674  assert(child);
2675 
2676  ret = GetMenu(child);
2677  ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2678 
2679  ok(!SetMenu(child, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
2681  ret = GetMenu(child);
2682  ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2683 
2684  ok(!SetMenu(child, hMenu), "SetMenu on a child window should fail\n");
2686  ret = GetMenu(child);
2687  ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2688 
2689  ok(!SetMenu(child, 0), "SetMenu(0) on a child window should fail\n");
2691  ret = GetMenu(child);
2692  ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2693 
2696  ok(SetMenu(child, hMenu), "SetMenu on a popup child window should not fail\n");
2697  ok(SetMenu(child, 0), "SetMenu on a popup child window should not fail\n");
2699 
2701  ok(!SetMenu(child, hMenu), "SetMenu on an overlapped child window should fail\n");
2703 
2705  DestroyMenu(hMenu);
2706 }
2707 
2708 static void test_window_tree(HWND parent, const DWORD *style, const int *order, int total)
2709 {
2710  HWND child[5], hwnd;
2711  INT_PTR i;
2712 
2713  assert(total <= 5);
2714 
2716  ok(!hwnd, "have to start without children to perform the test\n");
2717 
2718  for (i = 0; i < total; i++)
2719  {
2720  if (style[i] & DS_CONTROL)
2721  {
2722  child[i] = CreateWindowExA(0, (LPCSTR)MAKEINTATOM(32770), "", style[i] & ~WS_VISIBLE,
2723  0,0,0,0, parent, (HMENU)i, 0, NULL);
2724  if (style[i] & WS_VISIBLE)
2726 
2728  }
2729  else
2730  child[i] = CreateWindowExA(0, "static", "", style[i], 0,0,10,10,
2731  parent, (HMENU)i, 0, NULL);
2732  trace("child[%ld] = %p\n", i, child[i]);
2733  ok(child[i] != 0, "CreateWindowEx failed to create child window\n");
2734  }
2735 
2737  ok(hwnd != 0, "GetWindow(GW_CHILD) failed\n");
2738  ok(hwnd == GetWindow(child[total - 1], GW_HWNDFIRST), "GW_HWNDFIRST is wrong\n");
2739  ok(child[order[total - 1]] == GetWindow(child[0], GW_HWNDLAST), "GW_HWNDLAST is wrong\n");
2740 
2741  for (i = 0; i < total; i++)
2742  {
2743  trace("hwnd[%ld] = %p\n", i, hwnd);
2744  ok(child[order[i]] == hwnd, "Z order of child #%ld is wrong\n", i);
2745 
2747  }
2748 
2749  for (i = 0; i < total; i++)
2750  ok(DestroyWindow(child[i]), "DestroyWindow failed\n");
2751 }
2752 
2754 {
2755  const DWORD simple_style[5] = { WS_CHILD, WS_CHILD, WS_CHILD, WS_CHILD,
2756  WS_CHILD };
2757  const int simple_order[5] = { 0, 1, 2, 3, 4 };
2758 
2759  const DWORD complex_style[5] = { WS_CHILD, WS_CHILD | WS_MAXIMIZE,
2762  const int complex_order_1[1] = { 0 };
2763  const int complex_order_2[2] = { 1, 0 };
2764  const int complex_order_3[3] = { 1, 0, 2 };
2765  const int complex_order_4[4] = { 1, 0, 2, 3 };
2766  const int complex_order_5[5] = { 4, 1, 0, 2, 3 };
2767  const DWORD complex_style_6[3] = { WS_CHILD | WS_VISIBLE,
2769  WS_CHILD | WS_VISIBLE };
2770  const int complex_order_6[3] = { 0, 1, 2 };
2771 
2772  /* simple WS_CHILD */
2773  test_window_tree(parent, simple_style, simple_order, 5);
2774 
2775  /* complex children styles */
2776  test_window_tree(parent, complex_style, complex_order_1, 1);
2777  test_window_tree(parent, complex_style, complex_order_2, 2);
2778  test_window_tree(parent, complex_style, complex_order_3, 3);
2779  test_window_tree(parent, complex_style, complex_order_4, 4);
2780  test_window_tree(parent, complex_style, complex_order_5, 5);
2781 
2782  /* another set of complex children styles */
2783  test_window_tree(parent, complex_style_6, complex_order_6, 3);
2784 }
2785 
2786 #define check_z_order(hwnd, next, prev, owner, topmost) \
2787  check_z_order_debug((hwnd), (next), (prev), (owner), (topmost), \
2788  __FILE__, __LINE__)
2789 
2790 static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner,
2791  BOOL topmost, const char *file, int line)
2792 {
2793  HWND test;
2794  DWORD ex_style;
2795 
2797  /* skip foreign windows */
2798  while (test && test != next &&
2801  GetWindow(test, GW_OWNER) == next))
2802  {
2803  /*trace("skipping next %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
2805  }
2806  ok_(file, line)(next == test, "%p: expected next %p, got %p\n", hwnd, next, test);
2807 
2809  /* skip foreign windows */
2810  while (test && test != prev &&
2813  GetWindow(test, GW_OWNER) == hwnd))
2814  {
2815  /*trace("skipping prev %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
2817  }
2818  ok_(file, line)(prev == test, "%p: expected prev %p, got %p\n", hwnd, prev, test);
2819 
2821  ok_(file, line)(owner == test, "%p: expected owner %p, got %p\n", hwnd, owner, test);
2822 
2823  ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
2824  ok_(file, line)(!(ex_style & WS_EX_TOPMOST) == !topmost, "%p: expected %stopmost\n",
2825  hwnd, topmost ? "" : "NOT ");
2826 }
2827 
2828 static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E, DWORD style)
2829 {
2830  HWND hwnd_A, hwnd_B, hwnd_C, hwnd_F;
2831 
2832  trace("hwnd_D %p, hwnd_E %p\n", hwnd_D, hwnd_E);
2833 
2834  SetWindowPos(hwnd_E, hwnd_D, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
2835 
2836  check_z_order(hwnd_D, hwnd_E, 0, 0, FALSE);
2837  check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2838 
2839  hwnd_F = CreateWindowExA(0, "MainWindowClass", "Owner window",
2841  100, 100, 100, 100,
2842  0, 0, GetModuleHandleA(NULL), NULL);
2843  trace("hwnd_F %p\n", hwnd_F);
2844  check_z_order(hwnd_F, hwnd_D, 0, 0, FALSE);
2845 
2846  SetWindowPos(hwnd_F, hwnd_E, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
2847  check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2848  check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2849  check_z_order(hwnd_D, hwnd_E, 0, 0, FALSE);
2850 
2851  hwnd_C = CreateWindowExA(0, "MainWindowClass", NULL,
2852  style,
2853  100, 100, 100, 100,
2854  hwnd_F, 0, GetModuleHandleA(NULL), NULL);
2855  trace("hwnd_C %p\n", hwnd_C);
2856  check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2857  check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2858  check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2859  check_z_order(hwnd_C, hwnd_D, 0, hwnd_F, FALSE);
2860 
2861  hwnd_B = CreateWindowExA(WS_EX_TOPMOST, "MainWindowClass", NULL,
2862  style,
2863  100, 100, 100, 100,
2864  hwnd_F, 0, GetModuleHandleA(NULL), NULL);
2865  trace("hwnd_B %p\n", hwnd_B);
2866  check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2867  check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2868  check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2869  check_z_order(hwnd_C, hwnd_D, hwnd_B, hwnd_F, FALSE);
2870  check_z_order(hwnd_B, hwnd_C, 0, hwnd_F, TRUE);
2871 
2872  hwnd_A = CreateWindowExA(WS_EX_TOPMOST, "MainWindowClass", NULL,
2873  style,
2874  100, 100, 100, 100,
2875  0, 0, GetModuleHandleA(NULL), NULL);
2876  trace("hwnd_A %p\n", hwnd_A);
2877  check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2878  check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2879  check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2880  check_z_order(hwnd_C, hwnd_D, hwnd_B, hwnd_F, FALSE);
2881  check_z_order(hwnd_B, hwnd_C, hwnd_A, hwnd_F, TRUE);
2882  check_z_order(hwnd_A, hwnd_B, 0, 0, TRUE);
2883 
2884  trace("A %p B %p C %p D %p E %p F %p\n", hwnd_A, hwnd_B, hwnd_C, hwnd_D, hwnd_E, hwnd_F);
2885 
2886  /* move hwnd_F and its popups up */
2888  check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2889  check_z_order(hwnd_D, hwnd_E, hwnd_F, 0, FALSE);
2890  check_z_order(hwnd_F, hwnd_D, hwnd_C, 0, FALSE);
2891  check_z_order(hwnd_C, hwnd_F, hwnd_B, hwnd_F, FALSE);
2892  check_z_order(hwnd_B, hwnd_C, hwnd_A, hwnd_F, TRUE);
2893  check_z_order(hwnd_A, hwnd_B, 0, 0, TRUE);
2894 
2895  /* move hwnd_F and its popups down */
2896 #if 0 /* enable once Wine is fixed to pass this test */
2898  check_z_order(hwnd_F, 0, hwnd_C, 0, FALSE);
2899  check_z_order(hwnd_C, hwnd_F, hwnd_B, hwnd_F, FALSE);
2900  check_z_order(hwnd_B, hwnd_C, hwnd_E, hwnd_F, FALSE);
2901  check_z_order(hwnd_E, hwnd_B, hwnd_D, 0, FALSE);
2902  check_z_order(hwnd_D, hwnd_E, hwnd_A, 0, FALSE);
2903  check_z_order(hwnd_A, hwnd_D, 0, 0, TRUE);
2904 #endif
2905 
2906  /* make hwnd_C owned by a topmost window */
2907  DestroyWindow( hwnd_C );
2908  hwnd_C = CreateWindowExA(0, "MainWindowClass", NULL,
2909  style,
2910  100, 100, 100, 100,
2911  hwnd_A, 0, GetModuleHandleA(NULL), NULL);
2912  trace("hwnd_C %p\n", hwnd_C);
2913  check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2914  check_z_order(hwnd_D, hwnd_E, hwnd_F, 0, FALSE);
2915  check_z_order(hwnd_F, hwnd_D, hwnd_B, 0, FALSE);
2916  check_z_order(hwnd_B, hwnd_F, hwnd_A, hwnd_F, TRUE);
2917  check_z_order(hwnd_A, hwnd_B, hwnd_C, 0, TRUE);
2918  check_z_order(hwnd_C, hwnd_A, 0, hwnd_A, TRUE);
2919 
2920  DestroyWindow(hwnd_A);
2921  DestroyWindow(hwnd_B);
2922  DestroyWindow(hwnd_C);
2923  DestroyWindow(hwnd_F);
2924 }
2925 
2926 static void test_vis_rgn( HWND hwnd )
2927 {
2928  RECT win_rect, rgn_rect;
2929  HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
2930  HDC hdc;
2931 
2933  hdc = GetDC( hwnd );
2934  ok( GetRandomRgn( hdc, hrgn, SYSRGN ) != 0, "GetRandomRgn failed\n" );
2935  GetWindowRect( hwnd, &win_rect );
2936  GetRgnBox( hrgn, &rgn_rect );
2937  if (is_win9x)
2938  {
2939  trace("win9x, mapping to screen coords\n");
2940  MapWindowPoints( hwnd, 0, (POINT *)&rgn_rect, 2 );
2941  }
2942  trace("win: %s\n", wine_dbgstr_rect(&win_rect));
2943  trace("rgn: %s\n", wine_dbgstr_rect(&rgn_rect));
2944  ok( win_rect.left <= rgn_rect.left, "rgn left %d not inside win rect %d\n",
2945  rgn_rect.left, win_rect.left );
2946  ok( win_rect.top <= rgn_rect.top, "rgn top %d not inside win rect %d\n",
2947  rgn_rect.top, win_rect.top );
2948  ok( win_rect.right >= rgn_rect.right, "rgn right %d not inside win rect %d\n",
2949  rgn_rect.right, win_rect.right );
2950  ok( win_rect.bottom >= rgn_rect.bottom, "rgn bottom %d not inside win rect %d\n",
2951  rgn_rect.bottom, win_rect.bottom );
2952  ReleaseDC( hwnd, hdc );
2953 }
2954 
2956 {
2957  if (msg == WM_ACTIVATE && LOWORD(wp) == WA_ACTIVE)
2958  {
2960  ok(child != 0, "couldn't find child window\n");
2961  SetFocus(child);
2962  ok(GetFocus() == child, "Focus should be on child %p\n", child);
2963  return 0;
2964  }
2965  return DefWindowProcA(hwnd, msg, wp, lp);
2966 }
2967 
2969 {
2970  HWND child, child2, ret;
2972 
2973  /* check if we can set focus to non-visible windows */
2974 
2976  SetFocus(0);
2977  SetFocus(hwnd);
2978  ok( GetFocus() == hwnd, "Failed to set focus to visible window %p\n", hwnd );
2979  ok( GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE, "Window %p not visible\n", hwnd );
2981  SetFocus(0);
2982  SetFocus(hwnd);
2983  ok( GetFocus() == hwnd, "Failed to set focus to invisible window %p\n", hwnd );
2984  ok( !(GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE), "Window %p still visible\n", hwnd );
2985  child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, hwnd, 0, 0, NULL);
2986  assert(child);
2987  SetFocus(child);
2988  ok( GetFocus() == child, "Failed to set focus to invisible child %p\n", child );
2989  ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
2991  ok( GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE, "Child %p is not visible\n", child );
2992  ok( GetFocus() == child, "Focus no longer on child %p\n", child );
2994  ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
2995  ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
2997  child2 = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, child, 0, 0, NULL);
2998  assert(child2);
2999  ShowWindow(child2, SW_SHOW);
3000  SetFocus(child2);
3002  ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
3003  ok( GetFocus() == child2, "Focus should be on %p, not %p\n", child2, GetFocus() );
3005  SetFocus(child);
3006  ok( GetFocus() == child, "Focus should be on child %p\n", child );
3008  ok( GetFocus() == child, "Focus should still be on child %p\n", child );
3009 
3011  SetFocus(hwnd);
3012  ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
3014  ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
3016  ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
3017 
3020  SetFocus(child);
3021  ok( GetFocus() == child, "Focus should be on child %p\n", child );
3023  ok( GetFocus() == child, "Focus should still be on child %p\n", child );
3025 
3026  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3028  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3029 todo_wine
3030  ok( GetFocus() != child, "Focus should not be on child %p\n", child );
3031  ok( GetFocus() != hwnd, "Focus should not be on parent %p\n", hwnd );
3033  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3034  ok( GetFocus() == hwnd, "Focus should be on parent %p\n", hwnd );
3036  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3037  ok( GetFocus() != child, "Focus should not be on child %p\n", child );
3038 todo_wine
3039  ok( GetFocus() != hwnd, "Focus should not be on parent %p\n", hwnd );
3042  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3043 todo_wine
3044  ok( GetFocus() == child, "Focus should be on child %p, not %p\n", child, GetFocus() );
3046 
3047  SetFocus( hwnd );
3049  SetParent( child2, child );
3050  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3051  ok( GetFocus() == hwnd, "Focus should be on parent %p\n", hwnd );
3052  ret = SetFocus( child2 );
3053  ok( ret == 0, "SetFocus %p should fail\n", child2);
3054  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3055  ok( GetFocus() == hwnd, "Focus should be on parent %p\n", hwnd );
3056  ret = SetFocus( child );
3057  ok( ret == 0, "SetFocus %p should fail\n", child);
3058  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3059  ok( GetFocus() == hwnd, "Focus should be on parent %p\n", hwnd );
3061  SetFocus( child2 );
3062  ok( GetActiveWindow() == child, "child window %p should be active\n", child);
3063  ok( GetFocus() == child2, "Focus should be on child2 %p\n", child2 );
3064  SetFocus( hwnd );
3065  ok( GetActiveWindow() == hwnd, "parent window %p should be active\n", hwnd);
3066  ok( GetFocus() == hwnd, "Focus should be on parent %p\n", hwnd );
3067  SetFocus( child );
3068  ok( GetActiveWindow() == child, "child window %p should be active\n", child);
3069  ok( GetFocus() == child, "Focus should be on child %p\n", child );
3070 
3071  DestroyWindow( child2 );
3072  DestroyWindow( child );
3073 }
3074 
3076 {
3077  HWND hwnd2;
3078 
3079  flush_events( TRUE );
3081  SetFocus(0);
3082  SetActiveWindow(0);
3083  check_wnd_state(0, 0, 0, 0);
3084 
3085  /*trace("testing SetActiveWindow %p\n", hwnd);*/
3086 
3088  check_wnd_state(hwnd, hwnd, hwnd, 0);
3089 
3090  hwnd2 = SetActiveWindow(0);
3091  ok(hwnd2 == hwnd, "SetActiveWindow returned %p instead of %p\n", hwnd2, hwnd);
3092  if (!GetActiveWindow()) /* doesn't always work on vista */
3093  {
3094  check_wnd_state(0, 0, 0, 0);
3095  hwnd2 = SetActiveWindow(hwnd);
3096  ok(hwnd2 == 0, "SetActiveWindow returned %p instead of 0\n", hwnd2);
3097  }
3098  check_wnd_state(hwnd, hwnd, hwnd, 0);
3099 
3101  check_wnd_state(hwnd, hwnd, hwnd, 0);
3102 
3104  check_wnd_state(hwnd, hwnd, hwnd, 0);
3105 
3107  check_wnd_state(0, 0, 0, 0);
3108 
3109  /*trace("testing SetActiveWindow on an invisible window %p\n", hwnd);*/
3111  check_wnd_state(hwnd, hwnd, hwnd, 0);
3112 
3114  check_wnd_state(hwnd, hwnd, hwnd, 0);
3115 
3116  hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
3117  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3118 
3119  DestroyWindow(hwnd2);
3120  check_wnd_state(hwnd, hwnd, hwnd, 0);
3121 
3122  hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
3123  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3124 
3126  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3127 
3128  DestroyWindow(hwnd2);
3129  check_wnd_state(hwnd, hwnd, hwnd, 0);
3130 }
3131 
3133 {
3137 };
3138 
3140 {
3142  DWORD res;
3143  BOOL ret;
3144 
3145  p->window = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0);
3146 
3147  ret = SetEvent(p->window_created);
3148  ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
3149 
3150  res = WaitForSingleObject(p->test_finished, INFINITE);
3151  ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3152 
3153  DestroyWindow(p->window);
3154  return 0;
3155 }
3156 
3158 {
3159  struct create_window_thread_params thread_params;
3160  HANDLE thread;
3161  DWORD res, tid;
3162  BOOL ret;
3163  HWND hwnd2;
3164  MSG msg;
3165  LONG style;
3166 
3167  flush_events( TRUE );
3169  SetFocus(0);
3170  SetActiveWindow(0);
3171  check_wnd_state(0, 0, 0, 0);
3172 
3173  /*trace("testing SetForegroundWindow %p\n", hwnd);*/
3174 
3176  check_wnd_state(hwnd, hwnd, hwnd, 0);
3177 
3178  hwnd2 = SetActiveWindow(0);
3179  ok(hwnd2 == hwnd, "SetActiveWindow(0) returned %p instead of %p\n", hwnd2, hwnd);
3180  if (GetActiveWindow() == hwnd) /* doesn't always work on vista */
3181  check_wnd_state(hwnd, hwnd, hwnd, 0);
3182  else
3183  check_wnd_state(0, 0, 0, 0);
3184 
3186  if (!ret)
3187  {
3188  skip( "SetForegroundWindow not working\n" );
3189  return;
3190  }
3191  check_wnd_state(hwnd, hwnd, hwnd, 0);
3192 
3193  SetLastError(0xdeadbeef);
3194  ret = SetForegroundWindow(0);
3195  ok(!ret, "SetForegroundWindow returned TRUE instead of FALSE\n");
3197  broken(GetLastError() == 0xdeadbeef), /* win9x */
3198  "got error %d expected ERROR_INVALID_WINDOW_HANDLE\n", GetLastError());
3199  check_wnd_state(hwnd, hwnd, hwnd, 0);
3200 
3202  check_wnd_state(hwnd, hwnd, hwnd, 0);
3203 
3205  check_wnd_state(hwnd, hwnd, hwnd, 0);
3206 
3207  hwnd2 = GetForegroundWindow();
3208  ok(hwnd2 == hwnd, "Wrong foreground window %p\n", hwnd2);
3210  ok(ret, "SetForegroundWindow(desktop) error: %d\n", GetLastError());
3211  hwnd2 = GetForegroundWindow();
3212  ok(hwnd2 != hwnd, "Wrong foreground window %p\n", hwnd2);
3213 
3215  check_wnd_state(0, 0, 0, 0);
3216 
3217  /*trace("testing SetForegroundWindow on an invisible window %p\n", hwnd);*/
3219  ok(ret || broken(!ret), /* win98 */ "SetForegroundWindow returned FALSE instead of TRUE\n");
3220  check_wnd_state(hwnd, hwnd, hwnd, 0);
3221 
3223  check_wnd_state(hwnd, hwnd, hwnd, 0);
3224 
3225  hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
3226  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3227 
3228  DestroyWindow(hwnd2);
3229  check_wnd_state(hwnd, hwnd, hwnd, 0);
3230 
3231  hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
3232  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3233 
3235  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3236 
3237  DestroyWindow(hwnd2);
3238  check_wnd_state(hwnd, hwnd, hwnd, 0);
3239 
3240  hwnd2 = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0);
3241  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3242 
3243  thread_params.window_created = CreateEventW(NULL, FALSE, FALSE, NULL);
3244  ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
3245  thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
3246  ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError());
3247  thread = CreateThread(NULL, 0, create_window_thread, &thread_params, 0, &tid);
3248  ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
3249  res = WaitForSingleObject(thread_params.window_created, INFINITE);
3250  ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
3251  check_wnd_state(hwnd2, thread_params.window, hwnd2, 0);
3252 
3253  SetForegroundWindow(hwnd2);
3254  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3255 
3256  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
3257  if (0) check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3258  todo_wine ok(GetActiveWindow() == hwnd2, "Expected active window %p, got %p.\n", hwnd2, GetActiveWindow());
3259  todo_wine ok(GetFocus() == hwnd2, "Expected focus window %p, got %p.\n", hwnd2, GetFocus());
3260 
3262  check_wnd_state(hwnd, hwnd, hwnd, 0);
3263  style = GetWindowLongA(hwnd2, GWL_STYLE) | WS_CHILD;
3264  ok(SetWindowLongA(hwnd2, GWL_STYLE, style), "SetWindowLong failed\n");
3265  ok(SetForegroundWindow(hwnd2), "SetForegroundWindow failed\n");
3266  check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
3267 
3269  check_wnd_state(hwnd, hwnd, hwnd, 0);
3270  ok(SetWindowLongA(hwnd2, GWL_STYLE, style & (~WS_POPUP)), "SetWindowLong failed\n");
3271  ok(!SetForegroundWindow(hwnd2), "SetForegroundWindow failed\n");
3272  check_wnd_state(hwnd, hwnd, hwnd, 0);
3273 
3274  SetEvent(thread_params.test_fi