ReactOS 0.4.15-dev-7889-g76290a6
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
36void dump_region(HRGN hrgn);
37
38static HWND (WINAPI *pGetAncestor)(HWND,UINT);
39static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
40static UINT (WINAPI *pGetWindowModuleFileNameA)(HWND,LPSTR,UINT);
41static BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF*,BYTE*,DWORD*);
42static BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
43static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
44static BOOL (WINAPI *pUpdateLayeredWindowIndirect)(HWND,const UPDATELAYEREDWINDOWINFO*);
45static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
46static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
47static int (WINAPI *pGetWindowRgnBox)(HWND,LPRECT);
48static BOOL (WINAPI *pGetGUIThreadInfo)(DWORD, GUITHREADINFO*);
49static BOOL (WINAPI *pGetProcessDefaultLayout)( DWORD *layout );
50static BOOL (WINAPI *pSetProcessDefaultLayout)( DWORD layout );
51static BOOL (WINAPI *pFlashWindow)( HWND hwnd, BOOL bInvert );
52static BOOL (WINAPI *pFlashWindowEx)( PFLASHWINFO pfwi );
53static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
54static DWORD (WINAPI *pGetLayout)(HDC hdc);
55static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn);
56
62static HHOOK hhook;
64
65static const char* szAWRClass = "Winsize";
66static HMENU hmenu;
68
70
71#define COUNTOF(arr) (sizeof(arr)/sizeof(arr[0]))
72
73static 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 */
84static 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 */
118static 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 );
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)
144static 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() &&
153 ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
154 ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
155 ok_(file, line)(capture == GetCapture(), "GetCapture() = %p\n", GetCapture());
156}
157
158/* same as above but without capture test */
159#define check_active_state(a,b,c) check_active_state_(__FILE__,__LINE__,a,b,c)
160static void check_active_state_(const char *file, int line,
161 HWND active, HWND foreground, HWND focus)
162{
163 ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
164 /* only check foreground if it belongs to the current thread */
165 /* foreground can be moved to a different app pretty much at any time */
166 if (foreground && GetForegroundWindow() &&
169 ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
170 ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
171}
172
174{
175 /* these are always ignored */
176 return (message >= 0xc000 ||
177 message == WM_GETICON ||
178 message == WM_GETOBJECT ||
179 message == WM_TIMER ||
180 message == WM_SYSTIMER ||
183}
184
186{
187 (*(LPINT)lParam)++;
188 trace("EnumChildProc on %p\n", hwndChild);
189 if (*(LPINT)lParam > 1) return FALSE;
190 return TRUE;
191}
192
193/* will search for the given window */
195{
196 trace("EnumChildProc1 on %p\n", hwndChild);
197 if ((HWND)lParam == hwndChild) return FALSE;
198 return TRUE;
199}
200
202{
203 HWND ret = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", style,
204 0, 0, 100, 100, parent, 0, 0, NULL );
205 ok( ret != 0, "Creation failed\n" );
206 return ret;
207}
208
209/* test parent and owner values for various combinations */
210static void test_parent_owner(void)
211{
212 LONG style;
213 HWND test, owner, ret;
214 HWND desktop = GetDesktopWindow();
216 INT numChildren;
217
218 trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
219
220 /* child without parent, should fail */
221 SetLastError(0xdeadbeef);
222 test = CreateWindowExA(0, "ToolWindowClass", "Tool window 1",
223 WS_CHILD, 0, 0, 100, 100, 0, 0, 0, NULL );
224 ok( !test, "WS_CHILD without parent created\n" );
226 broken(GetLastError() == 0xdeadbeef), /* win9x */
227 "CreateWindowExA error %u\n", GetLastError() );
228
229 /* desktop window */
230 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
231 style = GetWindowLongA( desktop, GWL_STYLE );
232 ok( !SetWindowLongA( desktop, GWL_STYLE, WS_POPUP ), "Set GWL_STYLE on desktop succeeded\n" );
233 ok( !SetWindowLongA( desktop, GWL_STYLE, 0 ), "Set GWL_STYLE on desktop succeeded\n" );
234 ok( GetWindowLongA( desktop, GWL_STYLE ) == style, "Desktop style changed\n" );
235
236 /* normal child window */
238 trace( "created child %p\n", test );
248
249 /* normal child window with WS_MAXIMIZE */
252
253 /* normal child window with WS_THICKFRAME */
256
257 /* popup window with WS_THICKFRAME */
260
261 /* child of desktop */
262 test = create_tool_window( WS_CHILD, desktop );
263 trace( "created child of desktop %p\n", test );
264 check_parents( test, desktop, 0, desktop, 0, test, desktop );
266 check_parents( test, desktop, 0, 0, 0, test, test );
268 check_parents( test, desktop, 0, 0, 0, test, test );
270
271 /* child of desktop with WS_MAXIMIZE */
274
275 /* child of desktop with WS_MINIMIZE */
278
279 /* child of child */
281 trace( "created child of child %p\n", test );
288
289 /* child of child with WS_MAXIMIZE */
292
293 /* child of child with WS_MINIMIZE */
296
297 /* not owned top-level window */
298 test = create_tool_window( 0, 0 );
299 trace( "created top-level %p\n", test );
300 check_parents( test, desktop, 0, 0, 0, test, test );
302 check_parents( test, desktop, 0, 0, 0, test, test );
304 check_parents( test, desktop, 0, desktop, 0, test, desktop );
306
307 /* not owned top-level window with WS_MAXIMIZE */
310
311 /* owned top-level window */
313 trace( "created owned top-level %p\n", test );
314 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
318 check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
320
321 /* owned top-level window with WS_MAXIMIZE */
324
325 /* not owned popup */
327 trace( "created popup %p\n", test );
328 check_parents( test, desktop, 0, 0, 0, test, test );
330 check_parents( test, desktop, 0, desktop, 0, test, desktop );
332 check_parents( test, desktop, 0, 0, 0, test, test );
334
335 /* not owned popup with WS_MAXIMIZE */
338
339 /* owned popup */
341 trace( "created owned popup %p\n", test );
344 check_parents( test, desktop, hwndMain, desktop, hwndMain, test, desktop );
346 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
348
349 /* owned popup with WS_MAXIMIZE */
352
353 /* top-level window owned by child (same as owned by top-level) */
355 trace( "created top-level owned by child %p\n", test );
356 check_parents( test, desktop, hwndMain, 0, hwndMain, test, test );
358
359 /* top-level window owned by child (same as owned by top-level) with WS_MAXIMIZE */
362
363 /* popup owned by desktop (same as not owned) */
364 test = create_tool_window( WS_POPUP, desktop );
365 trace( "created popup owned by desktop %p\n", test );
366 check_parents( test, desktop, 0, 0, 0, test, test );
368
369 /* popup owned by desktop (same as not owned) with WS_MAXIMIZE */
372
373 /* popup owned by child (same as owned by top-level) */
375 trace( "created popup owned by child %p\n", test );
378
379 /* popup owned by child (same as owned by top-level) with WS_MAXIMIZE */
382
383 /* not owned popup with WS_CHILD (same as WS_POPUP only) */
385 trace( "created WS_CHILD popup %p\n", test );
386 check_parents( test, desktop, 0, 0, 0, test, test );
388
389 /* not owned popup with WS_CHILD | WS_MAXIMIZE (same as WS_POPUP only) */
392
393 /* owned popup with WS_CHILD (same as WS_POPUP only) */
395 trace( "created owned WS_CHILD popup %p\n", test );
398
399 /* owned popup with WS_CHILD (same as WS_POPUP only) with WS_MAXIMIZE */
402
403 /******************** parent changes *************************/
404 trace( "testing parent changes\n" );
405
406 /* desktop window */
407 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
408 if (0)
409 {
410 /* this test succeeds on NT but crashes on win9x systems */
412 ok( !ret, "Set GWL_HWNDPARENT succeeded on desktop\n" );
413 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
414 ok( !SetParent( desktop, hwndMain ), "SetParent succeeded on desktop\n" );
415 check_parents( desktop, 0, 0, 0, 0, 0, 0 );
416 }
417 /* normal child window */
419 trace( "created child %p\n", test );
420
422 ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain );
424
426 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
428
430 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
431 check_parents( test, desktop, 0, desktop, 0, test, desktop );
432
433 /* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */
434 if (!is_win9x)
435 {
437 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
438 check_parents( test, desktop, 0, desktop, 0, test, desktop );
439 }
440 else
441 win_skip("Test creates circular window tree under Win9x/WinMe\n" );
442
444 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
445 check_parents( test, desktop, child, desktop, child, test, desktop );
446
448 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
449 check_parents( test, desktop, 0, desktop, 0, test, desktop );
451
452 /* not owned top-level window */
453 test = create_tool_window( 0, 0 );
454 trace( "created top-level %p\n", test );
455
457 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
458 check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
459
461 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
462 check_parents( test, desktop, child, 0, child, test, test );
463
465 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
466 check_parents( test, desktop, 0, 0, 0, test, test );
468
469 /* not owned popup */
471 trace( "created popup %p\n", test );
472
474 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
476
478 ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 );
480
482 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
483 check_parents( test, desktop, 0, 0, 0, test, test );
485
486 /* normal child window */
488 trace( "created child %p\n", test );
489
490 ret = SetParent( test, desktop );
491 ok( ret == hwndMain, "SetParent return value %p expected %p\n", ret, hwndMain );
492 check_parents( test, desktop, 0, desktop, 0, test, desktop );
493
494 ret = SetParent( test, child );
495 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
497
499 ok( ret == child, "SetParent return value %p expected %p\n", ret, child );
502
503 /* not owned top-level window */
504 test = create_tool_window( 0, 0 );
505 trace( "created top-level %p\n", test );
506
507 ret = SetParent( test, child );
508 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
510
511 if (!is_win9x)
512 {
514 ret = SetParent( test, test );
515 ok( ret == NULL, "SetParent return value %p expected %p\n", ret, NULL );
516 ok( GetWindowLongA( test, GWL_STYLE ) & WS_VISIBLE, "window is not visible after SetParent\n" );
518 }
519 else
520 win_skip( "Test crashes on Win9x/WinMe\n" );
522
523 /* owned popup */
525 trace( "created owned popup %p\n", test );
526
527 ret = SetParent( test, child );
528 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
530
532 ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child );
535
536 /**************** test owner destruction *******************/
537
538 /* owned child popup */
539 owner = create_tool_window( 0, 0 );
540 test = create_tool_window( WS_POPUP, owner );
541 trace( "created owner %p and popup %p\n", owner, test );
542 ret = SetParent( test, child );
543 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
544 check_parents( test, child, child, owner, owner, hwndMain, owner );
545 /* window is now child of 'child' but owned by 'owner' */
546 DestroyWindow( owner );
547 ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
548 /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
549 * while Win95, Win2k, WinXP do.
550 */
551 /*check_parents( test, child, child, owner, owner, hwndMain, owner );*/
552 ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
554
555 /* owned top-level popup */
556 owner = create_tool_window( 0, 0 );
557 test = create_tool_window( WS_POPUP, owner );
558 trace( "created owner %p and popup %p\n", owner, test );
559 check_parents( test, desktop, owner, owner, owner, test, owner );
560 DestroyWindow( owner );
561 ok( !IsWindow(test), "Window %p not destroyed by owner destruction\n", test );
562
563 /* top-level popup owned by child */
566 trace( "created owner %p and popup %p\n", owner, test );
568 ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
569 check_parents( test, desktop, owner, owner, owner, test, hwndMain2 );
570 DestroyWindow( owner );
571 ok( IsWindow(test), "Window %p destroyed by owner destruction\n", test );
572 ok( !IsWindow(owner), "Owner %p not destroyed\n", owner );
573 /* Win98 doesn't pass this test. It doesn't allow a destroyed owner,
574 * while Win95, Win2k, WinXP do.
575 */
576 /*check_parents( test, desktop, owner, owner, owner, test, owner );*/
578
579 /* final cleanup */
581
582
583 owner = create_tool_window( WS_OVERLAPPED, 0 );
584 test = create_tool_window( WS_POPUP, desktop );
585
586 ok( !GetWindow( test, GW_OWNER ), "Wrong owner window\n" );
587 numChildren = 0;
588 ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
589 "EnumChildWindows should have returned FALSE\n" );
590 ok( numChildren == 0, "numChildren should be 0 got %d\n", numChildren );
591
593 ret = SetParent( test, owner );
594 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
595
596 numChildren = 0;
597 ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
598 "EnumChildWindows should have returned TRUE\n" );
599 ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
600
602 numChildren = 0;
603 ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
604 "EnumChildWindows should have returned FALSE\n" );
605 ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
607
609 ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
610 numChildren = 0;
611 ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
612 "EnumChildWindows should have returned TRUE\n" );
613 ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
614
615 ret = SetParent( child, owner );
616 ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
617 ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop );
618 numChildren = 0;
619 ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
620 "EnumChildWindows should have returned FALSE\n" );
621 ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren );
622
623 ret = SetParent( child, NULL );
624 ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" );
625 ok( ret == owner, "SetParent return value %p expected %p\n", ret, owner );
626 numChildren = 0;
627 ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ),
628 "EnumChildWindows should have returned TRUE\n" );
629 ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren );
630
631 /* even GW_OWNER == owner it's still a desktop's child */
633 "EnumChildWindows should have found %p and returned FALSE\n", child );
634
637
639 "EnumChildWindows should have found %p and returned FALSE\n", child );
640
643 DestroyWindow( owner );
644
645 /* Test that owner window takes into account WS_CHILD flag even if parent is set by SetParent. */
647 SetParent(owner, hwndMain);
648 check_parents( owner, hwndMain, hwndMain, NULL, NULL, hwndMain, owner );
650 check_parents( test, desktop, owner, NULL, owner, test, test );
651 DestroyWindow( owner );
653
654 owner = create_tool_window( WS_VISIBLE | WS_CHILD, desktop );
655 SetParent(owner, hwndMain);
659 DestroyWindow( owner );
661
662 owner = create_tool_window( WS_VISIBLE | WS_POPUP | WS_CHILD, desktop );
663 SetParent(owner, hwndMain);
664 check_parents( owner, hwndMain, hwndMain, NULL, NULL, hwndMain, owner );
666 check_parents( test, desktop, owner, NULL, owner, test, test );
667 DestroyWindow( owner );
669}
670
672{
673 (*(LPINT)lParam)++;
674 if (*(LPINT)lParam > 2) return FALSE;
675 return TRUE;
676}
678{
679 INT count;
680 HWND hwnd[3];
681 BOOL ret;
682 MSG msg;
683
684 if (pGetGUIThreadInfo)
685 {
687 info.cbSize = sizeof(info);
688 ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
689 ok( ret || broken(!ret), /* win9x */
690 "GetGUIThreadInfo failed without message queue\n" );
691 SetLastError( 0xdeadbeef );
692 info.cbSize = sizeof(info) + 1;
693 ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
694 ok( !ret, "GetGUIThreadInfo succeeded with wrong size\n" );
696 broken(GetLastError() == 0xdeadbeef), /* win9x */
697 "wrong error %u\n", GetLastError() );
698 }
699
700 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ); /* make sure we have a message queue */
701
702 count = 0;
704 ok( ret, "EnumThreadWindows should have returned TRUE\n" );
705 ok( count == 0, "count should be 0 got %d\n", count );
706
707 hwnd[0] = CreateWindowExA(0, "ToolWindowClass", "Tool window 1", WS_POPUP,
708 0, 0, 100, 100, 0, 0, 0, NULL );
709 count = 0;
711 ok( ret, "EnumThreadWindows should have returned TRUE\n" );
712 if (count != 2) /* Vista gives us two windows for the price of one */
713 {
714 ok( count == 1, "count should be 1 got %d\n", count );
715 hwnd[2] = CreateWindowExA(0, "ToolWindowClass", "Tool window 2", WS_POPUP,
716 0, 0, 100, 100, 0, 0, 0, NULL );
717 }
718 else hwnd[2] = 0;
719
720 hwnd[1] = CreateWindowExA(0, "ToolWindowClass", "Tool window 3", WS_POPUP,
721 0, 0, 100, 100, 0, 0, 0, NULL );
722 count = 0;
724 ok( !ret, "EnumThreadWindows should have returned FALSE\n" );
725 ok( count == 3, "count should be 3 got %d\n", count );
726
727 if (hwnd[2]) DestroyWindow(hwnd[2]);
730 return 0;
731}
732
733/* test EnumThreadWindows in a separate thread */
735{
736 DWORD id;
737 HANDLE handle = CreateThread( NULL, 0, enum_thread, 0, 0, &id );
738 ok( !WaitForSingleObject( handle, 10000 ), "wait failed\n" );
740}
741
743{
744 BOOL enabled; /* when 1 bypasses default procedure */
745 char *buff; /* expected text buffer pointer */
746 WCHAR *buffW; /* same, for W test */
748
750{
751 switch (msg)
752 {
753 case WM_GETMINMAXINFO:
754 {
756 break;
757 }
759 {
760 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
761 if (!(winpos->flags & SWP_NOMOVE))
762 {
763 ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
764 ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
765 }
766 /* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
767 if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
768 {
769 ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
770 winpos->cx == 32768, /* win7 doesn't truncate */
771 "bad winpos->cx %d\n", winpos->cx);
772 ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
773 winpos->cy == 40000, /* win7 doesn't truncate */
774 "bad winpos->cy %d\n", winpos->cy);
775 }
776 break;
777 }
780 {
781 RECT rc1, rc2;
782 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
783 ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
784 ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
785
786 ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
787 winpos->cx == 32768, /* win7 doesn't truncate */
788 "bad winpos->cx %d\n", winpos->cx);
789 ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
790 winpos->cy == 40000, /* win7 doesn't truncate */
791 "bad winpos->cy %d\n", winpos->cy);
792
793 GetWindowRect(hwnd, &rc1);
794 SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
795 /* note: winpos coordinates are relative to parent */
797 if (0)
798 {
799 /* Uncomment this once the test succeeds in all cases */
800 ok(EqualRect(&rc1, &rc2), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc1),
802
805 MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
806 ok(EqualRect(&rc1, &rc2), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc1),
808 }
809 break;
810 }
811 case WM_NCCREATE:
812 {
813 BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
815
816 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
817 ok(got_getminmaxinfo, "main: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
818 else
819 ok(!got_getminmaxinfo, "main: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
820 break;
821 }
822 case WM_COMMAND:
824 {
827 }
828 break;
829 case WM_GETTEXT:
831 if (g_wm_gettext_override.enabled)
832 {
833 char *text = (char*)lparam;
834 ok(g_wm_gettext_override.buff == text, "expected buffer %p, got %p\n", g_wm_gettext_override.buff, text);
835 ok(*text == 0, "expected empty string buffer %x\n", *text);
836 return 0;
837 }
838 break;
839 case WM_SETTEXT:
841 break;
842 case WM_ACTIVATEAPP:
844 else app_deactivated = TRUE;
845 break;
846 }
847
849}
850
852{
853 switch (msg)
854 {
855 case WM_GETTEXT:
857 if (g_wm_gettext_override.enabled)
858 {
859 WCHAR *text = (WCHAR*)lparam;
860 ok(g_wm_gettext_override.buffW == text, "expected buffer %p, got %p\n", g_wm_gettext_override.buffW, text);
861 ok(*text == 0, "expected empty string buffer %x\n", *text);
862 return 0;
863 }
864 break;
865 }
866
868}
869
871{
872 switch (msg)
873 {
874 case WM_GETMINMAXINFO:
875 {
877 break;
878 }
879 case WM_NCCREATE:
880 {
881 BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021;
883
884 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
885 ok(got_getminmaxinfo, "tool: WM_GETMINMAXINFO should have been received before WM_NCCREATE\n");
886 else
887 ok(!got_getminmaxinfo, "tool: WM_GETMINMAXINFO should NOT have been received before WM_NCCREATE\n");
888 break;
889 }
890 }
891
893}
894
895static const WCHAR mainclassW[] = {'M','a','i','n','W','i','n','d','o','w','C','l','a','s','s','W',0};
896
898{
899 WNDCLASSW clsW;
900 WNDCLASSA cls;
901
902 cls.style = CS_DBLCLKS;
904 cls.cbClsExtra = 0;
905 cls.cbWndExtra = 0;
907 cls.hIcon = 0;
910 cls.lpszMenuName = NULL;
911 cls.lpszClassName = "MainWindowClass";
912
913 if(!RegisterClassA(&cls)) return FALSE;
914
915 clsW.style = CS_DBLCLKS;
917 clsW.cbClsExtra = 0;
918 clsW.cbWndExtra = 0;
919 clsW.hInstance = GetModuleHandleA(0);
920 clsW.hIcon = 0;
923 clsW.lpszMenuName = NULL;
925
926 if(!RegisterClassW(&clsW)) return FALSE;
927
928 cls.style = 0;
930 cls.cbClsExtra = 0;
931 cls.cbWndExtra = 0;
933 cls.hIcon = 0;
936 cls.lpszMenuName = NULL;
937 cls.lpszClassName = "ToolWindowClass";
938
939 if(!RegisterClassA(&cls)) return FALSE;
940
941 return TRUE;
942}
943
944static void verify_window_info(const char *hook, HWND hwnd, const WINDOWINFO *info)
945{
946 RECT rcWindow, rcClient;
948
949 ok(IsWindow(hwnd), "bad window handle %p in hook %s\n", hwnd, hook);
950
951 GetWindowRect(hwnd, &rcWindow);
952 ok(EqualRect(&rcWindow, &info->rcWindow), "wrong rcWindow for %p in hook %s\n", hwnd, hook);
953
954 GetClientRect(hwnd, &rcClient);
955 /* translate to screen coordinates */
956 MapWindowPoints(hwnd, 0, (LPPOINT)&rcClient, 2);
957 ok(EqualRect(&rcClient, &info->rcClient), "wrong rcClient for %p in hook %s\n", hwnd, hook);
958
959 ok(info->dwStyle == (DWORD)GetWindowLongA(hwnd, GWL_STYLE),
960 "wrong dwStyle: %08x != %08x for %p in hook %s\n",
961 info->dwStyle, GetWindowLongA(hwnd, GWL_STYLE), hwnd, hook);
962 /* Windows reports some undocumented exstyles in WINDOWINFO, but
963 * doesn't return them in GetWindowLong(hwnd, GWL_EXSTYLE).
964 */
965 ok((info->dwExStyle & ~0xe0000800) == (DWORD)GetWindowLongA(hwnd, GWL_EXSTYLE),
966 "wrong dwExStyle: %08x != %08x for %p in hook %s\n",
967 info->dwExStyle, GetWindowLongA(hwnd, GWL_EXSTYLE), hwnd, hook);
970 ok(info->dwWindowStatus == status, "wrong dwWindowStatus: %04x != %04x active %p fg %p in hook %s\n",
971 info->dwWindowStatus, status, GetActiveWindow(), GetForegroundWindow(), hook);
972 else
973 ok(1, "Just counting");
974
975 /* win2k and XP return broken border info in GetWindowInfo most of
976 * the time, so there is no point in testing it.
977 */
978if (0)
979{
980 UINT border;
981 ok(info->cxWindowBorders == (unsigned)(rcClient.left - rcWindow.left),
982 "wrong cxWindowBorders %d != %d\n", info->cxWindowBorders, rcClient.left - rcWindow.left);
983 border = min(rcWindow.bottom - rcClient.bottom, rcClient.top - rcWindow.top);
984 ok(info->cyWindowBorders == border,
985 "wrong cyWindowBorders %d != %d\n", info->cyWindowBorders, border);
986}
987 ok(info->atomWindowType == GetClassLongA(hwnd, GCW_ATOM), "wrong atomWindowType for %p in hook %s\n",
988 hwnd, hook);
989 ok(info->wCreatorVersion == 0x0400 /* NT4, Win2000, XP, Win2003 */ ||
990 info->wCreatorVersion == 0x0500 /* Vista */,
991 "wrong wCreatorVersion %04x for %p in hook %s\n", info->wCreatorVersion, hwnd, hook);
992}
993
994static void FixedAdjustWindowRectEx(RECT* rc, LONG style, BOOL menu, LONG exstyle)
995{
996 AdjustWindowRectEx(rc, style, menu, exstyle);
997 /* AdjustWindowRectEx does not include scroll bars */
998 if (style & WS_VSCROLL)
999 {
1000 if(exstyle & WS_EX_LEFTSCROLLBAR)
1002 else
1004 }
1005 if (style & WS_HSCROLL)
1007}
1008
1009/* reimplement it to check that the Wine algorithm gives the correct result */
1010static void wine_AdjustWindowRectEx( RECT *rect, LONG style, BOOL menu, LONG exStyle )
1011{
1012 int adjust;
1013
1014 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
1016 {
1017 adjust = 1; /* for the outer frame always present */
1018 }
1019 else
1020 {
1021 adjust = 0;
1022 if ((exStyle & WS_EX_DLGMODALFRAME) ||
1023 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
1024 }
1025 if (style & WS_THICKFRAME)
1026 adjust += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); /* The resize border */
1027 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
1028 (exStyle & WS_EX_DLGMODALFRAME))
1029 adjust++; /* The other border */
1030
1031 InflateRect (rect, adjust, adjust);
1032
1033 if ((style & WS_CAPTION) == WS_CAPTION)
1034 {
1035 if (exStyle & WS_EX_TOOLWINDOW)
1037 else
1039 }
1040 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
1041
1042 if (exStyle & WS_EX_CLIENTEDGE)
1044
1045 if (style & WS_VSCROLL)
1046 {
1047 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
1049 else
1051 }
1053}
1054
1056{
1057 DWORD style, exstyle;
1058 RECT rc_window, rc_client, rc;
1059 BOOL menu;
1060 LRESULT ret;
1061
1063 exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1064 menu = !(style & WS_CHILD) && GetMenu(hwnd) != 0;
1065
1066 GetWindowRect(hwnd, &rc_window);
1067 GetClientRect(hwnd, &rc_client);
1068
1069 /* avoid some cases when things go wrong */
1070 if (IsRectEmpty(&rc_window) || IsRectEmpty(&rc_client) ||
1071 rc_window.right > 32768 || rc_window.bottom > 32768) return;
1072
1073 rc = rc_client;
1074 MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
1075 FixedAdjustWindowRectEx(&rc, style, menu, exstyle);
1076
1077 ok(EqualRect(&rc, &rc_window),
1078 "window rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, win=%s, calc=%s\n",
1079 style, exstyle, menu, wine_dbgstr_rect(&rc_window), wine_dbgstr_rect(&rc));
1080
1081 rc = rc_client;
1082 MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
1083 wine_AdjustWindowRectEx(&rc, style, menu, exstyle);
1084 ok(EqualRect(&rc, &rc_window),
1085 "window rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, win=%s, calc=%s\n",
1086 style, exstyle, menu, wine_dbgstr_rect(&rc_window), wine_dbgstr_rect(&rc));
1087
1088
1089 rc = rc_window;
1091 MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
1092 ok(EqualRect(&rc, &rc_client),
1093 "client rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d client=%s, calc=%s\n",
1094 style, exstyle, menu, wine_dbgstr_rect(&rc_client), wine_dbgstr_rect(&rc));
1095
1096 /* NULL rectangle shouldn't crash */
1098 ok(ret == 0, "NULL rectangle returned %ld instead of 0\n", ret);
1099
1100 /* Win9x doesn't like WM_NCCALCSIZE with synthetic data and crashes */;
1101 if (is_win9x)
1102 return;
1103
1104 /* and now test AdjustWindowRectEx and WM_NCCALCSIZE on synthetic data */
1105 SetRect(&rc_client, 0, 0, 250, 150);
1106 rc_window = rc_client;
1107 MapWindowPoints(hwnd, 0, (LPPOINT)&rc_window, 2);
1108 FixedAdjustWindowRectEx(&rc_window, style, menu, exstyle);
1109
1110 rc = rc_window;
1112 MapWindowPoints(0, hwnd, (LPPOINT)&rc, 2);
1113 ok(EqualRect(&rc, &rc_client),
1114 "synthetic rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, client=%s, calc=%s\n",
1115 style, exstyle, menu, wine_dbgstr_rect(&rc_client), wine_dbgstr_rect(&rc));
1116}
1117
1119{
1120 static const char *CBT_code_name[10] = {
1121 "HCBT_MOVESIZE",
1122 "HCBT_MINMAX",
1123 "HCBT_QS",
1124 "HCBT_CREATEWND",
1125 "HCBT_DESTROYWND",
1126 "HCBT_ACTIVATE",
1127 "HCBT_CLICKSKIPPED",
1128 "HCBT_KEYSKIPPED",
1129 "HCBT_SYSCOMMAND",
1130 "HCBT_SETFOCUS" };
1131 const char *code_name = (nCode >= 0 && nCode <= HCBT_SETFOCUS) ? CBT_code_name[nCode] : "Unknown";
1132 HWND hwnd = (HWND)wParam;
1133
1134 switch (nCode)
1135 {
1136 case HCBT_CREATEWND:
1137 {
1138 static const RECT rc_null;
1139 RECT rc;
1140 LONG style;
1141 CBT_CREATEWNDA *createwnd = (CBT_CREATEWNDA *)lParam;
1142 ok(createwnd->hwndInsertAfter == HWND_TOP, "hwndInsertAfter should be always HWND_TOP\n");
1143
1144 if (pGetWindowInfo)
1145 {
1147 info.cbSize = sizeof(WINDOWINFO);
1148 ok(pGetWindowInfo(hwnd, &info), "GetWindowInfo should not fail\n");
1149 verify_window_info(code_name, hwnd, &info);
1150 }
1151
1152 /* WS_VISIBLE should be turned off yet */
1153 style = createwnd->lpcs->style & ~WS_VISIBLE;
1155 "style of hwnd and style in the CREATESTRUCT do not match: %08x != %08x\n",
1157
1158 if (0)
1159 {
1160 /* Uncomment this once the test succeeds in all cases */
1161 if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
1162 {
1164 "wrong result from GetParent %p: message window %p\n",
1166 }
1167 else
1168 ok(!GetParent(hwnd), "GetParent should return 0 at this point\n");
1169
1170 ok(!GetWindow(hwnd, GW_OWNER), "GW_OWNER should be set to 0 at this point\n");
1171 }
1172 if (0)
1173 {
1174 /* while NT assigns GW_HWNDFIRST/LAST some values at this point,
1175 * Win9x still has them set to 0.
1176 */
1177 ok(GetWindow(hwnd, GW_HWNDFIRST) != 0, "GW_HWNDFIRST should not be set to 0 at this point\n");
1178 ok(GetWindow(hwnd, GW_HWNDLAST) != 0, "GW_HWNDLAST should not be set to 0 at this point\n");
1179 }
1180 ok(!GetWindow(hwnd, GW_HWNDPREV), "GW_HWNDPREV should be set to 0 at this point\n");
1181 ok(!GetWindow(hwnd, GW_HWNDNEXT), "GW_HWNDNEXT should be set to 0 at this point\n");
1182
1183 if (0)
1184 {
1185 /* Uncomment this once the test succeeds in all cases */
1186 if (pGetAncestor)
1187 {
1188 ok(pGetAncestor(hwnd, GA_PARENT) == hwndMessage, "GA_PARENT should be set to hwndMessage at this point\n");
1189 ok(pGetAncestor(hwnd, GA_ROOT) == hwnd,
1190 "GA_ROOT is set to %p, expected %p\n", pGetAncestor(hwnd, GA_ROOT), hwnd);
1191
1192 if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
1193 ok(pGetAncestor(hwnd, GA_ROOTOWNER) == hwndMessage,
1194 "GA_ROOTOWNER should be set to hwndMessage at this point\n");
1195 else
1196 ok(pGetAncestor(hwnd, GA_ROOTOWNER) == hwnd,
1197 "GA_ROOTOWNER is set to %p, expected %p\n", pGetAncestor(hwnd, GA_ROOTOWNER), hwnd);
1198 }
1199
1200 ok(GetWindowRect(hwnd, &rc), "GetWindowRect failed\n");
1201 ok(EqualRect(&rc, &rc_null), "window rect should be set to 0 HCBT_CREATEWND\n");
1202 ok(GetClientRect(hwnd, &rc), "GetClientRect failed\n");
1203 ok(EqualRect(&rc, &rc_null), "client rect should be set to 0 on HCBT_CREATEWND\n");
1204 }
1205 break;
1206 }
1207 case HCBT_MOVESIZE:
1208 case HCBT_MINMAX:
1209 case HCBT_ACTIVATE:
1210 if (pGetWindowInfo && IsWindow(hwnd))
1211 {
1213
1214 /* Win98 actually does check the info.cbSize and doesn't allow
1215 * it to be anything except sizeof(WINDOWINFO), while Win95, Win2k,
1216 * WinXP do not check it at all.
1217 */
1218 info.cbSize = sizeof(WINDOWINFO);
1219 ok(pGetWindowInfo(hwnd, &info), "GetWindowInfo should not fail\n");
1220 verify_window_info(code_name, hwnd, &info);
1221 }
1222 break;
1223 /* window state is undefined */
1224 case HCBT_SETFOCUS:
1225 case HCBT_DESTROYWND:
1226 break;
1227 default:
1228 break;
1229 }
1230
1231 return CallNextHookEx(hhook, nCode, wParam, lParam);
1232}
1233
1234static void test_shell_window(void)
1235{
1236 BOOL ret;
1237 DWORD error;
1238 HMODULE hinst, hUser32;
1240 HWND hwnd1, hwnd2, hwnd3, hwnd4, hwnd5;
1241 HWND shellWindow, nextWnd;
1242
1243 if (is_win9x)
1244 {
1245 win_skip("Skipping shell window test on Win9x\n");
1246 return;
1247 }
1248
1249 shellWindow = GetShellWindow();
1251 hUser32 = GetModuleHandleA("user32");
1252
1253 SetShellWindow = (void *)GetProcAddress(hUser32, "SetShellWindow");
1254
1255 trace("previous shell window: %p\n", shellWindow);
1256
1257 if (shellWindow) {
1258 DWORD pid;
1260
1261 GetWindowThreadProcessId(shellWindow, &pid);
1263 if (!hProcess)
1264 {
1265 skip( "cannot get access to shell process\n" );
1266 return;
1267 }
1268
1269 SetLastError(0xdeadbeef);
1270 ret = DestroyWindow(shellWindow);
1271 error = GetLastError();
1272
1273 ok(!ret, "DestroyWindow(shellWindow)\n");
1274 /* passes on Win XP, but not on Win98 */
1275 ok(error==ERROR_ACCESS_DENIED || error == 0xdeadbeef,
1276 "got %u after DestroyWindow(shellWindow)\n", error);
1277
1278 /* close old shell instance */
1280 ok(ret, "termination of previous shell process failed: GetLastError()=%d\n", GetLastError());
1281 WaitForSingleObject(hProcess, INFINITE); /* wait for termination */
1283 }
1284
1285 hwnd1 = CreateWindowExA(0, "#32770", "TEST1", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 100, 100, 300, 200, 0, 0, hinst, 0);
1286 trace("created window 1: %p\n", hwnd1);
1287
1288 ret = SetShellWindow(hwnd1);
1289 ok(ret, "first call to SetShellWindow(hwnd1)\n");
1290 shellWindow = GetShellWindow();
1291 ok(shellWindow==hwnd1, "wrong shell window: %p\n", shellWindow);
1292
1293 ret = SetShellWindow(hwnd1);
1294 ok(!ret, "second call to SetShellWindow(hwnd1)\n");
1295
1296 ret = SetShellWindow(0);
1297 error = GetLastError();
1298 /* passes on Win XP, but not on Win98
1299 ok(!ret, "reset shell window by SetShellWindow(0)\n");
1300 ok(error==ERROR_INVALID_WINDOW_HANDLE, "ERROR_INVALID_WINDOW_HANDLE after SetShellWindow(0)\n"); */
1301
1302 ret = SetShellWindow(hwnd1);
1303 /* passes on Win XP, but not on Win98
1304 ok(!ret, "third call to SetShellWindow(hwnd1)\n"); */
1305
1307 ret = (GetWindowLongA(hwnd1,GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
1308 ok(!ret, "SetWindowExStyle(hwnd1, WS_EX_TOPMOST)\n");
1309
1310 ret = DestroyWindow(hwnd1);
1311 ok(ret, "DestroyWindow(hwnd1)\n");
1312
1313 hwnd2 = CreateWindowExA(WS_EX_TOPMOST, "#32770", "TEST2", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 150, 250, 300, 200, 0, 0, hinst, 0);
1314 trace("created window 2: %p\n", hwnd2);
1315 ret = SetShellWindow(hwnd2);
1316 ok(!ret, "SetShellWindow(hwnd2) with WS_EX_TOPMOST\n");
1317
1318 hwnd3 = CreateWindowExA(0, "#32770", "TEST3", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 200, 400, 300, 200, 0, 0, hinst, 0);
1319 trace("created window 3: %p\n", hwnd3);
1320
1321 hwnd4 = CreateWindowExA(0, "#32770", "TEST4", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 250, 500, 300, 200, 0, 0, hinst, 0);
1322 trace("created window 4: %p\n", hwnd4);
1323
1324 nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1325 ok(nextWnd==hwnd3, "wrong next window for hwnd4: %p - expected hwnd3\n", nextWnd);
1326
1327 ret = SetShellWindow(hwnd4);
1328 ok(ret, "SetShellWindow(hwnd4)\n");
1329 shellWindow = GetShellWindow();
1330 ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4\n", shellWindow);
1331
1332 nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1333 ok(nextWnd==0, "wrong next window for hwnd4: %p - expected 0\n", nextWnd);
1334
1335 ret = SetWindowPos(hwnd4, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1336 ok(ret, "SetWindowPos(hwnd4, HWND_TOPMOST)\n");
1337
1338 ret = SetWindowPos(hwnd4, hwnd3, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1339 ok(ret, "SetWindowPos(hwnd4, hwnd3\n");
1340
1341 ret = SetShellWindow(hwnd3);
1342 ok(!ret, "SetShellWindow(hwnd3)\n");
1343 shellWindow = GetShellWindow();
1344 ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4\n", shellWindow);
1345
1346 hwnd5 = CreateWindowExA(0, "#32770", "TEST5", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 300, 600, 300, 200, 0, 0, hinst, 0);
1347 trace("created window 5: %p\n", hwnd5);
1348 ret = SetWindowPos(hwnd4, hwnd5, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
1349 ok(ret, "SetWindowPos(hwnd4, hwnd5)\n");
1350
1351 todo_wine
1352 {
1353 nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
1354 ok(nextWnd==0, "wrong next window for hwnd4 after SetWindowPos(): %p - expected 0\n", nextWnd);
1355 }
1356
1357 /* destroy test windows */
1358 DestroyWindow(hwnd2);
1359 DestroyWindow(hwnd3);
1360 DestroyWindow(hwnd4);
1361 DestroyWindow(hwnd5);
1362}
1363
1364/************** MDI test ****************/
1365
1366static char mdi_lParam_test_message[] = "just a test string";
1367
1369{
1370 MDICREATESTRUCTA mdi_cs;
1371 HWND mdi_child, hwnd, exp_hwnd;
1372 INT_PTR id;
1373 static const WCHAR classW[] = {'M','D','I','_','c','h','i','l','d','_','C','l','a','s','s','_','1',0};
1374 static const WCHAR titleW[] = {'M','D','I',' ','c','h','i','l','d',0};
1375 BOOL isWin9x = FALSE;
1376 HMENU frame_menu = GetMenu(parent);
1377
1378 ok(frame_menu != NULL, "Frame window didn't have a menu\n");
1379
1380 mdi_cs.szClass = "MDI_child_Class_1";
1381 mdi_cs.szTitle = "MDI child";
1382 mdi_cs.hOwner = GetModuleHandleA(NULL);
1383 mdi_cs.x = CW_USEDEFAULT;
1384 mdi_cs.y = CW_USEDEFAULT;
1385 mdi_cs.cx = CW_USEDEFAULT;
1386 mdi_cs.cy = CW_USEDEFAULT;
1387 mdi_cs.style = 0;
1389 mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1390 ok(mdi_child != 0, "MDI child creation failed\n");
1391 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1392 ok(id == first_id, "wrong child id %ld\n", id);
1394 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1395 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1397 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1398
1399 mdi_cs.style = 0x7fffffff; /* without WS_POPUP */
1400 mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1401 ok(mdi_child != 0, "MDI child creation failed\n");
1402 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1403 ok(id == first_id, "wrong child id %ld\n", id);
1405 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1407 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1408
1409 mdi_cs.style = 0xffffffff; /* with WS_POPUP */
1410 mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1412 {
1413 ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1414 }
1415 else
1416 {
1417 ok(mdi_child != 0, "MDI child creation failed\n");
1418 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1419 ok(id == first_id, "wrong child id %ld\n", id);
1421 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1422 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1424 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1425 }
1426
1427 /* test MDICREATESTRUCT A<->W mapping */
1428 /* MDICREATESTRUCTA and MDICREATESTRUCTW have the same layout */
1429 mdi_cs.style = 0;
1430 mdi_cs.szClass = (LPCSTR)classW;
1431 mdi_cs.szTitle = (LPCSTR)titleW;
1432 SetLastError(0xdeadbeef);
1433 mdi_child = (HWND)SendMessageW(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
1434 if (!mdi_child)
1435 {
1437 isWin9x = TRUE;
1438 else
1439 ok(mdi_child != 0, "MDI child creation failed\n");
1440 }
1441 else
1442 {
1443 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1444 ok(id == first_id, "wrong child id %ld\n", id);
1446 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1447 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1448 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1450 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1451 }
1452
1453 mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1454 0,
1459 ok(mdi_child != 0, "MDI child creation failed\n");
1460 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1461 ok(id == first_id, "wrong child id %ld\n", id);
1463 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1464 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1465 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1467 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1468
1469 mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1470 0x7fffffff, /* without WS_POPUP */
1475 ok(mdi_child != 0, "MDI child creation failed\n");
1476 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1477 ok(id == first_id, "wrong child id %ld\n", id);
1479 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1480 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1482 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1483
1484 mdi_child = CreateMDIWindowA("MDI_child_Class_1", "MDI child",
1485 0xffffffff, /* with WS_POPUP */
1491 {
1492 ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1493 }
1494 else
1495 {
1496 ok(mdi_child != 0, "MDI child creation failed\n");
1497 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1498 ok(id == first_id, "wrong child id %ld\n", id);
1500 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1501 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1503 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1504 }
1505
1506 /* test MDICREATESTRUCT A<->W mapping */
1507 SetLastError(0xdeadbeef);
1508 mdi_child = CreateMDIWindowW(classW, titleW,
1509 0,
1514 if (!mdi_child)
1515 {
1517 isWin9x = TRUE;
1518 else
1519 ok(mdi_child != 0, "MDI child creation failed\n");
1520 }
1521 else
1522 {
1523 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1524 ok(id == first_id, "wrong child id %ld\n", id);
1526 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1527 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1528 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1530 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1531 }
1532
1533 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1534 0,
1539 ok(mdi_child != 0, "MDI child creation failed\n");
1540 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1541 ok(id == first_id, "wrong child id %ld\n", id);
1543 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1544 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1545 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1547 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1548
1549 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1555 ok(mdi_child != 0, "MDI child creation failed\n");
1556 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1557 ok(id == first_id, "wrong child id %ld\n", id);
1559 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1560 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1562 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1563 else
1564 ok(GetMenuItemCount(frame_menu) == 4, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1566 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1567
1568 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1569 0x7fffffff, /* without WS_POPUP */
1574 ok(mdi_child != 0, "MDI child creation failed\n");
1575 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1576 ok(id == first_id, "wrong child id %ld\n", id);
1578 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1579 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1581 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1582
1583 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
1584 0xffffffff, /* with WS_POPUP */
1590 {
1591 ok(!mdi_child, "MDI child with WS_POPUP and with MDIS_ALLCHILDSTYLES should fail\n");
1592 }
1593 else
1594 {
1595 ok(mdi_child != 0, "MDI child creation failed\n");
1596 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1597 ok(id == first_id, "wrong child id %ld\n", id);
1599 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1600 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1602 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1603 }
1604
1605 /* test MDICREATESTRUCT A<->W mapping */
1606 SetLastError(0xdeadbeef);
1608 0,
1613 if (!mdi_child)
1614 {
1616 isWin9x = TRUE;
1617 else
1618 ok(mdi_child != 0, "MDI child creation failed\n");
1619 }
1620 else
1621 {
1622 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1623 ok(id == first_id, "wrong child id %ld\n", id);
1625 exp_hwnd = (GetWindowLongW(mdi_child, GWL_STYLE) & WS_VISIBLE) ? mdi_child : 0;
1626 ok(hwnd == exp_hwnd, "WM_MDIGETACTIVE should return %p, got %p\n", exp_hwnd, hwnd);
1627 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1629 ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
1630 }
1631
1632 /* This test fails on Win9x */
1633 if (!isWin9x)
1634 {
1635 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_2", "MDI child",
1636 WS_CHILD,
1641 ok(!mdi_child, "WS_EX_MDICHILD with a not MDIClient parent should fail\n");
1642 }
1643
1644 mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1645 WS_CHILD, /* without WS_POPUP */
1650 ok(mdi_child != 0, "MDI child creation failed\n");
1651 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1652 ok(id == 0, "wrong child id %ld\n", id);
1653 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1655 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1656 DestroyWindow(mdi_child);
1657
1658 mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1659 WS_CHILD | WS_POPUP, /* with WS_POPUP */
1664 ok(mdi_child != 0, "MDI child creation failed\n");
1665 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1666 ok(id == 0, "wrong child id %ld\n", id);
1668 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1669 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1670 DestroyWindow(mdi_child);
1671
1672 /* maximized child */
1673 mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1679 ok(mdi_child != 0, "MDI child creation failed\n");
1680 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1681 ok(id == 0, "wrong child id %ld\n", id);
1683 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1684 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1685 DestroyWindow(mdi_child);
1686
1687 trace("Creating maximized child with a caption\n");
1688 mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1694 ok(mdi_child != 0, "MDI child creation failed\n");
1695 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1696 ok(id == 0, "wrong child id %ld\n", id);
1698 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1699 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1700 DestroyWindow(mdi_child);
1701
1702 trace("Creating maximized child with a caption and a thick frame\n");
1703 mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
1709 ok(mdi_child != 0, "MDI child creation failed\n");
1710 id = GetWindowLongPtrA(mdi_child, GWLP_ID);
1711 ok(id == 0, "wrong child id %ld\n", id);
1713 ok(!hwnd, "WM_MDIGETACTIVE should return 0, got %p\n", hwnd);
1714 ok(GetMenuItemCount(frame_menu) == 0, "Got wrong frame menu item count: %u\n", GetMenuItemCount(frame_menu));
1715 DestroyWindow(mdi_child);
1716}
1717
1719{
1720 HWND child_1, child_2, child_3, child_4;
1721 HWND stack[4];
1723
1724 cs.szClass = "MDI_child_Class_1";
1725 cs.szTitle = "MDI child";
1726 cs.hOwner = GetModuleHandleA(0);
1727 cs.x = CW_USEDEFAULT;
1728 cs.y = CW_USEDEFAULT;
1729 cs.cx = CW_USEDEFAULT;
1730 cs.cy = CW_USEDEFAULT;
1731 cs.style = 0;
1733
1734 child_1 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1735 ok(child_1 != 0, "expected child_1 to be non NULL\n");
1736 child_2 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1737 ok(child_2 != 0, "expected child_2 to be non NULL\n");
1738 child_3 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1739 ok(child_3 != 0, "expected child_3 to be non NULL\n");
1740 child_4 = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&cs);
1741 ok(child_4 != 0, "expected child_4 to be non NULL\n");
1742
1744 stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1745 stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1746 stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1747 trace("Initial MDI child stack: %p->%p->%p->%p\n", stack[0], stack[1], stack[2], stack[3]);
1748 ok(stack[0] == child_4 && stack[1] == child_3 &&
1749 stack[2] == child_2 && stack[3] == child_1,
1750 "Unexpected initial order, should be: %p->%p->%p->%p\n",
1751 child_4, child_3, child_2, child_1);
1752
1753 trace("Activate child next to %p\n", child_3);
1755
1757 stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1758 stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1759 stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1760 ok(stack[0] == child_2 && stack[1] == child_4 &&
1761 stack[2] == child_1 && stack[3] == child_3,
1762 "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n",
1763 child_2, child_4, child_1, child_3, stack[0], stack[1], stack[2], stack[3]);
1764
1765 trace("Activate child previous to %p\n", child_1);
1767
1769 stack[1] = GetWindow(stack[0], GW_HWNDNEXT);
1770 stack[2] = GetWindow(stack[1], GW_HWNDNEXT);
1771 stack[3] = GetWindow(stack[2], GW_HWNDNEXT);
1772 ok(stack[0] == child_4 && stack[1] == child_2 &&
1773 stack[2] == child_1 && stack[3] == child_3,
1774 "Broken MDI child stack:\nexpected: %p->%p->%p->%p, but got: %p->%p->%p->%p\n",
1775 child_4, child_2, child_1, child_3, stack[0], stack[1], stack[2], stack[3]);
1776
1777 DestroyWindow(child_1);
1778 DestroyWindow(child_2);
1779 DestroyWindow(child_3);
1780 DestroyWindow(child_4);
1781}
1782
1783/**********************************************************************
1784 * MDI_ChildGetMinMaxInfo (copied from windows/mdi.c)
1785 *
1786 * Note: The rule here is that client rect of the maximized MDI child
1787 * is equal to the client rect of the MDI client window.
1788 */
1790{
1791 RECT rect;
1792
1796
1797 rect.right -= rect.left;
1798 rect.bottom -= rect.top;
1799 lpMinMax->ptMaxSize.x = rect.right;
1800 lpMinMax->ptMaxSize.y = rect.bottom;
1801
1802 lpMinMax->ptMaxPosition.x = rect.left;
1803 lpMinMax->ptMaxPosition.y = rect.top;
1804
1805 trace("max rect %s\n", wine_dbgstr_rect(&rect));
1806}
1807
1809{
1810 switch (msg)
1811 {
1812 case WM_NCCREATE:
1813 case WM_CREATE:
1814 {
1816 MDICREATESTRUCTA *mdi_cs = cs->lpCreateParams;
1817
1818 ok(cs->dwExStyle & WS_EX_MDICHILD, "WS_EX_MDICHILD should be set\n");
1819 ok(mdi_cs->lParam == (LPARAM)mdi_lParam_test_message, "wrong mdi_cs->lParam\n");
1820
1821 ok(!lstrcmpA(cs->lpszClass, "MDI_child_Class_1"), "wrong class name\n");
1822 ok(!lstrcmpA(cs->lpszClass, mdi_cs->szClass), "class name does not match\n");
1823 ok(!lstrcmpA(cs->lpszName, "MDI child"), "wrong title\n");
1824 ok(!lstrcmpA(cs->lpszName, mdi_cs->szTitle), "title does not match\n");
1825 ok(cs->hInstance == mdi_cs->hOwner, "%p != %p\n", cs->hInstance, mdi_cs->hOwner);
1826
1827 /* MDICREATESTRUCT should have original values */
1828 ok(mdi_cs->style == 0 || mdi_cs->style == 0x7fffffff || mdi_cs->style == 0xffffffff || mdi_cs->style == WS_MAXIMIZE,
1829 "mdi_cs->style does not match (%08x)\n", mdi_cs->style);
1830 ok(mdi_cs->x == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->x);
1831 ok(mdi_cs->y == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->y);
1832 ok(mdi_cs->cx == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->cx);
1833 ok(mdi_cs->cy == CW_USEDEFAULT, "%d != CW_USEDEFAULT\n", mdi_cs->cy);
1834
1835 /* CREATESTRUCT should have fixed values */
1836 ok(cs->x != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->x);
1837 ok(cs->y != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->y);
1838
1839 /* cx/cy == CW_USEDEFAULT are translated to NOT zero values */
1840 ok(cs->cx != CW_USEDEFAULT && cs->cx != 0, "%d == CW_USEDEFAULT\n", cs->cx);
1841 ok(cs->cy != CW_USEDEFAULT && cs->cy != 0, "%d == CW_USEDEFAULT\n", cs->cy);
1842
1843 ok(!(cs->style & WS_POPUP), "WS_POPUP is not allowed\n");
1844
1845 if (GetWindowLongA(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
1846 {
1847 LONG style = mdi_cs->style | WS_CHILD | WS_CLIPSIBLINGS;
1848 ok(cs->style == style,
1849 "cs->style does not match (%08x)\n", cs->style);
1850 }
1851 else
1852 {
1853 LONG style = mdi_cs->style;
1854 style &= ~WS_POPUP;
1857 ok(cs->style == style,
1858 "cs->style does not match (%08x)\n", cs->style);
1859 }
1860 break;
1861 }
1862
1863 case WM_GETMINMAXINFO:
1864 {
1866 RECT rc;
1867 MINMAXINFO *minmax = (MINMAXINFO *)lparam;
1868 MINMAXINFO my_minmax;
1869 LONG style, exstyle;
1870
1872 exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1873
1874 GetClientRect(client, &rc);
1875
1876 GetClientRect(client, &rc);
1877 if ((style & WS_CAPTION) == WS_CAPTION)
1878 style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1879 AdjustWindowRectEx(&rc, style, 0, exstyle);
1880 trace("MDI child: calculated max window size = (%d x %d)\n", rc.right-rc.left, rc.bottom-rc.top);
1881 dump_minmax_info( minmax );
1882
1883 ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %d != %d\n",
1884 minmax->ptMaxSize.x, rc.right - rc.left);
1885 ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %d != %d\n",
1886 minmax->ptMaxSize.y, rc.bottom - rc.top);
1887
1889
1890 trace("DefMDIChildProc returned:\n");
1891 dump_minmax_info( minmax );
1892
1893 MDI_ChildGetMinMaxInfo(client, hwnd, &my_minmax);
1894 ok(minmax->ptMaxSize.x == my_minmax.ptMaxSize.x, "default width of maximized child %d != %d\n",
1895 minmax->ptMaxSize.x, my_minmax.ptMaxSize.x);
1896 ok(minmax->ptMaxSize.y == my_minmax.ptMaxSize.y, "default height of maximized child %d != %d\n",
1897 minmax->ptMaxSize.y, my_minmax.ptMaxSize.y);
1898
1899 return 1;
1900 }
1901
1902 case WM_MDIACTIVATE:
1903 {
1904 HWND active, client = GetParent(hwnd);
1905 /*trace("%p WM_MDIACTIVATE %08x %08lx\n", hwnd, wparam, lparam);*/
1906 active = (HWND)SendMessageA(client, WM_MDIGETACTIVE, 0, 0);
1907 if (hwnd == (HWND)lparam) /* if we are being activated */
1908 ok (active == (HWND)lparam, "new active %p != active %p\n", (HWND)lparam, active);
1909 else
1910 ok (active == (HWND)wparam, "old active %p != active %p\n", (HWND)wparam, active);
1911 break;
1912 }
1913 }
1915}
1916
1918{
1919 switch (msg)
1920 {
1921 case WM_NCCREATE:
1922 case WM_CREATE:
1923 {
1925
1926 trace("%s: x %d, y %d, cx %d, cy %d\n", (msg == WM_NCCREATE) ? "WM_NCCREATE" : "WM_CREATE",
1927 cs->x, cs->y, cs->cx, cs->cy);
1928
1929 ok(!(cs->dwExStyle & WS_EX_MDICHILD), "WS_EX_MDICHILD should not be set\n");
1930 ok(cs->lpCreateParams == mdi_lParam_test_message, "wrong cs->lpCreateParams\n");
1931
1932 ok(!lstrcmpA(cs->lpszClass, "MDI_child_Class_2"), "wrong class name\n");
1933 ok(!lstrcmpA(cs->lpszName, "MDI child"), "wrong title\n");
1934
1935 /* CREATESTRUCT should have fixed values */
1936 /* For some reason Win9x doesn't translate cs->x from CW_USEDEFAULT,
1937 while NT does. */
1938 /*ok(cs->x != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->x);*/
1939 ok(cs->y != CW_USEDEFAULT, "%d == CW_USEDEFAULT\n", cs->y);
1940
1941 /* cx/cy == CW_USEDEFAULT are translated to 0 */
1942 /* For some reason Win98 doesn't translate cs->cx from CW_USEDEFAULT,
1943 while Win95, Win2k, WinXP do. */
1944 /*ok(cs->cx == 0, "%d != 0\n", cs->cx);*/
1945 ok(cs->cy == 0, "%d != 0\n", cs->cy);
1946 break;
1947 }
1948
1949 case WM_GETMINMAXINFO:
1950 {
1952 RECT rc;
1953 MINMAXINFO *minmax = (MINMAXINFO *)lparam;
1954 LONG style, exstyle;
1955
1957 exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
1958
1959 GetClientRect(parent, &rc);
1960 trace("WM_GETMINMAXINFO: parent %p client size = (%d x %d)\n", parent, rc.right, rc.bottom);
1961
1962 GetClientRect(parent, &rc);
1963 if ((style & WS_CAPTION) == WS_CAPTION)
1964 style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
1965 AdjustWindowRectEx(&rc, style, 0, exstyle);
1966 dump_minmax_info( minmax );
1967
1968 ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %d != %d\n",
1969 minmax->ptMaxSize.x, rc.right - rc.left);
1970 ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %d != %d\n",
1971 minmax->ptMaxSize.y, rc.bottom - rc.top);
1972 break;
1973 }
1974
1976 {
1977 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
1978 RECT rc1, rc2;
1979
1980 GetWindowRect(hwnd, &rc1);
1981 SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
1982 /* note: winpos coordinates are relative to parent */
1984 ok(EqualRect(&rc1, &rc2), "rects do not match, window=%s pos=%s\n",
1986 GetWindowRect(hwnd, &rc1);
1989 MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
1990 ok(EqualRect(&rc1, &rc2), "rects do not match, window=%s client=%s\n",
1992 }
1993 /* fall through */
1995 {
1996 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
1997 WINDOWPOS my_winpos = *winpos;
1998
1999 trace("%s: %p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2000 (msg == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED",
2001 winpos->hwnd, winpos->hwndInsertAfter,
2002 winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2003
2005
2006 ok(!memcmp(&my_winpos, winpos, sizeof(WINDOWPOS)),
2007 "DefWindowProc should not change WINDOWPOS: %p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2008 winpos->hwnd, winpos->hwndInsertAfter,
2009 winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2010
2011 return 1;
2012 }
2013 }
2014 return DefWindowProcA(hwnd, msg, wparam, lparam);
2015}
2016
2018{
2019 static HWND mdi_client;
2020
2021 switch (msg)
2022 {
2023 case WM_CREATE:
2024 return 1;
2025
2027 {
2028 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
2029 RECT rc1, rc2;
2030
2031 GetWindowRect(hwnd, &rc1);
2032 trace("window: %s\n", wine_dbgstr_rect(&rc1));
2033 SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
2034 /* note: winpos coordinates are relative to parent */
2036 trace("pos: %s\n", wine_dbgstr_rect(&rc2));
2037 ok(EqualRect(&rc1, &rc2), "rects do not match\n");
2038
2039 GetWindowRect(hwnd, &rc1);
2042 MapWindowPoints(0, hwnd, (LPPOINT)&rc1, 2);
2043 ok(EqualRect(&rc1, &rc2), "rects do not match\n");
2044 }
2045 /* fall through */
2047 {
2048 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
2049 WINDOWPOS my_winpos = *winpos;
2050
2051 trace("%s\n", (msg == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2052 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2053 winpos->hwnd, winpos->hwndInsertAfter,
2054 winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2055
2057
2058 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2059 winpos->hwnd, winpos->hwndInsertAfter,
2060 winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
2061
2062 ok(!memcmp(&my_winpos, winpos, sizeof(WINDOWPOS)),
2063 "DefWindowProc should not change WINDOWPOS values\n");
2064
2065 return 1;
2066 }
2067
2068 case WM_CLOSE:
2069 PostQuitMessage(0);
2070 break;
2071 }
2073}
2074
2076{
2077 WNDCLASSA cls;
2078
2079 cls.style = 0;
2081 cls.cbClsExtra = 0;
2082 cls.cbWndExtra = 0;
2083 cls.hInstance = GetModuleHandleA(0);
2084 cls.hIcon = 0;
2087 cls.lpszMenuName = NULL;
2088 cls.lpszClassName = "MDI_parent_Class";
2089 if(!RegisterClassA(&cls)) return FALSE;
2090
2092 cls.lpszClassName = "MDI_child_Class_1";
2093 if(!RegisterClassA(&cls)) return FALSE;
2094
2096 cls.lpszClassName = "MDI_child_Class_2";
2097 if(!RegisterClassA(&cls)) return FALSE;
2098
2099 return TRUE;
2100}
2101
2102static void test_mdi(void)
2103{
2104 static const DWORD style[] = { 0, WS_HSCROLL, WS_VSCROLL, WS_HSCROLL | WS_VSCROLL };
2105 HWND mdi_hwndMain, mdi_client, mdi_child;
2106 CLIENTCREATESTRUCT client_cs;
2107 RECT rc;
2108 DWORD i;
2109 MSG msg;
2110 HMENU frame_menu, child_menu;
2111
2113
2114 mdi_hwndMain = CreateWindowExA(0, "MDI_parent_Class", "MDI parent window",
2116 WS_MAXIMIZEBOX /*| WS_VISIBLE*/,
2117 100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
2118 GetDesktopWindow(), 0,
2120 assert(mdi_hwndMain);
2121
2122 frame_menu = CreateMenu();
2123
2124 GetClientRect(mdi_hwndMain, &rc);
2125
2126 client_cs.hWindowMenu = 0;
2127 client_cs.idFirstChild = 1;
2128
2129 for (i = 0; i < sizeof(style)/sizeof(style[0]); i++)
2130 {
2131 SCROLLINFO si;
2132 BOOL ret, gotit;
2133
2134 mdi_client = CreateWindowExA(0, "mdiclient", NULL,
2135 WS_CHILD | style[i],
2136 0, 0, rc.right, rc.bottom,
2137 mdi_hwndMain, 0, 0, &client_cs);
2138 ok(mdi_client != 0, "MDI client creation failed\n");
2139
2140 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
2141 0,
2144 mdi_client, 0, 0,
2146 ok(mdi_child != 0, "MDI child creation failed\n");
2147
2148 SendMessageW(mdi_child, WM_SIZE, SIZE_MAXIMIZED, 0);
2149 SetMenu(mdi_hwndMain, frame_menu);
2150
2151 ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child maximize, but has %u\n",
2152 GetMenuItemCount(frame_menu));
2153
2154 child_menu = CreateMenu();
2155 SendMessageW(mdi_client, WM_MDISETMENU, 0, (LPARAM)child_menu);
2156
2157 ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after WM_MDISETMENU, but has %u\n",
2158 GetMenuItemCount(frame_menu));
2159
2160 SendMessageW(mdi_child, WM_SIZE, SIZE_RESTORED, 0);
2161
2162 ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child restored, but has %u items\n",
2163 GetMenuItemCount(frame_menu));
2164
2165 SetMenu(mdi_hwndMain, NULL);
2166
2167 si.cbSize = sizeof(si);
2168 si.fMask = SIF_ALL;
2170 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2171 {
2172 ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2173 ok(si.nPage == 0, "expected 0\n");
2174 ok(si.nPos == 0, "expected 0\n");
2175 ok(si.nTrackPos == 0, "expected 0\n");
2176 ok(si.nMin == 0, "expected 0\n");
2177 ok(si.nMax == 100, "expected 100\n");
2178 }
2179 else
2180 ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2181
2183 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2184 {
2185 ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2186 ok(si.nPage == 0, "expected 0\n");
2187 ok(si.nPos == 0, "expected 0\n");
2188 ok(si.nTrackPos == 0, "expected 0\n");
2189 ok(si.nMin == 0, "expected 0\n");
2190 ok(si.nMax == 100, "expected 100\n");
2191 }
2192 else
2193 ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2194
2195 SetWindowPos(mdi_child, 0, -100, -100, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
2196
2197 si.cbSize = sizeof(si);
2198 si.fMask = SIF_ALL;
2200 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2201 {
2202 ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2203 ok(si.nPage == 0, "expected 0\n");
2204 ok(si.nPos == 0, "expected 0\n");
2205 ok(si.nTrackPos == 0, "expected 0\n");
2206 ok(si.nMin == 0, "expected 0\n");
2207 ok(si.nMax == 100, "expected 100\n");
2208 }
2209 else
2210 ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2211
2213 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2214 {
2215 ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2216 ok(si.nPage == 0, "expected 0\n");
2217 ok(si.nPos == 0, "expected 0\n");
2218 ok(si.nTrackPos == 0, "expected 0\n");
2219 ok(si.nMin == 0, "expected 0\n");
2220 ok(si.nMax == 100, "expected 100\n");
2221 }
2222 else
2223 ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2224
2225 gotit = FALSE;
2226 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2227 {
2228 if (msg.message == WM_MOUSEMOVE || msg.message == WM_PAINT)
2229 {
2231 continue;
2232 }
2233
2234 if (msg.message == 0x003f) /* WM_MDICALCCHILDSCROLL ??? */
2235 {
2236 ok(msg.hwnd == mdi_client, "message 0x003f should be posted to mdiclient\n");
2237 gotit = TRUE;
2238 }
2239 else
2240 ok(msg.hwnd != mdi_client, "message %04x should not be posted to mdiclient\n", msg.message);
2242 }
2243 ok(gotit, "message 0x003f should appear after SetWindowPos\n");
2244
2245 si.cbSize = sizeof(si);
2246 si.fMask = SIF_ALL;
2248 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2249 {
2250 ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
2252 ok(si.nPage != 0, "expected !0\n");
2253 ok(si.nPos == 0, "expected 0\n");
2254 ok(si.nTrackPos == 0, "expected 0\n");
2255 ok(si.nMin != 0, "expected !0\n");
2256 ok(si.nMax != 100, "expected !100\n");
2257 }
2258 else
2259 ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
2260
2262 if (style[i] & (WS_HSCROLL | WS_VSCROLL))
2263 {
2264 ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
2266 ok(si.nPage != 0, "expected !0\n");
2267 ok(si.nPos == 0, "expected 0\n");
2268 ok(si.nTrackPos == 0, "expected 0\n");
2269 ok(si.nMin != 0, "expected !0\n");
2270 ok(si.nMax != 100, "expected !100\n");
2271 }
2272 else
2273 ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
2274
2275 DestroyMenu(child_menu);
2276 DestroyWindow(mdi_child);
2278 }
2279
2280 SetMenu(mdi_hwndMain, frame_menu);
2281
2282 mdi_client = CreateWindowExA(0, "mdiclient", NULL,
2283 WS_CHILD,
2284 0, 0, rc.right, rc.bottom,
2285 mdi_hwndMain, 0, 0, &client_cs);
2286 ok(mdi_client != 0, "MDI client creation failed\n");
2287
2288 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
2289 0,
2292 mdi_client, 0, 0,
2294 ok(mdi_child != 0, "MDI child creation failed\n");
2295
2296 SendMessageW(mdi_child, WM_SIZE, SIZE_MAXIMIZED, 0);
2297 ok(GetMenuItemCount(frame_menu) == 4, "Frame menu should have 4 items after child maximize, but has %u\n",
2298 GetMenuItemCount(frame_menu));
2299
2300 child_menu = CreateMenu();
2301 SendMessageW(mdi_client, WM_MDISETMENU, 0, (LPARAM)child_menu);
2302
2303 ok(GetMenuItemCount(frame_menu) == 4, "Frame menu should have 4 items after WM_MDISETMENU, but has %u\n",
2304 GetMenuItemCount(frame_menu));
2305
2306 SendMessageW(mdi_child, WM_SIZE, SIZE_RESTORED, 0);
2307
2308 ok(GetMenuItemCount(frame_menu) == 0, "Frame menu should be empty after child restored, but has %u items\n",
2309 GetMenuItemCount(frame_menu));
2310
2311 DestroyMenu(child_menu);
2312 DestroyWindow(mdi_child);
2314
2315 /* MDIClient without MDIS_ALLCHILDSTYLES */
2316 mdi_client = CreateWindowExA(0, "mdiclient",
2317 NULL,
2318 WS_CHILD /*| WS_VISIBLE*/,
2319 /* tests depend on a not zero MDIClient size */
2320 0, 0, rc.right, rc.bottom,
2321 mdi_hwndMain, 0, GetModuleHandleA(NULL),
2322 &client_cs);
2324 test_MDI_create(mdi_hwndMain, mdi_client, client_cs.idFirstChild);
2326
2327 /* MDIClient with MDIS_ALLCHILDSTYLES */
2328 mdi_client = CreateWindowExA(0, "mdiclient",
2329 NULL,
2330 WS_CHILD | MDIS_ALLCHILDSTYLES /*| WS_VISIBLE*/,
2331 /* tests depend on a not zero MDIClient size */
2332 0, 0, rc.right, rc.bottom,
2333 mdi_hwndMain, 0, GetModuleHandleA(NULL),
2334 &client_cs);
2336 test_MDI_create(mdi_hwndMain, mdi_client, client_cs.idFirstChild);
2338
2339 /* Test child window stack management */
2340 mdi_client = CreateWindowExA(0, "mdiclient",
2341 NULL,
2342 WS_CHILD,
2343 0, 0, rc.right, rc.bottom,
2344 mdi_hwndMain, 0, GetModuleHandleA(NULL),
2345 &client_cs);
2349/*
2350 while(GetMessage(&msg, 0, 0, 0))
2351 {
2352 TranslateMessage(&msg);
2353 DispatchMessage(&msg);
2354 }
2355*/
2356 DestroyWindow(mdi_hwndMain);
2357}
2358
2359static void test_icons(void)
2360{
2361 WNDCLASSEXA cls;
2362 HWND hwnd;
2364 HICON icon2 = LoadIconA(0, (LPCSTR)IDI_QUESTION);
2367 HICON res;
2368
2369 cls.cbSize = sizeof(cls);
2370 cls.style = 0;
2372 cls.cbClsExtra = 0;
2373 cls.cbWndExtra = 0;
2374 cls.hInstance = 0;
2375 cls.hIcon = LoadIconA(0, (LPCSTR)IDI_HAND);
2376 cls.hIconSm = small_icon;
2379 cls.lpszMenuName = NULL;
2380 cls.lpszClassName = "IconWindowClass";
2381
2382 RegisterClassExA(&cls);
2383
2384 hwnd = CreateWindowExA(0, "IconWindowClass", "icon test", 0,
2385 100, 100, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL);
2386 assert( hwnd );
2387
2388 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2389 ok( res == 0, "wrong big icon %p/0\n", res );
2390 res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon );
2391 ok( res == 0, "wrong previous big icon %p/0\n", res );
2392 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2393 ok( res == icon, "wrong big icon after set %p/%p\n", res, icon );
2394 res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon2 );
2395 ok( res == icon, "wrong previous big icon %p/%p\n", res, icon );
2396 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2397 ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
2398
2399 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2400 ok( res == 0, "wrong small icon %p/0\n", res );
2401 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2402 ok( (res && res != small_icon && res != icon2) || broken(!res), "wrong small2 icon %p\n", res );
2403 res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)icon );
2404 ok( res == 0, "wrong previous small icon %p/0\n", res );
2405 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2406 ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );
2407 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2408 ok( res == icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, icon );
2409 res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)small_icon );
2410 ok( res == icon, "wrong previous small icon %p/%p\n", res, icon );
2411 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
2412 ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );
2413 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
2414 ok( res == small_icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, small_icon );
2415
2416 /* make sure the big icon hasn't changed */
2417 res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
2418 ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
2419
2421}
2422
2424{
2425 if (msg == WM_NCCALCSIZE)
2426 {
2427 RECT *rect = (RECT *)lparam;
2428 /* first time around increase the rectangle, next time decrease it */
2429 if (rect->left == 100) InflateRect( rect, 10, 10 );
2430 else InflateRect( rect, -10, -10 );
2431 return 0;
2432 }
2433 return DefWindowProcA( hwnd, msg, wparam, lparam );
2434}
2435
2436static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
2437{
2438 RECT orig_win_rc, rect;
2440 HWND hwnd_grandchild, hwnd_child, hwnd_child2;
2441 HWND hwnd_desktop;
2442 RECT rc1, rc2;
2443 BOOL ret;
2444
2445 SetRect(&rect, 111, 222, 333, 444);
2446 ok(!GetWindowRect(0, &rect), "GetWindowRect 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 SetRect(&rect, 111, 222, 333, 444);
2451 ok(!GetClientRect(0, &rect), "GetClientRect succeeded\n");
2452 ok(rect.left == 111 && rect.top == 222 && rect.right == 333 && rect.bottom == 444,
2453 "wrong window rect %s\n", wine_dbgstr_rect(&rect));
2454
2455 GetWindowRect(hwnd, &orig_win_rc);
2456
2458 ret = SetWindowPos(hwnd, 0, 100, 100, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
2459 ok(ret, "Got %d\n", ret);
2460 GetWindowRect( hwnd, &rect );
2461 ok( rect.left == 100 && rect.top == 100 && rect.right == 100 && rect.bottom == 100,
2462 "invalid window rect %s\n", wine_dbgstr_rect(&rect));
2463 GetClientRect( hwnd, &rect );
2464 MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
2465 ok( rect.left == 90 && rect.top == 90 && rect.right == 110 && rect.bottom == 110,
2466 "invalid client rect %s\n", wine_dbgstr_rect(&rect));
2467
2468 ret = SetWindowPos(hwnd, 0, 200, 200, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
2469 ok(ret, "Got %d\n", ret);
2470 GetWindowRect( hwnd, &rect );
2471 ok( rect.left == 200 && rect.top == 200 && rect.right == 200 && rect.bottom == 200,
2472 "invalid window rect %s\n", wine_dbgstr_rect(&rect));
2473 GetClientRect( hwnd, &rect );
2474 MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
2475 ok( rect.left == 210 && rect.top == 210 && rect.right == 190 && rect.bottom == 190,
2476 "invalid client rect %s\n", wine_dbgstr_rect(&rect));
2477
2478 ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
2479 orig_win_rc.right, orig_win_rc.bottom, 0);
2480 ok(ret, "Got %d\n", ret);
2482
2483 /* Win9x truncates coordinates to 16-bit irrespectively */
2484 if (!is_win9x)
2485 {
2486 ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
2487 ok(ret, "Got %d\n", ret);
2488 ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
2489 ok(ret, "Got %d\n", ret);
2490
2491 ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
2492 ok(ret, "Got %d\n", ret);
2493 ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
2494 ok(ret, "Got %d\n", ret);
2495 }
2496
2497 ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
2498 orig_win_rc.right, orig_win_rc.bottom, 0);
2499 ok(ret, "Got %d\n", ret);
2500
2501 ok(!(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
2503 ok(ret, "Got %d\n", ret);
2504 ok(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
2506 ok(ret, "Got %d\n", ret);
2507 ok(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
2509 ok(ret, "Got %d\n", ret);
2510 ok(!(GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
2511
2512 hwnd_desktop = GetDesktopWindow();
2513 ok(!!hwnd_desktop, "Failed to get hwnd_desktop window (%d).\n", GetLastError());
2515 ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2516 hwnd_grandchild = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd_child);
2517 ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2519 ok(!!hwnd_child2, "Failed to create second child window (%d)\n", GetLastError());
2520
2521 ret = SetWindowPos(hwnd, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2522 ok(ret, "Got %d\n", ret);
2524
2525 ret = SetWindowPos(hwnd2, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2526 ok(ret, "Got %d\n", ret);
2527 check_active_state(hwnd2, hwnd2, hwnd2);
2528
2529 /* Returns TRUE also for windows that are not siblings */
2530 ret = SetWindowPos(hwnd_child, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2531 ok(ret, "Got %d\n", ret);
2532 check_active_state(hwnd2, hwnd2, hwnd2);
2533
2534 ret = SetWindowPos(hwnd2, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2535 ok(ret, "Got %d\n", ret);
2536 check_active_state(hwnd2, hwnd2, hwnd2);
2537
2538 /* Does not seem to do anything even without passing flags, still returns TRUE */
2539 GetWindowRect(hwnd_child, &rc1);
2540 ret = SetWindowPos(hwnd_child, hwnd2 , 1, 2, 3, 4, 0);
2541 ok(ret, "Got %d\n", ret);
2542 GetWindowRect(hwnd_child, &rc2);
2543 ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2544 check_active_state(hwnd2, hwnd2, hwnd2);
2545
2546 /* Same thing the other way around. */
2547 GetWindowRect(hwnd2, &rc1);
2548 ret = SetWindowPos(hwnd2, hwnd_child, 1, 2, 3, 4, 0);
2549 ok(ret, "Got %d\n", ret);
2550 GetWindowRect(hwnd2, &rc2);
2551 ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2552 check_active_state(hwnd2, hwnd2, hwnd2);
2553
2554 /* .. and with these windows. */
2555 GetWindowRect(hwnd_grandchild, &rc1);
2556 ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, 0);
2557 ok(ret, "Got %d\n", ret);
2558 GetWindowRect(hwnd_grandchild, &rc2);
2559 ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2560 check_active_state(hwnd2, hwnd2, hwnd2);
2561
2562 /* Add SWP_NOZORDER and it will be properly resized. */
2563 GetWindowRect(hwnd_grandchild, &rc1);
2564 ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, SWP_NOZORDER);
2565 ok(ret, "Got %d\n", ret);
2566 GetWindowRect(hwnd_grandchild, &rc2);
2567 ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
2568 (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
2569 "(%d,%d)-(%d,%d) != %s\n", rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6,
2571 check_active_state(hwnd2, hwnd2, hwnd2);
2572
2573 /* Given a sibling window, the window is properly resized. */
2574 GetWindowRect(hwnd_child, &rc1);
2575 ret = SetWindowPos(hwnd_child, hwnd_child2, 1, 2, 3, 4, 0);
2576 ok(ret, "Got %d\n", ret);
2577 GetWindowRect(hwnd_child, &rc2);
2578 ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
2579 (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
2580 "(%d,%d)-(%d,%d) != %s\n", rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6,
2582 check_active_state(hwnd2, hwnd2, hwnd2);
2583
2584 /* Involving the desktop window changes things. */
2585 ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2586 ok(!ret, "Got %d\n", ret);
2587 check_active_state(hwnd2, hwnd2, hwnd2);
2588
2589 GetWindowRect(hwnd_child, &rc1);
2590 ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, 0);
2591 ok(!ret, "Got %d\n", ret);
2592 GetWindowRect(hwnd_child, &rc2);
2593 ok(EqualRect(&rc1, &rc2), "%s != %s\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2));
2594 check_active_state(hwnd2, hwnd2, hwnd2);
2595
2596 ret = SetWindowPos(hwnd_desktop, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2597 ok(!ret, "Got %d\n", ret);
2598 check_active_state(hwnd2, hwnd2, hwnd2);
2599
2600 ret = SetWindowPos(hwnd_desktop, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2601 ok(!ret, "Got %d\n", ret);
2602 check_active_state(hwnd2, hwnd2, hwnd2);
2603
2604 ret = SetWindowPos(hwnd, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
2605 ok(!ret, "Got %d\n", ret);
2606 check_active_state(hwnd2, hwnd2, hwnd2);
2607
2608 DestroyWindow(hwnd_grandchild);
2609 DestroyWindow(hwnd_child);
2610 DestroyWindow(hwnd_child2);
2611
2612 hwnd_child = create_tool_window(WS_CHILD|WS_POPUP|WS_SYSMENU, hwnd2);
2613 ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
2615 ok(ret, "Got %d\n", ret);
2616 flush_events( TRUE );
2617 todo_wine check_active_state(hwnd2, hwnd2, hwnd2);
2618 DestroyWindow(hwnd_child);
2619}
2620
2622{
2623 HWND child;
2624 HMENU hMenu, ret;
2625 BOOL retok;
2626 DWORD style;
2627
2628 hMenu = CreateMenu();
2629 assert(hMenu);
2630
2631 ok(SetMenu(parent, hMenu), "SetMenu on a top level window should not fail\n");
2632 if (0)
2633 {
2634 /* fails on (at least) Wine, NT4, XP SP2 */
2636 }
2637 ret = GetMenu(parent);
2638 ok(ret == hMenu, "unexpected menu id %p\n", ret);
2639 /* test whether we can destroy a menu assigned to a window */
2640 retok = DestroyMenu(hMenu);
2641 ok( retok, "DestroyMenu error %d\n", GetLastError());
2642 retok = IsMenu(hMenu);
2643 ok(!retok || broken(retok) /* nt4 */, "menu handle should be not valid after DestroyMenu\n");
2644 ret = GetMenu(parent);
2645 /* This test fails on Win9x */
2646 if (!is_win9x)
2647 ok(ret == hMenu, "unexpected menu id %p\n", ret);
2648 ok(SetMenu(parent, 0), "SetMenu(0) on a top level window should not fail\n");
2650
2651 hMenu = CreateMenu();
2652 assert(hMenu);
2653
2654 /* parent */
2655 ret = GetMenu(parent);
2656 ok(ret == 0, "unexpected menu id %p\n", ret);
2657
2658 ok(!SetMenu(parent, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
2660 ret = GetMenu(parent);
2661 ok(ret == 0, "unexpected menu id %p\n", ret);
2662
2663 ok(SetMenu(parent, hMenu), "SetMenu on a top level window should not fail\n");
2664 if (0)
2665 {
2666 /* fails on (at least) Wine, NT4, XP SP2 */
2668 }
2669 ret = GetMenu(parent);
2670 ok(ret == hMenu, "unexpected menu id %p\n", ret);
2671
2672 ok(SetMenu(parent, 0), "SetMenu(0) on a top level window should not fail\n");
2674 ret = GetMenu(parent);
2675 ok(ret == 0, "unexpected menu id %p\n", ret);
2676
2677 /* child */
2678 child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, parent, (HMENU)10, 0, NULL);
2679 assert(child);
2680
2681 ret = GetMenu(child);
2682 ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2683
2684 ok(!SetMenu(child, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
2686 ret = GetMenu(child);
2687 ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2688
2689 ok(!SetMenu(child, hMenu), "SetMenu on a child window should fail\n");
2691 ret = GetMenu(child);
2692 ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2693
2694 ok(!SetMenu(child, 0), "SetMenu(0) on a child window should fail\n");
2696 ret = GetMenu(child);
2697 ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
2698
2701 ok(SetMenu(child, hMenu), "SetMenu on a popup child window should not fail\n");
2702 ok(SetMenu(child, 0), "SetMenu on a popup child window should not fail\n");
2704
2706 ok(!SetMenu(child, hMenu), "SetMenu on an overlapped child window should fail\n");
2708
2710 DestroyMenu(hMenu);
2711}
2712
2713static void test_window_tree(HWND parent, const DWORD *style, const int *order, int total)
2714{
2715 HWND child[5], hwnd;
2716 INT_PTR i;
2717
2718 assert(total <= 5);
2719
2721 ok(!hwnd, "have to start without children to perform the test\n");
2722
2723 for (i = 0; i < total; i++)
2724 {
2725 if (style[i] & DS_CONTROL)
2726 {
2727 child[i] = CreateWindowExA(0, (LPCSTR)MAKEINTATOM(32770), "", style[i] & ~WS_VISIBLE,
2728 0,0,0,0, parent, (HMENU)i, 0, NULL);
2729 if (style[i] & WS_VISIBLE)
2731
2733 }
2734 else
2735 child[i] = CreateWindowExA(0, "static", "", style[i], 0,0,10,10,
2736 parent, (HMENU)i, 0, NULL);
2737 trace("child[%ld] = %p\n", i, child[i]);
2738 ok(child[i] != 0, "CreateWindowEx failed to create child window\n");
2739 }
2740
2742 ok(hwnd != 0, "GetWindow(GW_CHILD) failed\n");
2743 ok(hwnd == GetWindow(child[total - 1], GW_HWNDFIRST), "GW_HWNDFIRST is wrong\n");
2744 ok(child[order[total - 1]] == GetWindow(child[0], GW_HWNDLAST), "GW_HWNDLAST is wrong\n");
2745
2746 for (i = 0; i < total; i++)
2747 {
2748 trace("hwnd[%ld] = %p\n", i, hwnd);
2749 ok(child[order[i]] == hwnd, "Z order of child #%ld is wrong\n", i);
2750
2752 }
2753
2754 for (i = 0; i < total; i++)
2755 ok(DestroyWindow(child[i]), "DestroyWindow failed\n");
2756}
2757
2759{
2760 const DWORD simple_style[5] = { WS_CHILD, WS_CHILD, WS_CHILD, WS_CHILD,
2761 WS_CHILD };
2762 const int simple_order[5] = { 0, 1, 2, 3, 4 };
2763
2764 const DWORD complex_style[5] = { WS_CHILD, WS_CHILD | WS_MAXIMIZE,
2767 const int complex_order_1[1] = { 0 };
2768 const int complex_order_2[2] = { 1, 0 };
2769 const int complex_order_3[3] = { 1, 0, 2 };
2770 const int complex_order_4[4] = { 1, 0, 2, 3 };
2771 const int complex_order_5[5] = { 4, 1, 0, 2, 3 };
2772 const DWORD complex_style_6[3] = { WS_CHILD | WS_VISIBLE,
2774 WS_CHILD | WS_VISIBLE };
2775 const int complex_order_6[3] = { 0, 1, 2 };
2776
2777 /* simple WS_CHILD */
2778 test_window_tree(parent, simple_style, simple_order, 5);
2779
2780 /* complex children styles */
2781 test_window_tree(parent, complex_style, complex_order_1, 1);
2782 test_window_tree(parent, complex_style, complex_order_2, 2);
2783 test_window_tree(parent, complex_style, complex_order_3, 3);
2784 test_window_tree(parent, complex_style, complex_order_4, 4);
2785 test_window_tree(parent, complex_style, complex_order_5, 5);
2786
2787 /* another set of complex children styles */
2788 test_window_tree(parent, complex_style_6, complex_order_6, 3);
2789}
2790
2791#define check_z_order(hwnd, next, prev, owner, topmost) \
2792 check_z_order_debug((hwnd), (next), (prev), (owner), (topmost), \
2793 __FILE__, __LINE__)
2794
2795static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner,
2796 BOOL topmost, const char *file, int line)
2797{
2798 HWND test;
2799 DWORD ex_style;
2800
2802 /* skip foreign windows */
2803 while (test && test != next &&
2807 {
2808 /*trace("skipping next %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
2810 }
2811 ok_(file, line)(next == test, "%p: expected next %p, got %p\n", hwnd, next, test);
2812
2814 /* skip foreign windows */
2815 while (test && test != prev &&
2819 {
2820 /*trace("skipping prev %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
2822 }
2823 ok_(file, line)(prev == test, "%p: expected prev %p, got %p\n", hwnd, prev, test);
2824
2826 ok_(file, line)(owner == test, "%p: expected owner %p, got %p\n", hwnd, owner, test);
2827
2828 ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
2829 ok_(file, line)(!(ex_style & WS_EX_TOPMOST) == !topmost, "%p: expected %stopmost\n",
2830 hwnd, topmost ? "" : "NOT ");
2831}
2832
2833static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E, DWORD style)
2834{
2835 HWND hwnd_A, hwnd_B, hwnd_C, hwnd_F;
2836
2837 trace("hwnd_D %p, hwnd_E %p\n", hwnd_D, hwnd_E);
2838
2839 SetWindowPos(hwnd_E, hwnd_D, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
2840
2841 check_z_order(hwnd_D, hwnd_E, 0, 0, FALSE);
2842 check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2843
2844 hwnd_F = CreateWindowExA(0, "MainWindowClass", "Owner window",
2846 100, 100, 100, 100,
2847 0, 0, GetModuleHandleA(NULL), NULL);
2848 trace("hwnd_F %p\n", hwnd_F);
2849 check_z_order(hwnd_F, hwnd_D, 0, 0, FALSE);
2850
2851 SetWindowPos(hwnd_F, hwnd_E, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
2852 check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2853 check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2854 check_z_order(hwnd_D, hwnd_E, 0, 0, FALSE);
2855
2856 hwnd_C = CreateWindowExA(0, "MainWindowClass", NULL,
2857 style,
2858 100, 100, 100, 100,
2859 hwnd_F, 0, GetModuleHandleA(NULL), NULL);
2860 trace("hwnd_C %p\n", hwnd_C);
2861 check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2862 check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2863 check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2864 check_z_order(hwnd_C, hwnd_D, 0, hwnd_F, FALSE);
2865
2866 hwnd_B = CreateWindowExA(WS_EX_TOPMOST, "MainWindowClass", NULL,
2867 style,
2868 100, 100, 100, 100,
2869 hwnd_F, 0, GetModuleHandleA(NULL), NULL);
2870 trace("hwnd_B %p\n", hwnd_B);
2871 check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2872 check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2873 check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2874 check_z_order(hwnd_C, hwnd_D, hwnd_B, hwnd_F, FALSE);
2875 check_z_order(hwnd_B, hwnd_C, 0, hwnd_F, TRUE);
2876
2877 hwnd_A = CreateWindowExA(WS_EX_TOPMOST, "MainWindowClass", NULL,
2878 style,
2879 100, 100, 100, 100,
2880 0, 0, GetModuleHandleA(NULL), NULL);
2881 trace("hwnd_A %p\n", hwnd_A);
2882 check_z_order(hwnd_F, 0, hwnd_E, 0, FALSE);
2883 check_z_order(hwnd_E, hwnd_F, hwnd_D, 0, FALSE);
2884 check_z_order(hwnd_D, hwnd_E, hwnd_C, 0, FALSE);
2885 check_z_order(hwnd_C, hwnd_D, hwnd_B, hwnd_F, FALSE);
2886 check_z_order(hwnd_B, hwnd_C, hwnd_A, hwnd_F, TRUE);
2887 check_z_order(hwnd_A, hwnd_B, 0, 0, TRUE);
2888
2889 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);
2890
2891 /* move hwnd_F and its popups up */
2893 check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2894 check_z_order(hwnd_D, hwnd_E, hwnd_F, 0, FALSE);
2895 check_z_order(hwnd_F, hwnd_D, hwnd_C, 0, FALSE);
2896 check_z_order(hwnd_C, hwnd_F, hwnd_B, hwnd_F, FALSE);
2897 check_z_order(hwnd_B, hwnd_C, hwnd_A, hwnd_F, TRUE);
2898 check_z_order(hwnd_A, hwnd_B, 0, 0, TRUE);
2899
2900 /* move hwnd_F and its popups down */
2901#if 0 /* enable once Wine is fixed to pass this test */
2903 check_z_order(hwnd_F, 0, hwnd_C, 0, FALSE);
2904 check_z_order(hwnd_C, hwnd_F, hwnd_B, hwnd_F, FALSE);
2905 check_z_order(hwnd_B, hwnd_C, hwnd_E, hwnd_F, FALSE);
2906 check_z_order(hwnd_E, hwnd_B, hwnd_D, 0, FALSE);
2907 check_z_order(hwnd_D, hwnd_E, hwnd_A, 0, FALSE);
2908 check_z_order(hwnd_A, hwnd_D, 0, 0, TRUE);
2909#endif
2910
2911 /* make hwnd_C owned by a topmost window */
2912 DestroyWindow( hwnd_C );
2913 hwnd_C = CreateWindowExA(0, "MainWindowClass", NULL,
2914 style,
2915 100, 100, 100, 100,
2916 hwnd_A, 0, GetModuleHandleA(NULL), NULL);
2917 trace("hwnd_C %p\n", hwnd_C);
2918 check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
2919 check_z_order(hwnd_D, hwnd_E, hwnd_F, 0, FALSE);
2920 check_z_order(hwnd_F, hwnd_D, hwnd_B, 0, FALSE);
2921 check_z_order(hwnd_B, hwnd_F, hwnd_A, hwnd_F, TRUE);
2922 check_z_order(hwnd_A, hwnd_B, hwnd_C, 0, TRUE);
2923 check_z_order(hwnd_C, hwnd_A, 0, hwnd_A, TRUE);
2924
2925 DestroyWindow(hwnd_A);
2926 DestroyWindow(hwnd_B);
2927 DestroyWindow(hwnd_C);
2928 DestroyWindow(hwnd_F);
2929}
2930
2931static void test_vis_rgn( HWND hwnd )
2932{
2933 RECT win_rect, rgn_rect;
2934 HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
2935 HDC hdc;
2936
2938 hdc = GetDC( hwnd );
2939 ok( GetRandomRgn( hdc, hrgn, SYSRGN ) != 0, "GetRandomRgn failed\n" );
2940 GetWindowRect( hwnd, &win_rect );
2941 GetRgnBox( hrgn, &rgn_rect );
2942 if (is_win9x)
2943 {
2944 trace("win9x, mapping to screen coords\n");
2945 MapWindowPoints( hwnd, 0, (POINT *)&rgn_rect, 2 );
2946 }
2947 trace("win: %s\n", wine_dbgstr_rect(&win_rect));
2948 trace("rgn: %s\n", wine_dbgstr_rect(&rgn_rect));
2949 ok( win_rect.left <= rgn_rect.left, "rgn left %d not inside win rect %d\n",
2950 rgn_rect.left, win_rect.left );
2951 ok( win_rect.top <= rgn_rect.top, "rgn top %d not inside win rect %d\n",
2952 rgn_rect.top, win_rect.top );
2953 ok( win_rect.right >= rgn_rect.right, "rgn right %d not inside win rect %d\n",
2954 rgn_rect.right, win_rect.right );
2955 ok( win_rect.bottom >= rgn_rect.bottom, "rgn bottom %d not inside win rect %d\n",
2956 rgn_rect.bottom, win_rect.bottom );
2957 ReleaseDC( hwnd, hdc );
2958}
2959
2961{
2962 if (msg == WM_ACTIVATE && LOWORD(wp) == WA_ACTIVE)
2963 {
2965 ok(child != 0, "couldn't find child window\n");
2966 SetFocus(child);
2967 ok(GetFocus() == child, "Focus should be on child %p\n", child);
2968 return 0;
2969 }
2970 return DefWindowProcA(hwnd, msg, wp, lp);
2971}
2972
2974{
2975 HWND child, child2, ret;
2977
2978 /* check if we can set focus to non-visible windows */
2979
2981 SetFocus(0);
2982 SetFocus(hwnd);
2983 ok( GetFocus() == hwnd, "Failed to set focus to visible window %p\n", hwnd );
2984 ok( GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE, "Window %p not visible\n", hwnd );
2986 SetFocus(0);
2987 SetFocus(hwnd);
2988 ok( GetFocus() == hwnd, "Failed to set focus to invisible window %p\n", hwnd );
2989 ok( !(GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE), "Window %p still visible\n", hwnd );
2990 child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, hwnd, 0, 0, NULL);
2991 assert(child);
2992 SetFocus(child);
2993 ok( GetFocus() == child, "Failed to set focus to invisible child %p\n", child );
2994 ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
2996 ok( GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE, "Child %p is not visible\n", child );
2997 ok( GetFocus() == child, "Focus no longer on child %p\n", child );
2999 ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
3000 ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
3002 child2 = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, child, 0, 0, NULL);
3003 assert(child2);
3004 ShowWindow(child2, SW_SHOW);
3005 SetFocus(child2);
3007 ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
3008 ok( GetFocus() == child2, "Focus should be on %p, not %p\n", child2, GetFocus() );
3010 SetFocus(child);
3011 ok( GetFocus() == child, "Focus should be on child %p\n", child );
3013 ok( GetFocus() == child, "Focus should still be on child %p\n", child );
3014
3016 SetFocus(hwnd);
3017 ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
3019 ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
3021 ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
3022
3025 SetFocus(