ReactOS 0.4.17-dev-1321-g5c122a9
mdi.c
Go to the documentation of this file.
1/* MDI.C
2 *
3 * Copyright 1994, Bob Amstadt
4 * Copyright 1995,1996 Alex Korobka
5 * Copyright 2018 Katayama Hirofumi MZ
6 *
7 * This file contains routines to support MDI (Multiple Document
8 * Interface) features.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 *
24 * Notes: Fairly complete implementation.
25 * Also, Excel and WinWord do _not_ use MDI so if you're trying
26 * to fix them look elsewhere.
27 *
28 * Notes on how the "More Windows..." is implemented:
29 *
30 * When we have more than 9 opened windows, a "More Windows..."
31 * option appears in the "Windows" menu. Each child window has
32 * a WND* associated with it, accessible via the children list of
33 * the parent window. This WND* has a wIDmenu member, which reflects
34 * the position of the child in the window list. For example, with
35 * 9 child windows, we could have the following pattern:
36 *
37 *
38 *
39 * Name of the child window pWndChild->wIDmenu
40 * Doc1 5000
41 * Doc2 5001
42 * Doc3 5002
43 * Doc4 5003
44 * Doc5 5004
45 * Doc6 5005
46 * Doc7 5006
47 * Doc8 5007
48 * Doc9 5008
49 *
50 *
51 * The "Windows" menu, as the "More windows..." dialog, are constructed
52 * in this order. If we add a child, we would have the following list:
53 *
54 *
55 * Name of the child window pWndChild->wIDmenu
56 * Doc1 5000
57 * Doc2 5001
58 * Doc3 5002
59 * Doc4 5003
60 * Doc5 5004
61 * Doc6 5005
62 * Doc7 5006
63 * Doc8 5007
64 * Doc9 5008
65 * Doc10 5009
66 *
67 * But only 5000 to 5008 would be displayed in the "Windows" menu. We want
68 * the last created child to be in the menu, so we swap the last child with
69 * the 9th... Doc9 will be accessible via the "More Windows..." option.
70 *
71 * Doc1 5000
72 * Doc2 5001
73 * Doc3 5002
74 * Doc4 5003
75 * Doc5 5004
76 * Doc6 5005
77 * Doc7 5006
78 * Doc8 5007
79 * Doc9 5009
80 * Doc10 5008
81 *
82 */
83
84#include <user32.h>
85
87
88#define MDI_MAXTITLELENGTH 0xa1
89
90#define WM_MDICALCCHILDSCROLL 0x003f /* this is exactly what Windows uses */
91
92/* "More Windows..." definitions */
93#define MDI_MOREWINDOWSLIMIT 9 /* after this number of windows, a "More Windows..."
94 option will appear under the Windows menu */
95#define MDI_IDC_LISTBOX 100
96#define IDS_MDI_MOREWINDOWS 13
98#define MDIF_NEEDUPDATE 0x0001
100typedef struct
101{
102 /* At some points, particularly when switching MDI children, active and
103 * maximized MDI children may be not the same window, so we need to track
104 * them separately.
105 * The only place where we switch to/from maximized state is DefMDIChildProc
106 * WM_SIZE/SIZE_MAXIMIZED handler. We get that notification only after the
107 * ShowWindow(SW_SHOWMAXIMIZED) request, therefore window is guaranteed to
108 * be visible at the time we get the notification, and it's safe to assume
109 * that hwndChildMaximized is always visible.
110 * If the app plays games with WS_VISIBLE, WS_MAXIMIZE or any other window
111 * states it must keep coherency with USER32 on its own. This is true for
112 * Windows as well.
113 */
115 UINT nActiveChildren;
116 HWND hwndChildMaximized;
117 HWND hwndActiveChild;
118 HWND *child; /* array of tracked children */
119 HMENU hFrameMenu;
121 UINT idFirstChild;
122 LPWSTR frameTitle;
123 UINT nTotalCreated;
124 UINT mdiFlags;
125 UINT sbRecalc; /* SB_xxx flags for scrollbar fixup */
126 HBITMAP hBmpClose; /* ReactOS modification */
128
129//static HBITMAP hBmpClose = 0;
130
131/* ----------------- declarations ----------------- */
132static void MDI_UpdateFrameText( HWND, HWND, BOOL, LPCWSTR);
137
140HWND* WIN_ListChildren (HWND hWndparent)
141{
142
143 DWORD dwCount = 0;
144 HWND* pHwnd = NULL;
145 HANDLE hHeap;
147
148 Status = NtUserBuildHwndList(NULL, hWndparent, FALSE, 0, dwCount, NULL, &dwCount);
149
150 if ( !NT_SUCCESS( Status ) )
151 return 0;
152
153 /* allocate buffer to receive HWND handles */
154 hHeap = GetProcessHeap();
155
156 pHwnd = HeapAlloc ( hHeap, 0, sizeof(HWND)*(dwCount+1) );
157 if ( !pHwnd )
158 {
160 return 0;
161 }
162
163 /* now call kernel again to fill the buffer this time */
164 Status = NtUserBuildHwndList(NULL, hWndparent, FALSE, 0, dwCount, pHwnd, &dwCount);
165
166 if ( !NT_SUCCESS( Status ) )
167 {
168 if ( pHwnd )
169 HeapFree ( hHeap, 0, pHwnd );
170 return 0;
171 }
172
173 pHwnd[dwCount] = (HWND) 0;
174
175 return pHwnd;
176}
177
178
179/* -------- Miscellaneous service functions ----------
180 *
181 * MDI_GetChildByID
182 */
184{
185 int i;
186
187 for (i = 0; ci->nActiveChildren; i++)
188 {
189 if (GetWindowLongPtrW( ci->child[i], GWLP_ID ) == id)
190 return ci->child[i];
191 }
192 return 0;
193}
195static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
196{
197 if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
198 {
201 }
202 ci->sbRecalc = recalc;
203}
204
205#ifdef __REACTOS__
206/*********************************************************************
207 * MDIClient class descriptor
208 */
210{
211 L"MDIClient", /* name */
212 0, /* style */
213 &pfnClientA.pfnMDIClientWndProc, /* procA */
214 &pfnClientW.pfnMDIClientWndProc, /* procW */
215 sizeof(MDIWND), /* extra */
216 IDC_ARROW, /* cursor */
217 (HBRUSH)(COLOR_APPWORKSPACE+1) /* brush */
218};
219#endif
222{
224}
226static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
227{
229
230 if (!hSysMenu) hSysMenu = NtUserGetSystemMenu( hwnd, FALSE );
231 if (hSysMenu)
232 {
234 if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
235 return FALSE;
236 }
237 return TRUE;
238}
239
240/**********************************************************************
241 * MDI_GetWindow
242 *
243 * returns "activatable" child different from the current or zero
244 */
245static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
246 DWORD dwStyleMask )
247{
248 int i;
249 HWND *list;
250 HWND last = 0;
251
252 dwStyleMask |= WS_DISABLED | WS_VISIBLE;
253 if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
254
255 if (!(list = WIN_ListChildren( GetParent(hWnd) ))) return 0;
256 i = 0;
257 /* start from next after hWnd */
258 while (list[i] && list[i] != hWnd) i++;
259 if (list[i]) i++;
260
261 for ( ; list[i]; i++)
262 {
263 if (GetWindow( list[i], GW_OWNER )) continue;
264 if ((GetWindowLongPtrW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
265 last = list[i];
266 if (bNext) goto found;
267 }
268 /* now restart from the beginning */
269 for (i = 0; list[i] && list[i] != hWnd; i++)
270 {
271 if (GetWindow( list[i], GW_OWNER )) continue;
272 if ((GetWindowLongPtrW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
273 last = list[i];
274 if (bNext) goto found;
275 }
276 found:
278 return last;
279}
280
281/**********************************************************************
282 * MDI_CalcDefaultChildPos
283 *
284 * It seems that the default height is about 2/3 of the client rect
285 */
286void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id )
287{
288 INT nstagger;
289 RECT rect;
291
292 if (total < 0) /* we are called from CreateWindow */
293 {
294 MDICLIENTINFO *ci = get_client_info(hwndClient);
295 total = ci ? ci->nTotalCreated : 0; // Do not portsync wine
296 *id = ci ? ci->idFirstChild + ci->nActiveChildren : 0; // Do not portsync wine
297 TRACE("MDI child id %04x\n", *id);
298 }
299
300 GetClientRect( hwndClient, &rect );
301 if( rect.bottom - rect.top - delta >= spacing )
302 rect.bottom -= delta;
303
304 nstagger = (rect.bottom - rect.top)/(3 * spacing);
305 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
306 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
307 lpPos[0].x = lpPos[0].y = spacing * (total%(nstagger+1));
308}
309
310/**********************************************************************
311 * MDISetMenu
312 */
313static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
314 HMENU hmenuWindow)
315{
316 MDICLIENTINFO *ci;
317 HWND hwndFrame = GetParent(hwnd);
318
319 TRACE("%p, frame menu %p, window menu %p\n", hwnd, hmenuFrame, hmenuWindow);
320
321 if (hmenuFrame && !IsMenu(hmenuFrame))
322 {
323 WARN("hmenuFrame is not a menu handle\n");
324 return 0L;
325 }
326
327 if (hmenuWindow && !IsMenu(hmenuWindow))
328 {
329 WARN("hmenuWindow is not a menu handle\n");
330 return 0L;
331 }
332
333 if (!(ci = get_client_info( hwnd ))) return 0;
334
335 TRACE("old frame menu %p, old window menu %p\n", ci->hFrameMenu, ci->hWindowMenu);
336
337 if (hmenuFrame)
338 {
339 if (hmenuFrame == ci->hFrameMenu) return (LRESULT)hmenuFrame;
340
341 if (ci->hwndChildMaximized)
343 }
344
345 if( hmenuWindow && hmenuWindow != ci->hWindowMenu )
346 {
347 /* delete menu items from ci->hWindowMenu
348 * and add them to hmenuWindow */
349 /* Agent newsreader calls this function with ci->hWindowMenu == NULL */
350 if( ci->hWindowMenu && ci->nActiveChildren )
351 {
352 UINT nActiveChildren_old = ci->nActiveChildren;
353
354 /* Remove all items from old Window menu */
355 ci->nActiveChildren = 0;
356 MDI_RefreshMenu(ci);
357
358 ci->hWindowMenu = hmenuWindow;
359
360 ci->nActiveChildren = nActiveChildren_old;
361 }
362 else
363 ci->hWindowMenu = hmenuWindow;
364
365 MDI_RefreshMenu(ci);
366 }
367
368 if (hmenuFrame)
369 {
370#ifdef __REACTOS__
371 NtUserSetMenu(hwndFrame, hmenuFrame, TRUE);
372#else
373 NtUserSetMenu(hwndFrame, hmenuFrame);
374#endif
375 if( hmenuFrame != ci->hFrameMenu )
376 {
377 HMENU oldFrameMenu = ci->hFrameMenu;
378
379 ci->hFrameMenu = hmenuFrame;
380 if (ci->hwndChildMaximized)
382
383 return (LRESULT)oldFrameMenu;
384 }
385 }
386
387 return 0;
388}
389
390/**********************************************************************
391 * MDIRefreshMenu
392 */
394{
395 UINT i, count, visible, id;
397
398 TRACE("children %u, window menu %p\n", ci->nActiveChildren, ci->hWindowMenu);
399
400 if (!ci->hWindowMenu)
401 return 0;
402
403 if (!IsMenu(ci->hWindowMenu))
404 {
405 WARN("Window menu handle %p is no longer valid\n", ci->hWindowMenu);
406 return 0;
407 }
408
409 /* Windows finds the last separator in the menu, and if after it
410 * there is a menu item with MDI magic ID removes all existing
411 * menu items after it, and then adds visible MDI children.
412 */
414 for (i = 0; i < count; i++)
415 {
416 MENUITEMINFOW mii;
417
418 memset(&mii, 0, sizeof(mii));
419 mii.cbSize = sizeof(mii);
420 mii.fMask = MIIM_TYPE;
421 if (GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii))
422 {
423 if (mii.fType & MF_SEPARATOR)
424 {
425 /* Windows checks only ID of the menu item */
426 memset(&mii, 0, sizeof(mii));
427 mii.cbSize = sizeof(mii);
428 mii.fMask = MIIM_ID;
429 if (GetMenuItemInfoW(ci->hWindowMenu, i + 1, TRUE, &mii))
430 {
431 if (mii.wID == ci->idFirstChild)
432 {
433 TRACE("removing %u items including separator\n", count - i);
435 /* nothing */;
436
437 break;
438 }
439 }
440 }
441 }
442 }
443
444 visible = 0;
445 for (i = 0; i < ci->nActiveChildren; i++)
446 {
448 {
449 id = ci->idFirstChild + visible;
450
451 if (visible == MDI_MOREWINDOWSLIMIT)
452 {
455 break;
456 }
457
458 if (!visible)
459 /* Visio expects that separator has id 0 */
461
462 visible++;
463
464 SetWindowLongPtrW(ci->child[i], GWLP_ID, id);
465
466 buf[0] = '&';
467 buf[1] = '0' + visible;
468 buf[2] = ' ';
470 TRACE("Adding %p, id %u %s\n", ci->child[i], id, debugstr_w(buf));
472
473 if (ci->child[i] == ci->hwndActiveChild)
474#ifdef __REACTOS__
476#else
478#endif
479 }
480 else
481 TRACE("MDI child %p is not visible, skipping\n", ci->child[i]);
482 }
483
484 return (LRESULT)ci->hFrameMenu;
485}
486
487
488/* ------------------ MDI child window functions ---------------------- */
489
490/**********************************************************************
491 * MDI_ChildGetMinMaxInfo
492 *
493 * Note: The rule here is that client rect of the maximized MDI child
494 * is equal to the client rect of the MDI client window.
495 */
496static void MDI_ChildGetMinMaxInfo( HWND client, HWND hwnd, MINMAXINFO* lpMinMax )
497{
498 RECT rect;
499
503
504 lpMinMax->ptMaxSize.x = rect.right -= rect.left;
505 lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
506
507 lpMinMax->ptMaxPosition.x = rect.left;
508 lpMinMax->ptMaxPosition.y = rect.top;
509
510 TRACE("max rect %s\n", wine_dbgstr_rect(&rect));
511}
512
513/**********************************************************************
514 * MDI_SwitchActiveChild
515 *
516 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
517 * being activated
518 */
519static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo, BOOL activate )
520{
521 HWND hwndPrev;
522
523 hwndPrev = ci->hwndActiveChild;
524
525 TRACE("from %p, to %p\n", hwndPrev, hwndTo);
526
527 if ( hwndTo != hwndPrev )
528 {
529 BOOL was_zoomed = IsZoomed(hwndPrev);
530
531 if (was_zoomed && (GetWindowLongW( hwndTo, GWL_STYLE ) & WS_MAXIMIZEBOX))
532 {
533 /* restore old MDI child */
534 SendMessageW( hwndPrev, WM_SETREDRAW, FALSE, 0 );
535 NtUserShowWindow( hwndPrev, SW_RESTORE );
536 SendMessageW( hwndPrev, WM_SETREDRAW, TRUE, 0 );
537
538 /* activate new MDI child */
539 NtUserSetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
540 /* maximize new MDI child */
541 NtUserShowWindow( hwndTo, SW_MAXIMIZE );
542 }
543 /* activate new MDI child */
544 NtUserSetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0,
545 SWP_NOMOVE | SWP_NOSIZE | (activate ? 0 : SWP_NOACTIVATE) );
546 }
547}
548
549
550/**********************************************************************
551 * MDIDestroyChild
552 */
554 HWND child, BOOL flagDestroy )
555{
556 UINT i;
557
558 TRACE("# of managed children %u\n", ci->nActiveChildren);
559
560 if( child == ci->hwndActiveChild )
561 {
562 HWND next = MDI_GetWindow(ci, child, TRUE, 0);
563 if (next)
565 else
566 {
568 if (child == ci->hwndChildMaximized)
569 {
570 HWND frame = GetParent(client);
572 ci->hwndChildMaximized = 0;
574 }
575 if (flagDestroy)
577 }
578 }
579
580 for (i = 0; i < ci->nActiveChildren; i++)
581 {
582 if (ci->child[i] == child)
583 {
584 HWND *new_child = HeapAlloc(GetProcessHeap(), 0, (ci->nActiveChildren - 1) * sizeof(HWND));
585 if (new_child != NULL)
586 {
587 memcpy(new_child, ci->child, i * sizeof(HWND));
588 if (i + 1 < ci->nActiveChildren)
589 memcpy(new_child + i, ci->child + i + 1, (ci->nActiveChildren - i - 1) * sizeof(HWND));
590 HeapFree(GetProcessHeap(), 0, ci->child);
591 ci->child = new_child;
592 }
593 else
594 {
595 UINT c;
596 for (c = i; c < ci->nActiveChildren - 1; c++)
597 {
598 ci->child[c] = ci->child[c+1];
599 }
600 }
601
602 ci->nActiveChildren--;
603 break;
604 }
605 }
606
607 if (flagDestroy)
608 {
612 }
613
614 TRACE("child destroyed - %p\n", child);
615 return 0;
616}
617
618
619/**********************************************************************
620 * MDI_ChildActivate
621 *
622 * Called in response to WM_CHILDACTIVATE, or when last MDI child
623 * is being deactivated.
624 */
626{
627 MDICLIENTINFO *clientInfo;
628 HWND prevActiveWnd, frame;
629 BOOL isActiveFrameWnd;
630
631 clientInfo = get_client_info( client );
632
633 if (clientInfo->hwndActiveChild == child) return 0;
634
635 TRACE("%p\n", child);
636
637 frame = GetParent(client);
638 isActiveFrameWnd = (GetActiveWindow() == frame);
639 prevActiveWnd = clientInfo->hwndActiveChild;
640
641 /* deactivate prev. active child */
642 if(prevActiveWnd)
643 {
644 SendMessageW( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
645 SendMessageW( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
646 }
647
648 MDI_SwitchActiveChild( clientInfo, child, FALSE );
649 clientInfo->hwndActiveChild = child;
650
651 MDI_RefreshMenu(clientInfo);
652
653 if( isActiveFrameWnd )
654 {
656 /* Let the client window manage focus for children, but if the focus
657 * is already on the client (for instance this is the 1st child) then
658 * SetFocus won't work. It appears that Windows sends WM_SETFOCUS
659 * manually in this case.
660 */
663 }
664
665 SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
666 return TRUE;
667}
668
669/* -------------------- MDI client window functions ------------------- */
670
671/**********************************************************************
672 * CreateMDIMenuBitmap
673 */
674static HBITMAP CreateMDIMenuBitmap(void)
675{
676 HDC hDCSrc = CreateCompatibleDC(0);
677 HDC hDCDest = CreateCompatibleDC(hDCSrc);
678 HBITMAP hbClose = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_OLD_CLOSE) );
679 HBITMAP hbCopy;
680 HBITMAP hobjSrc, hobjDest;
681
682 hobjSrc = SelectObject(hDCSrc, hbClose);
684 hobjDest = SelectObject(hDCDest, hbCopy);
685
687 hDCSrc, GetSystemMetrics(SM_CXSIZE), 0, SRCCOPY);
688
689 SelectObject(hDCSrc, hobjSrc);
690 DeleteObject(hbClose);
691 DeleteDC(hDCSrc);
692
693 hobjSrc = SelectObject( hDCDest, GetStockObject(BLACK_PEN) );
694
695 MoveToEx( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, 0, NULL );
697
698 SelectObject(hDCDest, hobjSrc );
699 SelectObject(hDCDest, hobjDest);
700 DeleteDC(hDCDest);
701
702 return hbCopy;
703}
704
705/**********************************************************************
706 * MDICascade
707 */
709{
710 HWND *win_array;
711 BOOL has_icons = FALSE;
712 int i, total;
713
714 if (ci->hwndChildMaximized)
716
717 if (ci->nActiveChildren == 0) return 0;
718
719 if (!(win_array = WIN_ListChildren( client ))) return 0;
720
721 /* remove all the windows we don't want */
722 for (i = total = 0; win_array[i]; i++)
723 {
724 if (!IsWindowVisible( win_array[i] )) continue;
725 if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows */
726 if (IsIconic( win_array[i] ))
727 {
728 has_icons = TRUE;
729 continue;
730 }
731 win_array[total++] = win_array[i];
732 }
733 win_array[total] = 0;
734
735 if (total)
736 {
737 INT delta = 0, n = 0, i;
738 POINT pos[2];
740
741 /* walk the list (backwards) and move windows */
742 for (i = total - 1; i >= 0; i--)
743 {
744 LONG style;
746
748 TRACE("move %p to (%ld,%ld) size [%ld,%ld]\n",
749 win_array[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
750 style = GetWindowLongW(win_array[i], GWL_STYLE);
751
752 if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
753 NtUserSetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y, posOptions );
754 }
755 }
756 HeapFree( GetProcessHeap(), 0, win_array );
757
758 if (has_icons) NtUserArrangeIconicWindows( client );
759 return 0;
760}
761
762/**********************************************************************
763 * MDITile
764 */
765static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
766{
767 HWND *win_array;
768 int i, total, rows, columns;
769 BOOL has_icons = FALSE;
770
771 if (ci->hwndChildMaximized)
773
774 if (ci->nActiveChildren == 0) return;
775
776 if (!(win_array = WIN_ListChildren( client ))) return;
777
778 /* remove all the windows we don't want */
779 for (i = total = rows = 0; win_array[i]; i++)
780 {
781 if (!IsWindowVisible( win_array[i] )) continue;
782 if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows (icon titles) */
783 if (IsIconic( win_array[i] ))
784 {
785 has_icons = TRUE;
786 continue;
787 }
788 if ((wParam & MDITILE_SKIPDISABLED) && !IsWindowEnabled( win_array[i] )) continue;
789 if(total == (rows * (rows + 2))) rows++; /* total+1 == (rows+1)*(rows+1) */
790 win_array[total++] = win_array[i];
791 }
792 win_array[total] = 0;
793
794 TRACE("%u windows to tile\n", total);
795
796 if (total)
797 {
798 HWND *pWnd = win_array;
799 RECT rect;
800 int x, y, xsize, ysize;
801 int r, c, i;
802
804 columns = total/rows;
805 //while(total < rows*columns) rows++;
806
807 if( wParam & MDITILE_HORIZONTAL ) /* version >= 3.1 */
808 {
809 i = rows;
810 rows = columns; /* exchange r and c */
811 columns = i;
812 }
813
814 if (has_icons)
815 {
818 }
819
820 ysize = rect.bottom / rows;
821 xsize = rect.right / columns;
822
823 for (x = i = 0, c = 1; c <= columns && *pWnd; c++)
824 {
825 if (c == columns)
826 {
827 rows = total - i;
828 ysize = rect.bottom / rows;
829 }
830
831 y = 0;
832 for (r = 1; r <= rows && *pWnd; r++, i++)
833 {
835 LONG style = GetWindowLongW(win_array[i], GWL_STYLE);
836 if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
837
838 NtUserSetWindowPos( *pWnd, 0, x, y, xsize, ysize, posOptions );
839 y += ysize;
840 pWnd++;
841 }
842 x += xsize;
843 }
844 }
845 HeapFree( GetProcessHeap(), 0, win_array );
846 if (has_icons) NtUserArrangeIconicWindows( client );
847}
848
849/* ----------------------- Frame window ---------------------------- */
850
851
852/**********************************************************************
853 * MDI_AugmentFrameMenu
854 */
856{
857 HMENU menu = GetMenu( frame );
858 HMENU hSysPopup;
859 HBITMAP hSysMenuBitmap = 0;
860 HICON hIcon;
861 INT nItems;
862 UINT iId;
863
864 TRACE("frame %p,child %p\n",frame,hChild);
865
866 if( !menu ) return FALSE;
868 /* if the system buttons already exist do not add them again */
870 iId = GetMenuItemID(menu,nItems) ;
871 if (iId == SC_RESTORE || iId == SC_CLOSE)
872 {
873 ERR("system buttons already exist\n");
874 return FALSE;
875 }
877 /* create a copy of sysmenu popup and insert it into frame menu bar */
878 if (!(hSysPopup = NtUserGetSystemMenu( hChild, FALSE )))
879 {
880 TRACE("child %p doesn't have a system menu\n", hChild);
881 return FALSE;
882 }
883
885 SC_CLOSE, is_close_enabled(hChild, hSysPopup) ?
891
892 /* The system menu is replaced by the child icon */
893 hIcon = (HICON)SendMessageW(hChild, WM_GETICON, ICON_SMALL, 0);
894 if (!hIcon)
896 if (!hIcon)
897 hIcon = (HICON)SendMessageW(hChild, WM_GETICON, ICON_BIG, 0);
898 if (!hIcon)
900 if (!hIcon)
903 if (hIcon)
904 {
905 HDC hMemDC;
906 HBITMAP hBitmap, hOldBitmap;
908
909 if (hdc)
910 {
911 int cx, cy;
914 hMemDC = CreateCompatibleDC(hdc);
916 hOldBitmap = SelectObject(hMemDC, hBitmap);
917 SetMapMode(hMemDC, MM_TEXT);
918#ifdef __REACTOS__
919 NtUserDrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL, 0, 0);
920#else
922#endif
923 SelectObject (hMemDC, hOldBitmap);
924 DeleteDC(hMemDC);
926 hSysMenuBitmap = hBitmap;
927 }
928 }
929
931 (UINT_PTR)hSysPopup, (LPSTR)hSysMenuBitmap))
932 {
933 TRACE("not inserted\n");
934 NtUserDestroyMenu( hSysPopup );
935 return FALSE;
936 }
937
942
943 /* redraw menu */
944 NtUserDrawMenuBar(frame);
945
946 return TRUE;
947}
948
949/**********************************************************************
950 * MDI_RestoreFrameMenu
951 */
952static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild, HBITMAP hBmpClose )
953{
954 MENUITEMINFOW menuInfo;
955 HMENU menu = GetMenu( frame );
956 INT nItems;
957 UINT iId;
958
959 TRACE("frame %p,child %p\n",frame, hChild);
960
961 if (!menu) return FALSE;
962
963 /* if there is no system buttons then nothing to do */
965 iId = GetMenuItemID(menu, nItems);
966 if ( !(iId == SC_RESTORE || iId == SC_CLOSE) )
967 {
968 ERR("no system buttons then nothing to do\n");
969 return FALSE;
970 }
971
972 /*
973 * Remove the system menu, If that menu is the icon of the window
974 * as it is in win95, we have to delete the bitmap.
975 */
976 memset(&menuInfo, 0, sizeof(menuInfo));
977 menuInfo.cbSize = sizeof(menuInfo);
978 menuInfo.fMask = MIIM_DATA | MIIM_TYPE | MIIM_BITMAP;
979
981 0,
982 TRUE,
983 &menuInfo);
984
986
987 if ( (menuInfo.fType & MFT_BITMAP) &&
988 (menuInfo.dwTypeData != 0) &&
989 (menuInfo.dwTypeData != (LPWSTR)hBmpClose) )
990 {
991 DeleteObject(menuInfo.dwTypeData);
992 }
993
994 if ( menuInfo.hbmpItem != 0 )
995 DeleteObject(menuInfo.hbmpItem);
996
997 /* close */
999 /* restore */
1001 /* minimize */
1003
1004 NtUserDrawMenuBar(frame);
1005
1006 return TRUE;
1007}
1008
1009
1010/**********************************************************************
1011 * MDI_UpdateFrameText
1012 *
1013 * used when child window is maximized/restored
1014 *
1015 * Note: lpTitle can be NULL
1017static void MDI_UpdateFrameText( HWND frame, HWND hClient, BOOL repaint, LPCWSTR lpTitle )
1018{
1020 MDICLIENTINFO *ci = get_client_info( hClient );
1021
1022 TRACE("frameText %s\n", debugstr_w(lpTitle));
1023
1024 if (!ci) return;
1025
1026 if (!lpTitle && !ci->frameTitle) /* first time around, get title from the frame window */
1027 {
1029 lpTitle = lpBuffer;
1030 }
1031
1032 /* store new "default" title if lpTitle is not NULL */
1033 if (lpTitle)
1034 {
1035 HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1036 if ((ci->frameTitle = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(lpTitle)+1)*sizeof(WCHAR))))
1037 lstrcpyW( ci->frameTitle, lpTitle );
1038 }
1039
1040 if (ci->frameTitle)
1041 {
1042 if (ci->hwndChildMaximized)
1043 {
1044 /* combine frame title and child title if possible */
1045 int i_frame_text_length = lstrlenW(ci->frameTitle);
1046
1048
1049 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
1050 {
1051 lstrcatW( lpBuffer, L" - [" );
1052 if (GetWindowTextW( ci->hwndActiveChild, lpBuffer + i_frame_text_length + 4,
1053 MDI_MAXTITLELENGTH - i_frame_text_length - 5 ))
1054 lstrcatW( lpBuffer, L"]" );
1055 else
1056 lpBuffer[i_frame_text_length] = 0; /* remove bracket */
1057 }
1058 }
1059 else
1060 {
1062 }
1063 }
1064 else
1065 lpBuffer[0] = '\0';
1066
1068
1069 if (repaint)
1070 {
1072 NtUserSetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
1074 }
1075}
1076
1077
1078/* ----------------------------- Interface ---------------------------- */
1079
1080
1081/**********************************************************************
1082 * MDIClientWndProc_common
1085{
1086 MDICLIENTINFO *ci = NULL;
1087
1088 TRACE("%p %04x (%s) %08Ix %08Ix\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1089
1091
1092 if (!(ci = get_client_info( hwnd )))
1093 {
1094 if (message == WM_NCCREATE)
1095 {
1096 if (!(ci = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ci) ))) return 0;
1098 }
1099 return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1101 }
1102
1103 switch (message)
1104 {
1105 case WM_CREATE:
1106 {
1107 /* Since we are using only cs->lpCreateParams, we can safely
1108 * cast to LPCREATESTRUCTA here */
1110 LPCLIENTCREATESTRUCT ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
1111
1112 ci->hWindowMenu = ccs->hWindowMenu;
1113 ci->idFirstChild = ccs->idFirstChild;
1114 ci->hwndChildMaximized = 0;
1115 ci->child = NULL;
1116 ci->nActiveChildren = 0;
1117 ci->nTotalCreated = 0;
1118 ci->frameTitle = NULL;
1119 ci->mdiFlags = 0;
1120 ci->hFrameMenu = GetMenu(cs->hwndParent);
1121
1122 if (!ci->hBmpClose) ci->hBmpClose = CreateMDIMenuBitmap();
1123
1124 TRACE("Client created: hwnd %p, Window menu %p, idFirst = %04x\n",
1125 hwnd, ci->hWindowMenu, ci->idFirstChild );
1126 return 0;
1127 }
1128
1129 case WM_DESTROY:
1130 {
1131 if( ci->hwndChildMaximized )
1133
1134 ci->nActiveChildren = 0;
1135 MDI_RefreshMenu(ci);
1136
1137 HeapFree( GetProcessHeap(), 0, ci->child );
1138 HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1139 HeapFree( GetProcessHeap(), 0, ci );
1140#ifdef __REACTOS__
1142#endif
1143 return 0;
1144 }
1145
1146#ifdef __REACTOS__
1147 case WM_NCDESTROY:
1148 {
1150 return 0;
1151 }
1152#endif
1153
1154 case WM_MDIACTIVATE:
1155 {
1156 if( ci->hwndActiveChild != (HWND)wParam )
1158 return 0;
1159 }
1160
1161 case WM_MDICASCADE:
1162 return MDICascade(hwnd, ci);
1163
1164 case WM_MDICREATE:
1165 if (lParam)
1166 {
1167 HWND child;
1168
1169 if (unicode)
1170 {
1173 csW->szTitle, csW->style,
1174 csW->x, csW->y, csW->cx, csW->cy,
1175 hwnd, 0, csW->hOwner,
1176 (LPVOID)csW->lParam);
1177 }
1178 else
1179 {
1182 csA->szTitle, csA->style,
1183 csA->x, csA->y, csA->cx, csA->cy,
1184 hwnd, 0, csA->hOwner,
1185 (LPVOID)csA->lParam);
1186 }
1187 return (LRESULT)child;
1188 }
1189 return 0;
1190
1191 case WM_MDIDESTROY:
1192 return MDIDestroyChild( hwnd, ci, (HWND)wParam, TRUE );
1193
1194 case WM_MDIGETACTIVE:
1195 if (lParam) *(BOOL *)lParam = IsZoomed(ci->hwndActiveChild);
1196 return (LRESULT)ci->hwndActiveChild;
1197
1198 case WM_MDIICONARRANGE:
1201 ci->sbRecalc = SB_BOTH+1;
1202#ifdef __REACTOS__
1204#else
1206#endif
1207 return 0;
1208
1209 case WM_MDIMAXIMIZE:
1211 return 0;
1212
1213 case WM_MDINEXT: /* lParam != 0 means previous window */
1214 {
1216 HWND next = MDI_GetWindow( ci, hwnd, !lParam, 0 );
1218 if (!lParam)
1220 break;
1221 }
1222
1223 case WM_MDIRESTORE:
1225 return 0;
1226
1227 case WM_MDISETMENU:
1228 return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
1229
1230 case WM_MDIREFRESHMENU:
1231 return MDI_RefreshMenu( ci );
1232
1233 case WM_MDITILE:
1236 MDITile( hwnd, ci, wParam );
1237 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1238 return 0;
1239
1240 case WM_VSCROLL:
1241 case WM_HSCROLL:
1244 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1245 return 0;
1246
1247 case WM_SETFOCUS:
1248 if (ci->hwndActiveChild && !IsIconic( ci->hwndActiveChild ))
1250 return 0;
1251
1252 case WM_NCACTIVATE:
1253 if( ci->hwndActiveChild )
1255 break;
1256
1257 case WM_PARENTNOTIFY:
1258 switch (LOWORD(wParam))
1259 {
1260 case WM_CREATE:
1262 {
1263 // ReactOS See rev 33503
1264 if (!ci->child)
1265 ci->child = HeapAlloc(GetProcessHeap(), 0, sizeof(HWND));
1266 else
1267 ci->child = HeapReAlloc(GetProcessHeap(), 0, ci->child, sizeof(HWND) * (ci->nActiveChildren + 1));
1268
1269 TRACE("Adding MDI child %p, # of children %d\n",
1271
1272 if (ci->child != NULL)
1273 {
1274 ci->child[ci->nActiveChildren] = (HWND)lParam;
1275 ci->nTotalCreated++;
1276 ci->nActiveChildren++;
1277 }
1278 }
1279 break;
1280
1281 case WM_LBUTTONDOWN:
1282 {
1283 HWND child;
1284 POINT pt;
1285 pt.x = (short)LOWORD(lParam);
1286 pt.y = (short)HIWORD(lParam);
1288
1289 TRACE("notification from %p (%li,%li)\n",child,pt.x,pt.y);
1290
1291 if (child && child != hwnd && child != ci->hwndActiveChild)
1293 break;
1294 }
1295
1296 case WM_DESTROY:
1298 }
1299 return 0;
1300
1301 case WM_SIZE:
1302 if( ci->hwndActiveChild && IsZoomed(ci->hwndActiveChild) )
1303 {
1304 RECT rect;
1305
1306 SetRect(&rect, 0, 0, LOWORD(lParam), HIWORD(lParam));
1310 rect.right - rect.left, rect.bottom - rect.top, 1 );
1311 }
1312 else
1313 MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
1314
1315 break;
1316
1318 if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
1319 {
1321 ci->sbRecalc = 0;
1322 ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1323 }
1324 return 0;
1325 }
1326 return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1328}
1329
1330/***********************************************************************
1331 * MDIClientWndProcA
1334{
1335 if (!IsWindow(hwnd)) return 0;
1337}
1338
1339/***********************************************************************
1340 * MDIClientWndProcW
1343{
1344 if (!IsWindow(hwnd)) return 0;
1346}
1347
1348/***********************************************************************
1349 * DefFrameProcA (USER32.@)
1353{
1354 if (hwndMDIClient)
1355 {
1356 switch (message)
1357 {
1358 case WM_SETTEXT:
1359 {
1361 LPWSTR text = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1362 if (text == NULL)
1363 return 0;
1366 HeapFree( GetProcessHeap(), 0, text );
1367 }
1368 return 1; /* success. FIXME: check text length */
1369
1370 case WM_COMMAND:
1371 case WM_NCACTIVATE:
1372 case WM_NEXTMENU:
1373 case WM_SETFOCUS:
1374 case WM_SIZE:
1376 }
1377 }
1379}
1380
1381
1382/***********************************************************************
1383 * DefFrameProcW (USER32.@)
1387{
1389
1390 TRACE("%p %p %04x (%s) %08Ix %08Ix\n", hwnd, hwndMDIClient, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1391
1392 if (ci)
1393 {
1394 switch (message)
1395 {
1396 case WM_COMMAND:
1397 {
1398 WORD id = LOWORD(wParam);
1399 /* check for possible syscommands for maximized MDI child */
1400 if (id < ci->idFirstChild || id >= ci->idFirstChild + ci->nActiveChildren)
1401 {
1402 if( (id - 0xf000) & 0xf00f ) break;
1403 if( !ci->hwndChildMaximized ) break;
1404 switch( id )
1405 {
1406 case SC_CLOSE:
1407 if (!is_close_enabled(ci->hwndActiveChild, 0)) break;
1408 case SC_SIZE:
1409 case SC_MOVE:
1410 case SC_MINIMIZE:
1411 case SC_MAXIMIZE:
1412 case SC_NEXTWINDOW:
1413 case SC_PREVWINDOW:
1414 case SC_RESTORE:
1416 wParam, lParam);
1417 }
1418 }
1419 else
1420 {
1421 HWND childHwnd;
1422 if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
1423 /* User chose "More Windows..." */
1425 else
1426 /* User chose one of the windows listed in the "Windows" menu */
1427 childHwnd = MDI_GetChildByID(hwndMDIClient, id, ci);
1428
1429 if( childHwnd )
1431 }
1432 }
1433 break;
1434
1435 case WM_NCACTIVATE:
1437 break;
1438
1439 case WM_SETTEXT:
1441 return 1; /* success. FIXME: check text length */
1442
1443 case WM_SETFOCUS:
1445 break;
1446
1447 case WM_SIZE:
1449 break;
1450
1451 case WM_NEXTMENU:
1452 {
1453 MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1454
1456 {
1457 /* control menu is between the frame system menu and
1458 * the first entry of menu bar */
1459 if ((wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
1460 (wParam == VK_RIGHT && NtUserGetWindowSysSubMenu( hwnd ) == next_menu->hmenuIn))
1461 {
1463 next_menu->hwndNext = ci->hwndActiveChild;
1464 }
1465 }
1466 return 0;
1467 }
1468 }
1469 }
1470
1472}
1473
1474/***********************************************************************
1475 * DefMDIChildProcA (USER32.@)
1479{
1482
1483 TRACE("%p %04x (%s) %08Ix %08Ix\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1484
1486 if (!ci) return DefWindowProcA( hwnd, message, wParam, lParam );
1487
1488 switch (message)
1489 {
1490 case WM_SETTEXT:
1492 if( ci->hwndChildMaximized == hwnd )
1494 MDI_RefreshMenu( ci );
1495 return 1; /* success. FIXME: check text length */
1496
1497 case WM_GETMINMAXINFO:
1498 case WM_MENUCHAR:
1499 case WM_CLOSE:
1500 case WM_SETFOCUS:
1501 case WM_CHILDACTIVATE:
1502 case WM_SYSCOMMAND:
1503 case WM_SHOWWINDOW:
1504 case WM_SETVISIBLE:
1505 case WM_SIZE:
1506 case WM_NEXTMENU:
1507 case WM_SYSCHAR:
1508 case WM_DESTROY:
1510 }
1512}
1513
1514
1515/***********************************************************************
1516 * DefMDIChildProcW (USER32.@)
1520{
1523
1524 TRACE("%p %04x (%s) %08Ix %08Ix\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1525
1527 if (!ci) return DefWindowProcW( hwnd, message, wParam, lParam );
1528
1529 switch (message)
1530 {
1531 case WM_SETTEXT:
1533 if( ci->hwndChildMaximized == hwnd )
1535 MDI_RefreshMenu( ci );
1536 return 1; /* success. FIXME: check text length */
1537
1538 case WM_GETMINMAXINFO:
1540 return 0;
1541
1542 case WM_MENUCHAR:
1543 return MAKELRESULT( 0, MNC_CLOSE ); /* MDI children don't have menu bars */
1544
1545 case WM_CLOSE:
1547 return 0;
1548
1549 case WM_SETFOCUS:
1550 if (ci->hwndActiveChild != hwnd)
1552 break;
1553
1554 case WM_CHILDACTIVATE:
1555 if (IsWindowEnabled( hwnd ))
1557 return 0;
1558
1559 case WM_SYSCOMMAND:
1560 switch (wParam & 0xfff0)
1561 {
1562 case SC_MOVE:
1563 if( ci->hwndChildMaximized == hwnd )
1564 return 0;
1565 break;
1566 case SC_RESTORE:
1567 case SC_MINIMIZE:
1568 break;
1569 case SC_MAXIMIZE:
1570 if (ci->hwndChildMaximized == hwnd)
1572 break;
1573 case SC_NEXTWINDOW:
1575 return 0;
1576 case SC_PREVWINDOW:
1578 return 0;
1579 }
1580 break;
1581
1582 case WM_SHOWWINDOW:
1583 case WM_SETVISIBLE:
1585 /*if (ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1586 else*/ MDI_PostUpdate(client, ci, SB_BOTH+1);
1587 break;
1588
1589 case WM_SIZE:
1590 /* This is the only place where we switch to/from maximized state */
1591 /* do not change */
1592 TRACE("current active %p, maximized %p\n", ci->hwndActiveChild, ci->hwndChildMaximized);
1593
1594 if( ci->hwndChildMaximized == hwnd && wParam != SIZE_MAXIMIZED )
1595 {
1596 HWND frame;
1597
1598 ci->hwndChildMaximized = 0;
1599
1600 frame = GetParent(client);
1601 MDI_RestoreFrameMenu( frame, hwnd, ci->hBmpClose );
1602 MDI_UpdateFrameText( frame, client, TRUE, NULL );
1603 }
1604
1605 if( wParam == SIZE_MAXIMIZED )
1606 {
1607 HWND frame, hMaxChild = ci->hwndChildMaximized;
1608
1609 if( hMaxChild == hwnd ) break;
1610
1611 if( hMaxChild)
1612 {
1613 SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
1614
1615 MDI_RestoreFrameMenu( GetParent(client), hMaxChild, ci->hBmpClose );
1616 NtUserShowWindow( hMaxChild, SW_SHOWNOACTIVATE );
1617
1618 SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
1619 }
1620
1621 TRACE("maximizing child %p\n", hwnd );
1622
1623 /* keep track of the maximized window. */
1624 ci->hwndChildMaximized = hwnd; /* !!! */
1625
1626 frame = GetParent(client);
1627 MDI_AugmentFrameMenu( frame, hwnd );
1628 MDI_UpdateFrameText( frame, client, TRUE, NULL );
1629 }
1630
1631 if( wParam == SIZE_MINIMIZED )
1632 {
1633 HWND switchTo = MDI_GetWindow( ci, hwnd, TRUE, WS_MINIMIZE );
1634
1635 if (!switchTo) switchTo = hwnd;
1636 SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0 );
1637 }
1638
1640 break;
1641
1642 case WM_NEXTMENU:
1643 {
1644 MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1646
1647 if( wParam == VK_LEFT ) /* switch to frame system menu */
1648 {
1650 }
1651 if( wParam == VK_RIGHT ) /* to frame menu bar */
1652 {
1653 next_menu->hmenuNext = GetMenu(parent);
1654 }
1655 next_menu->hwndNext = parent;
1656 return 0;
1657 }
1658
1659 case WM_SYSCHAR:
1660 if (wParam == '-')
1661 {
1663 return 0;
1664 }
1665 break;
1666
1667 case WM_DESTROY:
1668 /* Remove itself from the Window menu */
1669 MDI_RefreshMenu(ci);
1670 break;
1671 }
1673}
1674
1675/**********************************************************************
1676 * CreateMDIWindowA (USER32.@) Creates a MDI child
1677 *
1678 * RETURNS
1679 * Success: Handle to created window
1680 * Failure: NULL
1683 LPCSTR lpClassName, /* [in] Pointer to registered child class name */
1684 LPCSTR lpWindowName, /* [in] Pointer to window name */
1685 DWORD dwStyle, /* [in] Window style */
1686 INT X, /* [in] Horizontal position of window */
1687 INT Y, /* [in] Vertical position of window */
1688 INT nWidth, /* [in] Width of window */
1689 INT nHeight, /* [in] Height of window */
1690 HWND hWndParent, /* [in] Handle to parent window */
1691 HINSTANCE hInstance, /* [in] Handle to application instance */
1692 LPARAM lParam) /* [in] Application-defined value */
1693{
1694 TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08Ix)\n",
1695 debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
1696 nWidth,nHeight,hWndParent,hInstance,lParam);
1697
1698 return CreateWindowExA(WS_EX_MDICHILD, lpClassName, lpWindowName,
1699 dwStyle, X, Y, nWidth, nHeight, hWndParent,
1700 0, hInstance, (LPVOID)lParam);
1701}
1702
1703/***********************************************************************
1704 * CreateMDIWindowW (USER32.@) Creates a MDI child
1705 *
1706 * RETURNS
1707 * Success: Handle to created window
1708 * Failure: NULL
1711 LPCWSTR lpClassName, /* [in] Pointer to registered child class name */
1712 LPCWSTR lpWindowName, /* [in] Pointer to window name */
1713 DWORD dwStyle, /* [in] Window style */
1714 INT X, /* [in] Horizontal position of window */
1715 INT Y, /* [in] Vertical position of window */
1716 INT nWidth, /* [in] Width of window */
1717 INT nHeight, /* [in] Height of window */
1718 HWND hWndParent, /* [in] Handle to parent window */
1719 HINSTANCE hInstance, /* [in] Handle to application instance */
1720 LPARAM lParam) /* [in] Application-defined value */
1721{
1722 TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08Ix)\n",
1723 debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
1724 nWidth, nHeight, hWndParent, hInstance, lParam);
1725
1726 return CreateWindowExW(WS_EX_MDICHILD, lpClassName, lpWindowName,
1727 dwStyle, X, Y, nWidth, nHeight, hWndParent,
1728 0, hInstance, (LPVOID)lParam);
1729}
1730
1731/**********************************************************************
1732 * TranslateMDISysAccel (USER32.@)
1735{
1736 if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
1737 {
1738 MDICLIENTINFO *ci = get_client_info( hwndClient );
1739 WPARAM wParam = 0;
1740
1741 if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
1742
1743 /* translate if the Ctrl key is down and Alt not. */
1744
1745 if( (NtUserGetKeyState(VK_CONTROL) & 0x8000) && !(NtUserGetKeyState(VK_MENU) & 0x8000))
1746 {
1747 switch( msg->wParam )
1748 {
1749 case VK_F6:
1750 case VK_TAB:
1752 break;
1753 case VK_F4:
1754 case VK_RBUTTON:
1756 {
1757 wParam = SC_CLOSE;
1758 break;
1759 }
1760 /* fall through */
1761 default:
1762 return FALSE;
1763 }
1764 TRACE("wParam = %04Ix\n", wParam);
1766 return TRUE;
1767 }
1768 }
1769 return FALSE; /* failure */
1770}
1771
1772/***********************************************************************
1773 * CalcChildScroll (USER32.@)
1775void WINAPI CalcChildScroll( HWND hwnd, INT scroll )
1776{
1777#ifndef __REACTOS__ /* not implemented */
1779#endif
1781 RECT childRect, clientRect;
1782 HWND *list;
1783 DWORD style;
1784#ifdef __REACTOS__
1785 WINDOWINFO WindowInfo;
1786#endif
1787
1788#ifndef __REACTOS__ /* not implemented */
1789 context = SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( hwnd ));
1790#endif
1791
1792 GetClientRect( hwnd, &clientRect );
1793 SetRectEmpty( &childRect );
1794
1795#ifdef __REACTOS__
1796 /* The rectangle returned by GetClientRect always has 0,0 as top left
1797 * because it is in client coordinates. The rectangles returned by
1798 * GetWindowRect are in screen coordinates to make this complicated.
1799 *
1800 * Apparently (in ReactOS at least) the rcClient returned by GetWindowInfo
1801 * is in screen coordinates too.
1802 */
1803 WindowInfo.cbSize = sizeof(WindowInfo);
1804 if (!GetWindowInfo(hwnd, &WindowInfo))
1805 {
1806 ERR("Can't get window info\n");
1807 return;
1808 }
1809#endif
1810
1811 TRACE("CalcChildScroll 1\n");
1812 if ((list = WIN_ListChildren( hwnd )))
1813 {
1814 int i;
1815 for (i = 0; list[i]; i++)
1816 {
1818 if (style & WS_MAXIMIZE)
1819 {
1820 HeapFree( GetProcessHeap(), 0, list );
1822 ERR("CalcChildScroll 2\n");
1823 goto done;
1824 }
1825 if (style & WS_VISIBLE)
1826 {
1827 RECT rect;
1828#ifdef __REACTOS__
1829 GetWindowRect( list[i], &rect );
1830 OffsetRect(&rect, -WindowInfo.rcClient.left,
1831 -WindowInfo.rcClient.top);
1832#else
1833 NtUserGetChildRect( list[i], &rect );
1834#endif
1835 UnionRect( &childRect, &rect, &childRect );
1836 }
1837 }
1838 HeapFree( GetProcessHeap(), 0, list );
1839 }
1840 UnionRect( &childRect, &clientRect, &childRect );
1841 TRACE("CalcChildScroll 3\n");
1842 /* set common info values */
1843 info.cbSize = sizeof(info);
1844 info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
1845 info.nPos = 0;
1846
1847 /* set the specific values and apply but only if window style allows */
1848 /* Note how we set nPos to 0 because we scroll the clients instead of
1849 * the window, and we set nPage to 1 bigger than the clientRect because
1850 * otherwise the scrollbar never disables. This causes a somewhat ugly
1851 * effect though while scrolling.
1852 */
1854 switch( scroll )
1855 {
1856 case SB_BOTH:
1857 case SB_HORZ:
1858 if (style & (WS_HSCROLL | WS_VSCROLL))
1859 {
1860 info.nMin = childRect.left;
1861#ifdef __REACTOS__
1862 info.nMax = childRect.right;
1863 info.nPage = 1 + clientRect.right - clientRect.left;
1865#else
1866 info.nMax = childRect.right - clientRect.right;
1867 info.nPos = clientRect.left - childRect.left;
1869#endif
1870 }
1871 if (scroll == SB_HORZ) break;
1872 /* fall through */
1873 case SB_VERT:
1874 if (style & (WS_HSCROLL | WS_VSCROLL))
1875 {
1876 info.nMin = childRect.top;
1877#ifdef __REACTOS__
1878 info.nMax = childRect.bottom;
1879 info.nPage = 1 + clientRect.bottom - clientRect.top;
1881#else
1882 info.nMax = childRect.bottom - clientRect.bottom;
1883 info.nPos = clientRect.top - childRect.top;
1885#endif
1886 }
1887 break;
1888 }
1889
1890done:
1891#ifndef __REACTOS__ /* not implemented */
1892 SetThreadDpiAwarenessContext( context );
1893#else
1894 return;
1895#endif
1896}
1897
1898
1899/***********************************************************************
1900 * ScrollChildren (USER32.@)
1903 LPARAM lParam)
1904{
1905#ifndef __REACTOS__ /* not implemented */
1907#endif
1908 INT newPos = -1;
1909 INT curPos, length, minPos, maxPos, shift;
1910 RECT rect;
1911
1912#ifndef __REACTOS__ /* not implemented */
1913 context = SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( hWnd ));
1914#endif
1915 GetClientRect( hWnd, &rect );
1916
1917 switch(uMsg)
1918 {
1919 case WM_HSCROLL:
1920 GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
1921 curPos = GetScrollPos(hWnd,SB_HORZ);
1922 length = (rect.right - rect.left) / 2;
1924 break;
1925 case WM_VSCROLL:
1926 GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
1927 curPos = GetScrollPos(hWnd,SB_VERT);
1928 length = (rect.bottom - rect.top) / 2;
1930 break;
1931 default:
1932 goto done;
1933 }
1934
1935 switch( wParam )
1936 {
1937 case SB_LINEUP:
1938 newPos = curPos - shift;
1939 break;
1940 case SB_LINEDOWN:
1941 newPos = curPos + shift;
1942 break;
1943 case SB_PAGEUP:
1944 newPos = curPos - length;
1945 break;
1946 case SB_PAGEDOWN:
1947 newPos = curPos + length;
1948 break;
1949
1950 case SB_THUMBPOSITION:
1951 newPos = LOWORD(lParam);
1952 break;
1953
1954 case SB_THUMBTRACK:
1955 goto done;
1956
1957 case SB_TOP:
1958 newPos = minPos;
1959 break;
1960 case SB_BOTTOM:
1961 newPos = maxPos;
1962 break;
1963 case SB_ENDSCROLL:
1965 goto done;
1966 }
1967
1968 if( newPos > maxPos )
1969 newPos = maxPos;
1970 else
1971 if( newPos < minPos )
1972 newPos = minPos;
1973
1974 SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
1975
1976 if( uMsg == WM_VSCROLL )
1977 NtUserScrollWindowEx( hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
1979 else
1980 NtUserScrollWindowEx( hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
1982done:
1983#ifndef __REACTOS__ /* not implemented */
1984 SetThreadDpiAwarenessContext( context );
1985#else
1986 return;
1987#endif
1988}
1989
1990#ifdef __REACTOS__
1991/******************************************************************************
1992 * CascadeWindows (USER32.@) Cascades MDI child windows
1993 *
1994 * RETURNS
1995 * Success: Number of cascaded windows.
1996 * Failure: 0
1997 */
1998
1999typedef struct CASCADE_INFO
2000{
2001 HWND hwndTop;
2002 UINT wFlags;
2004 HWND hwndDesktop;
2005 HWND hTrayWnd;
2006 HWND hwndProgman;
2007 HWND *ahwnd;
2008 DWORD chwnd;
2009} CASCADE_INFO;
2010
2011static BOOL CALLBACK
2012GetCascadeChildProc(HWND hwnd, LPARAM lParam)
2013{
2014 DWORD count, size;
2015 HWND *ahwnd;
2016 CASCADE_INFO *pInfo = (CASCADE_INFO *)lParam;
2017
2018 if (hwnd == pInfo->hwndDesktop || hwnd == pInfo->hTrayWnd ||
2019 hwnd == pInfo->hwndProgman || hwnd == pInfo->hwndTop)
2020 {
2021 return TRUE;
2022 }
2023
2024 if (pInfo->hwndParent && GetParent(hwnd) != pInfo->hwndParent)
2025 return TRUE;
2026
2027 if ((pInfo->wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2028 return TRUE;
2029
2031 return TRUE;
2032
2033 count = pInfo->chwnd;
2034 size = (count + 1) * sizeof(HWND);
2035
2036 if (count == 0 || pInfo->ahwnd == NULL)
2037 {
2038 count = 0;
2039 pInfo->ahwnd = (HWND *)HeapAlloc(GetProcessHeap(), 0, size);
2040 }
2041 else
2042 {
2043 ahwnd = (HWND *)HeapReAlloc(GetProcessHeap(), 0, pInfo->ahwnd, size);
2044 if (ahwnd == NULL)
2045 {
2046 HeapFree(GetProcessHeap(), 0, pInfo->ahwnd);
2047 }
2048 pInfo->ahwnd = ahwnd;
2049 }
2050
2051 if (pInfo->ahwnd == NULL)
2052 {
2053 pInfo->chwnd = 0;
2054 return FALSE;
2055 }
2056
2057 pInfo->ahwnd[count] = hwnd;
2058 pInfo->chwnd = count + 1;
2059 return TRUE;
2060}
2061
2062static BOOL
2063QuerySizeFix(HWND hwnd, LPINT pcx, LPINT pcy)
2064{
2065 MINMAXINFO mmi;
2066 DWORD_PTR dwResult;
2067
2068 mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 0;
2071 SMTO_ABORTIFHUNG | SMTO_NORMAL, 1000, &dwResult))
2072 {
2073 *pcx = min(max(*pcx, mmi.ptMinTrackSize.x), mmi.ptMaxTrackSize.x);
2074 *pcy = min(max(*pcy, mmi.ptMinTrackSize.y), mmi.ptMaxTrackSize.y);
2075 return TRUE;
2076 }
2077 return FALSE;
2078}
2079
2082 UINT cKids, const HWND *lpKids)
2083{
2084 CASCADE_INFO info;
2085 HWND hwnd, hwndTop, hwndPrev;
2086 HMONITOR hMon;
2088 RECT rcWork, rcWnd;
2089 DWORD i, ret = 0;
2090 INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, dx, dy;
2091 HDWP hDWP;
2092 POINT pt;
2093
2094 TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2095
2096 hwndTop = GetTopWindow(hwndParent);
2097
2098 ZeroMemory(&info, sizeof(info));
2099 info.hwndDesktop = GetDesktopWindow();
2100 info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2101 info.hwndProgman = FindWindowW(L"Progman", NULL);
2102 info.hwndParent = hwndParent;
2103 info.wFlags = wFlags;
2104
2105 if (cKids == 0 || lpKids == NULL)
2106 {
2107 info.hwndTop = hwndTop;
2108 EnumChildWindows(hwndParent, GetCascadeChildProc, (LPARAM)&info);
2109
2110 info.hwndTop = NULL;
2111 GetCascadeChildProc(hwndTop, (LPARAM)&info);
2112 }
2113 else
2114 {
2115 info.chwnd = cKids;
2116 info.ahwnd = (HWND *)lpKids;
2117 }
2118
2119 if (info.chwnd == 0 || info.ahwnd == NULL)
2120 return ret;
2121
2122 if (lpRect)
2123 {
2124 rcWork = *lpRect;
2125 }
2126 else if (hwndParent)
2127 {
2128 GetClientRect(hwndParent, &rcWork);
2129 }
2130 else
2131 {
2132 pt.x = pt.y = 0;
2133 hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2134 mi.cbSize = sizeof(mi);
2135 GetMonitorInfoW(hMon, &mi);
2136 rcWork = mi.rcWork;
2137 }
2138
2139 hDWP = BeginDeferWindowPos(info.chwnd);
2140 if (hDWP == NULL)
2141 goto cleanup;
2142
2143 x = rcWork.left;
2144 y = rcWork.top;
2147 cxWork = rcWork.right - rcWork.left;
2148 cyWork = rcWork.bottom - rcWork.top;
2149 hwndPrev = NULL;
2150 for (i = info.chwnd; i > 0;) /* in reverse order */
2151 {
2152 --i;
2153 hwnd = info.ahwnd[i];
2154
2156 continue;
2157
2158 if ((info.wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2159 continue;
2160
2161 if (IsZoomed(hwnd))
2163
2164 GetWindowRect(hwnd, &rcWnd);
2165 cxNew = cx = rcWnd.right - rcWnd.left;
2166 cyNew = cy = rcWnd.bottom - rcWnd.top;
2167
2168 /* if we can change the window size and it is not only one */
2169 if (info.chwnd != 1 && (GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_THICKFRAME))
2170 {
2171 /* check the size */
2172#define MIN_THRESHOLD(xy) (((xy) * 4) / 7) /* in the rate 4/7 */
2173#define MAX_THRESHOLD(xy) (((xy) * 5) / 7) /* in the rate 5/7 */
2174 cxNew = max(min(cxNew, MAX_THRESHOLD(cxWork)), MIN_THRESHOLD(cxWork));
2175 cyNew = max(min(cyNew, MAX_THRESHOLD(cyWork)), MIN_THRESHOLD(cyWork));
2176#undef MIN_THRESHOLD
2177#undef MAX_THRESHOLD
2178 if (cx != cxNew || cy != cyNew)
2179 {
2180 /* too large. shrink if we can */
2181 if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2182 {
2183 cx = cxNew;
2184 cy = cyNew;
2185 }
2186 }
2187 }
2188
2189 if (x + cx > rcWork.right)
2190 x = rcWork.left;
2191 if (y + cy > rcWork.bottom)
2192 y = rcWork.top;
2193
2194 hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2195 if (hDWP == NULL)
2196 {
2197 ret = 0;
2198 goto cleanup;
2199 }
2200
2201 x += dx;
2202 y += dy;
2203 hwndPrev = hwnd;
2204 ++ret;
2205 }
2206
2208
2209 if (hwndPrev)
2210 SetForegroundWindow(hwndPrev);
2211
2212cleanup:
2213 if (cKids == 0 || lpKids == NULL)
2214 HeapFree(GetProcessHeap(), 0, info.ahwnd);
2215
2216 return (WORD)ret;
2217}
2218
2219
2220/***********************************************************************
2221 * CascadeChildWindows (USER32.@)
2222 */
2223WORD WINAPI CascadeChildWindows( HWND parent, UINT flags )
2224{
2225 return CascadeWindows( parent, flags, NULL, 0, NULL );
2226}
2227
2228
2229/******************************************************************************
2230 * TileWindows (USER32.@) Tiles MDI child windows
2231 *
2232 * RETURNS
2233 * Success: Number of tiled windows.
2234 * Failure: 0
2235 */
2238 UINT cKids, const HWND *lpKids)
2239{
2240 HWND hwnd, hwndTop, hwndPrev;
2241 CASCADE_INFO info;
2242 RECT rcWork, rcWnd;
2243 DWORD i, iRow, iColumn, cRows, cColumns, ret = 0;
2244 INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, cxCell, cyCell, cxMin2, cyMin3;
2245 HDWP hDWP;
2247 HMONITOR hMon;
2248 POINT pt;
2249
2250 TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2251
2252 hwndTop = GetTopWindow(hwndParent);
2253
2254 ZeroMemory(&info, sizeof(info));
2255 info.hwndDesktop = GetDesktopWindow();
2256 info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2257 info.hwndProgman = FindWindowW(L"Progman", NULL);
2258 info.hwndParent = hwndParent;
2259 info.wFlags = wFlags;
2260
2261 if (cKids == 0 || lpKids == NULL)
2262 {
2263 info.hwndTop = hwndTop;
2264 EnumChildWindows(hwndParent, GetCascadeChildProc, (LPARAM)&info);
2265
2266 info.hwndTop = NULL;
2267 GetCascadeChildProc(hwndTop, (LPARAM)&info);
2268 }
2269 else
2270 {
2271 info.chwnd = cKids;
2272 info.ahwnd = (HWND *)lpKids;
2273 }
2274
2275 if (info.chwnd == 0 || info.ahwnd == NULL)
2276 return ret;
2277
2278 if (lpRect)
2279 {
2280 rcWork = *lpRect;
2281 }
2282 else if (hwndParent)
2283 {
2284 GetClientRect(hwndParent, &rcWork);
2285 }
2286 else
2287 {
2288 pt.x = pt.y = 0;
2289 hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2290 mi.cbSize = sizeof(mi);
2291 GetMonitorInfoW(hMon, &mi);
2292 rcWork = mi.rcWork;
2293 }
2294
2295 cxWork = rcWork.right - rcWork.left;
2296 cyWork = rcWork.bottom - rcWork.top;
2297
2298 cxMin2 = GetSystemMetrics(SM_CXMIN) * 2;
2299 cyMin3 = GetSystemMetrics(SM_CYMIN) * 3;
2300
2301 /* calculate the numbers and widths of columns and rows */
2302 if (info.wFlags & MDITILE_HORIZONTAL)
2303 {
2304 cColumns = info.chwnd;
2305 cRows = 1;
2306 for (;;)
2307 {
2308 cxCell = cxWork / cColumns;
2309 cyCell = cyWork / cRows;
2310 if (cyCell <= cyMin3 || cxCell >= cxMin2)
2311 break;
2312
2313 ++cRows;
2314 cColumns = (info.chwnd + cRows - 1) / cRows;
2315 }
2316 }
2317 else
2318 {
2319 cRows = info.chwnd;
2320 cColumns = 1;
2321 for (;;)
2322 {
2323 cxCell = cxWork / cColumns;
2324 cyCell = cyWork / cRows;
2325 if (cxCell <= cxMin2 || cyCell >= cyMin3)
2326 break;
2327
2328 ++cColumns;
2329 cRows = (info.chwnd + cColumns - 1) / cColumns;
2330 }
2331 }
2332
2333 hDWP = BeginDeferWindowPos(info.chwnd);
2334 if (hDWP == NULL)
2335 goto cleanup;
2336
2337 x = rcWork.left;
2338 y = rcWork.top;
2339 hwndPrev = NULL;
2340 iRow = iColumn = 0;
2341 for (i = info.chwnd; i > 0;) /* in reverse order */
2342 {
2343 --i;
2344 hwnd = info.ahwnd[i];
2345
2346 if (IsZoomed(hwnd))
2348
2349 GetWindowRect(hwnd, &rcWnd);
2350 cx = rcWnd.right - rcWnd.left;
2351 cy = rcWnd.bottom - rcWnd.top;
2352
2353 /* if we can change the window size */
2355 {
2356 cxNew = cxCell;
2357 cyNew = cyCell;
2358 /* shrink if we can */
2359 if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2360 {
2361 cx = cxNew;
2362 cy = cyNew;
2363 }
2364 }
2365
2366 hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2367 if (hDWP == NULL)
2368 {
2369 ret = 0;
2370 goto cleanup;
2371 }
2372
2373 if (info.wFlags & MDITILE_HORIZONTAL)
2374 {
2375 x += cxCell;
2376 ++iColumn;
2377 if (iColumn >= cColumns)
2378 {
2379 iColumn = 0;
2380 ++iRow;
2381 x = rcWork.left;
2382 y += cyCell;
2383 }
2384 }
2385 else
2386 {
2387 y += cyCell;
2388 ++iRow;
2389 if (iRow >= cRows)
2390 {
2391 iRow = 0;
2392 ++iColumn;
2393 x += cxCell;
2394 y = rcWork.top;
2395 }
2396 }
2397 hwndPrev = hwnd;
2398 ++ret;
2399 }
2400
2402
2403 if (hwndPrev)
2404 SetForegroundWindow(hwndPrev);
2405
2406cleanup:
2407 if (cKids == 0 || lpKids == NULL)
2408 HeapFree(GetProcessHeap(), 0, info.ahwnd);
2409
2410 return (WORD)ret;
2411}
2412
2413
2414/***********************************************************************
2415 * TileChildWindows (USER32.@)
2416 */
2417WORD WINAPI TileChildWindows( HWND parent, UINT flags )
2418{
2419 return TileWindows( parent, flags, NULL, 0, NULL );
2420}
2421#endif
2422
2423/************************************************************************
2424 * "More Windows..." functionality
2425 */
2426
2427/* MDI_MoreWindowsDlgProc
2428 *
2429 * This function will process the messages sent to the "More Windows..."
2430 * dialog.
2431 * Return values: 0 = cancel pressed
2432 * HWND = ok pressed or double-click in the list...
2433 *
2434 */
2437{
2438 switch (iMsg)
2439 {
2440 case WM_INITDIALOG:
2441 {
2442 UINT widest = 0;
2443 UINT length;
2444 UINT i;
2447
2448 for (i = 0; i < ci->nActiveChildren; i++)
2449 {
2451
2453 continue;
2456 length = lstrlenW(buffer); /* FIXME: should use GetTextExtentPoint */
2457 if (length > widest)
2458 widest = length;
2459 }
2460 /* Make sure the horizontal scrollbar scrolls ok */
2462
2463 /* Set the current selection */
2465 return TRUE;
2466 }
2467
2468 case WM_COMMAND:
2469 switch (LOWORD(wParam))
2470 {
2471 default:
2472 if (HIWORD(wParam) != LBN_DBLCLK) break;
2473 /* fall through */
2474 case IDOK:
2475 {
2476 /* windows are sorted by menu ID, so we must return the
2477 * window associated to the given id
2478 */
2482 EndDialog(hDlg, res);
2483 return TRUE;
2484 }
2485 case IDCANCEL:
2486 EndDialog(hDlg, 0);
2487 return TRUE;
2488 }
2489 break;
2490 }
2491 return FALSE;
2492}
2493
2494/*
2495 *
2496 * MDI_MoreWindowsDialog
2497 *
2498 * Prompts the user with a listbox containing the opened
2499 * documents. The user can then choose a windows and click
2500 * on OK to set the current window to the one selected, or
2501 * CANCEL to cancel. The function returns a handle to the
2502 * selected window.
2503 */
2506{
2507 LPCVOID template;
2508 HRSRC hRes;
2509 HANDLE hDlgTmpl;
2510
2511 hRes = FindResourceA(User32Instance, "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
2512
2513 if (hRes == 0)
2514 return 0;
2515
2516 hDlgTmpl = LoadResource(User32Instance, hRes );
2517
2518 if (hDlgTmpl == 0)
2519 return 0;
2520
2521 template = LockResource( hDlgTmpl );
2522
2523 if (template == 0)
2524 return 0;
2525
2526 return (HWND) DialogBoxIndirectParamA(User32Instance, template, hwnd,
2528}
static int state
Definition: maze.c:121
int nItems
Definition: appswitch.c:55
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
HWND hwndMDIClient
Definition: mmc.c:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
HINSTANCE hInstance
Definition: charmap.c:19
Definition: list.h:39
RECT rect
Definition: combotst.c:67
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static HWND hwndParent
Definition: cryptui.c:299
TCHAR lpTitle[80]
Definition: ctm.c:69
#define DC_ACTIVE
Definition: dc21x4.h:120
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static HBITMAP hBitmap
Definition: timezone.c:26
#define Y(I)
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
HANDLE HWND
Definition: compat.h:19
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
const WCHAR * text
Definition: package.c:1826
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define pt(x, y)
Definition: drawing.c:79
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Height *Stride) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Stride)
Definition: common.c:42
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
r reserved
Definition: btrfs.c:3006
HWND hListBox
Definition: enumfonts.cpp:27
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
size_t total
Status
Definition: gdiplustypes.h:24
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
#define cs
Definition: i386-dis.c:442
struct _MDIWND MDIWND
BOOL NTAPI NtUserSetMenu(HWND hWnd, HMENU hMenu, BOOL bRepaint)
Definition: menu.c:6424
BOOL NTAPI NtUserDrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags, BOOL bMetaHDC, PVOID pDIXData)
Definition: cursoricon.c:2086
BOOL NTAPI NtUserSetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
Definition: winpos.c:3573
DWORD NTAPI NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *rect, const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags)
Definition: scrollex.c:571
#define FNID_DESTROY
Definition: ntuser.h:905
INT NTAPI NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
Definition: window.c:4592
DWORD NTAPI NtUserCheckMenuItem(HMENU hmenu, UINT uIDCheckItem, UINT uCheck)
Definition: menu.c:5609
HWND NTAPI NtUserSetFocus(HWND hWnd)
Definition: focus.c:1717
DWORD NTAPI NtUserSetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:1344
HMENU NTAPI NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
Definition: menu.c:5685
DWORD_PTR NTAPI NtUserCallTwoParam(DWORD_PTR Param1, DWORD_PTR Param2, DWORD Routine)
Definition: simplecall.c:460
BOOL NTAPI NtUserMoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint)
Definition: winpos.c:3536
BOOLEAN NTAPI NtUserDestroyWindow(HWND Wnd)
Definition: window.c:3041
@ TWOPARAM_ROUTINE_REDRAWTITLE
Definition: ntuser.h:1663
BOOL NTAPI NtUserSetMenuDefaultItem(HMENU hMenu, UINT uItem, UINT fByPos)
Definition: menu.c:6492
UINT NTAPI NtUserEnableMenuItem(HMENU hMenu, UINT uIDEnableItem, UINT uEnable)
Definition: menu.c:5872
#define GWLP_MDIWND
Definition: ntuser.h:790
BOOL NTAPI NtUserDeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags)
Definition: menu.c:5635
BOOL NTAPI NtUserDestroyMenu(HMENU hMenu)
Definition: menu.c:5842
SHORT NTAPI NtUserGetKeyState(INT VirtKey)
Definition: msgqueue.c:2573
BOOL NTAPI NtUserShowWindow(HWND hWnd, LONG nCmdShow)
Definition: winpos.c:3861
NTSTATUS NTAPI NtUserBuildHwndList(HDESK hDesktop, HWND hwndParent, BOOLEAN bChildren, ULONG dwThreadId, ULONG cHwnd, HWND *phwndList, ULONG *pcHwndNeeded)
Definition: window.c:1515
BOOL NTAPI NtUserRemoveMenu(HMENU hMenu, UINT uPosition, UINT uFlags)
Definition: menu.c:6398
DWORD NTAPI NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
Definition: scrollbar.c:1383
BOOL NTAPI NtUserSetWindowFNID(HWND hWnd, WORD fnID)
Definition: window.c:4335
BOOL NTAPI NtUserEndDeferWindowPosEx(HDWP WinPosInfo, BOOL bAsync)
Definition: winpos.c:3313
HDC NTAPI NtUserGetDC(HWND hWnd)
Definition: windc.c:1014
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ZeroMemory
Definition: minwinbase.h:31
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
int * LPINT
Definition: minwindef.h:151
CONST void * LPCVOID
Definition: minwindef.h:164
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static HTREEITEM hChild
Definition: treeview.c:383
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
static HWND child
Definition: cursoricon.c:298
#define menu
Definition: input.c:3282
#define shift
Definition: input.c:3280
static DPI_AWARENESS_CONTEXT
Definition: sysparams.c:52
static MONITORINFO mi
Definition: win.c:9400
#define min(a, b)
Definition: monoChain.cc:55
HICON hIcon
Definition: msconfig.c:44
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HMONITOR WINAPI MonitorFromPoint(POINT, DWORD)
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
#define LOWORD(l)
Definition: pedump.c:82
#define WS_SIZEBOX
Definition: pedump.c:642
#define WS_MAXIMIZEBOX
Definition: pedump.c:632
#define WS_MAXIMIZE
Definition: pedump.c:623
short WCHAR
Definition: pedump.c:58
#define WS_VSCROLL
Definition: pedump.c:627
#define WS_MINIMIZE
Definition: pedump.c:622
#define WS_VISIBLE
Definition: pedump.c:620
#define RT_DIALOG
Definition: pedump.c:367
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define WS_HSCROLL
Definition: pedump.c:628
#define WS_THICKFRAME
Definition: pedump.c:630
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define SW_SHOWNORMAL
Definition: winuser.h:781
HWND WINAPI ChildWindowFromPoint(_In_ HWND, _In_ POINT)
#define GW_OWNER
Definition: winuser.h:777
#define WM_MDITILE
Definition: winuser.h:1846
#define WM_MDISETMENU
Definition: winuser.h:1850
BOOL WINAPI IsWindow(_In_opt_ HWND)
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
#define SW_HIDE
Definition: winuser.h:779
#define WM_CLOSE
Definition: winuser.h:1649
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define LB_GETITEMDATA
Definition: winuser.h:2070
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_SYSCOMMAND
Definition: winuser.h:1769
#define SB_THUMBTRACK
Definition: winuser.h:573
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define SC_KEYMENU
Definition: winuser.h:2632
#define VK_TAB
Definition: winuser.h:2235
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLL
Definition: winuser.h:1771
#define WM_NEXTMENU
Definition: winuser.h:1834
#define SWP_FRAMECHANGED
Definition: winuser.h:1251
#define GCLP_HICONSM
Definition: winuser.h:683
#define MIIM_ID
Definition: winuser.h:733
#define HBMMENU_MBAR_RESTORE
Definition: winuser.h:2674
#define COLOR_MENU
Definition: winuser.h:928
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2100
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MDICREATE
Definition: winuser.h:1840
UINT WINAPI GetMenuState(_In_ HMENU, _In_ UINT, _In_ UINT)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDCANCEL
Definition: winuser.h:842
#define IMAGE_ICON
Definition: winuser.h:212
#define WM_VSCROLL
Definition: winuser.h:1772
#define GCLP_HICON
Definition: winuser.h:682
#define SW_SCROLLCHILDREN
Definition: winuser.h:2614
#define LBN_DBLCLK
Definition: winuser.h:2107
#define WM_MDICASCADE
Definition: winuser.h:1847
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CHILDACTIVATE
Definition: winuser.h:1666
#define SIF_RANGE
Definition: winuser.h:1246
#define SM_CYSIZE
Definition: winuser.h:1003
#define WM_CREATE
Definition: winuser.h:1636
BOOL WINAPI GetWindowInfo(_In_ HWND, _Inout_ PWINDOWINFO)
#define SM_CXVSCROLL
Definition: winuser.h:972
#define SWP_DRAWFRAME
Definition: winuser.h:1250
#define SC_PREVWINDOW
Definition: winuser.h:2627
#define VK_SPACE
Definition: winuser.h:2255
#define HBMMENU_MBAR_MINIMIZE
Definition: winuser.h:2675
#define WM_SIZE
Definition: winuser.h:1639
WORD WINAPI CascadeWindows(_In_opt_ HWND hwndParent, _In_ UINT wHow, _In_opt_ CONST RECT *lpRect, _In_ UINT cKids, _In_reads_opt_(cKids) const HWND FAR *lpKids)
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define SB_VERT
Definition: winuser.h:553
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SB_BOTTOM
Definition: winuser.h:577
#define SWP_NOMOVE
Definition: winuser.h:1255
#define WM_COMMAND
Definition: winuser.h:1768
#define SW_INVALIDATE
Definition: winuser.h:2615
#define SM_CYICONSPACING
Definition: winuser.h:1013
#define MF_STRING
Definition: winuser.h:138
HWND WINAPI GetTopWindow(_In_opt_ HWND)
struct tagCREATESTRUCTA * LPCREATESTRUCTA
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define VK_RBUTTON
Definition: winuser.h:2227
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hInst, _In_ LPCWSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2572
#define IDC_ARROW
Definition: winuser.h:695
#define VK_CONTROL
Definition: winuser.h:2239
BOOL WINAPI AdjustWindowRectEx(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define SM_CYSMICON
Definition: winuser.h:1024
#define SW_SHOWNOACTIVATE
Definition: winuser.h:785
#define WM_SETFOCUS
Definition: winuser.h:1641
#define MF_CHECKED
Definition: winuser.h:132
#define SIF_PAGE
Definition: winuser.h:1244
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_MDINEXT
Definition: winuser.h:1844
#define SIZE_MINIMIZED
Definition: winuser.h:2542
BOOL WINAPI IsMenu(_In_ HMENU)
#define GetWindowLongPtrA
Definition: winuser.h:4982
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
#define WM_INITDIALOG
Definition: winuser.h:1767
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define LB_ADDSTRING
Definition: winuser.h:2060
#define WM_MDIACTIVATE
Definition: winuser.h:1842
BOOL WINAPI InsertMenuA(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
BOOL WINAPI EnumChildWindows(_In_opt_ HWND, _In_ WNDENUMPROC, _In_ LPARAM)
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
#define SM_CXSIZE
Definition: winuser.h:1002
#define VK_F6
Definition: winuser.h:2296
LRESULT WINAPI SendMessageTimeoutW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define MF_POPUP
Definition: winuser.h:136
#define IDI_WINLOGO
Definition: winuser.h:717
#define SM_CYFRAME
Definition: winuser.h:1007
#define SM_CYHSCROLL
Definition: winuser.h:973
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
BOOL WINAPI IsIconic(_In_ HWND)
#define IDOK
Definition: winuser.h:841
BOOL WINAPI GetScrollRange(_In_ HWND, _In_ int, _Out_ LPINT, _Out_ LPINT)
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define WM_NCCREATE
Definition: winuser.h:1711
#define SC_SIZE
Definition: winuser.h:2620
#define WM_MDIREFRESHMENU
Definition: winuser.h:1854
#define WM_SHOWWINDOW
Definition: winuser.h:1656
#define WM_MDIICONARRANGE
Definition: winuser.h:1848
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
BOOL WINAPI IsZoomed(_In_ HWND)
#define SC_MINIMIZE
Definition: winuser.h:2622
#define WM_SETTEXT
Definition: winuser.h:1645
#define SC_NEXTWINDOW
Definition: winuser.h:2626
#define SM_CXMIN
Definition: winuser.h:1000
#define SM_CXSMICON
Definition: winuser.h:1023
WORD WINAPI TileWindows(_In_opt_ HWND hwndParent, _In_ UINT wHow, _In_opt_ CONST RECT *lpRect, _In_ UINT cKids, _In_reads_opt_(cKids) const HWND FAR *lpKids)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define WM_NCACTIVATE
Definition: winuser.h:1716
#define WM_SYSCHAR
Definition: winuser.h:1749
#define SM_CYMIN
Definition: winuser.h:1001
#define SM_CYICON
Definition: winuser.h:984
#define HWND_TOP
Definition: winuser.h:1218
#define WS_EX_MDICHILD
Definition: winuser.h:394
BOOL WINAPI TranslateMDISysAccel(_In_ HWND, _In_ LPMSG)
#define SW_SHOWNA
Definition: winuser.h:789
#define WM_GETMINMAXINFO
Definition: winuser.h:1668
#define WM_MENUCHAR
Definition: winuser.h:1776
#define MAKELRESULT(l, h)
Definition: winuser.h:4118
#define SIZE_MAXIMIZED
Definition: winuser.h:2543
#define MF_SEPARATOR
Definition: winuser.h:137
#define WM_MDIDESTROY
Definition: winuser.h:1841
#define WM_MDIMAXIMIZE
Definition: winuser.h:1845
#define MIIM_BITMAP
Definition: winuser.h:739
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define MF_BYPOSITION
Definition: winuser.h:203
#define MFT_BITMAP
Definition: winuser.h:749
#define COLOR_APPWORKSPACE
Definition: winuser.h:936
#define SB_PAGEDOWN
Definition: winuser.h:569
#define MNC_CLOSE
Definition: winuser.h:2603
#define SB_BOTH
Definition: winuser.h:555
#define SM_CXSIZEFRAME
Definition: winuser.h:1004
#define SB_LINEDOWN
Definition: winuser.h:565
#define MF_BITMAP
Definition: winuser.h:131
#define SC_CLOSE
Definition: winuser.h:2628
#define SC_MOVE
Definition: winuser.h:2621
#define LR_SHARED
Definition: winuser.h:1111
#define VK_F4
Definition: winuser.h:2294
INT_PTR WINAPI DialogBoxIndirectParamA(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
#define HBMMENU_MBAR_CLOSE
Definition: winuser.h:2676
HWND WINAPI GetParent(_In_ HWND)
#define GetClassLongPtrW
Definition: winuser.h:4718
#define LB_SETITEMDATA
Definition: winuser.h:2101
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define SMTO_ABORTIFHUNG
Definition: winuser.h:1234
#define VK_LEFT
Definition: winuser.h:2260
struct tagCLIENTCREATESTRUCT * LPCLIENTCREATESTRUCT
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define WM_NCDESTROY
Definition: winuser.h:1712
#define VK_RIGHT
Definition: winuser.h:2262
#define SB_TOP
Definition: winuser.h:578
#define SIF_POS
Definition: winuser.h:1245
#define MDITILE_SKIPDISABLED
Definition: winuser.h:2223
#define GWLP_ID
Definition: winuser.h:871
#define SW_RESTORE
Definition: winuser.h:790
#define SW_ERASE
Definition: winuser.h:2616
#define SB_ENDSCROLL
Definition: winuser.h:574
#define LR_DEFAULTCOLOR
Definition: winuser.h:1098
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define VK_SHIFT
Definition: winuser.h:2238
HDWP WINAPI DeferWindowPos(_In_ HDWP, _In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define MDITILE_HORIZONTAL
Definition: winuser.h:2224
#define HBMMENU_MBAR_CLOSE_D
Definition: winuser.h:2677
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define WM_DESTROY
Definition: winuser.h:1637
#define LB_SETCURSEL
Definition: winuser.h:2099
#define WM_KEYDOWN
Definition: winuser.h:1743
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define MF_HELP
Definition: winuser.h:142
HWND WINAPI FindWindowW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define WM_MDIGETACTIVE
Definition: winuser.h:1849
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define WM_PARENTNOTIFY
Definition: winuser.h:1831
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2532
#define SWP_NOZORDER
Definition: winuser.h:1258
#define SW_MAXIMIZE
Definition: winuser.h:783
#define LB_GETCURSEL
Definition: winuser.h:2068
BOOL WINAPI UnionRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
#define SetWindowLongPtrW
Definition: winuser.h:5512
#define GWL_STYLE
Definition: winuser.h:863
#define SC_RESTORE
Definition: winuser.h:2634
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SM_CYCAPTION
Definition: winuser.h:974
#define SM_CYSIZEFRAME
Definition: winuser.h:1006
int WINAPI GetSystemMetrics(_In_ int)
#define CS_NOCLOSE
Definition: winuser.h:662
#define SB_PAGEUP
Definition: winuser.h:568
#define MIIM_DATA
Definition: winuser.h:737
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define MIIM_TYPE
Definition: winuser.h:736
#define GCL_STYLE
Definition: winuser.h:678
#define HWND_BOTTOM
Definition: winuser.h:1216
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HMENU WINAPI GetMenu(_In_ HWND)
#define SMTO_NORMAL
Definition: winuser.h:1236
#define SC_MAXIMIZE
Definition: winuser.h:2624
#define SB_HORZ
Definition: winuser.h:552
#define VK_MENU
Definition: winuser.h:2240
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
HDWP WINAPI BeginDeferWindowPos(_In_ int)
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define GWL_EXSTYLE
Definition: winuser.h:862
#define MF_GRAYED
Definition: winuser.h:129
#define WM_SETREDRAW
Definition: winuser.h:1644
#define SB_THUMBPOSITION
Definition: winuser.h:572
#define WM_MDIRESTORE
Definition: winuser.h:1843
#define MF_DISABLED
Definition: winuser.h:130
PFNCLIENT pfnClientA
Definition: regcontrol.c:15
PFNCLIENT pfnClientW
Definition: regcontrol.c:16
const struct builtin_class_descr MDICLIENT_builtin_class
#define list
Definition: rosglue.h:35
#define LoadStringW
Definition: utils.h:64
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:37
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR frameTitle
Definition: mdi.c:121
HWND hwndChildMaximized
Definition: mdi.c:115
UINT nTotalCreated
Definition: mdi.c:122
HBITMAP hBmpClose
Definition: mdi.c:125
UINT idFirstChild
Definition: mdi.c:120
HWND hwndActiveChild
Definition: mdi.c:116
HMENU hWindowMenu
Definition: mdi.c:119
UINT mdiFlags
Definition: mdi.c:123
HMENU hFrameMenu
Definition: mdi.c:118
HWND * child
Definition: mdi.c:117
UINT nActiveChildren
Definition: mdi.c:114
UINT sbRecalc
Definition: mdi.c:124
long y
Definition: dcommon.idl:24
long x
Definition: dcommon.idl:24
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
WNDPROC pfnMDIClientWndProc
Definition: ntuser.h:813
Definition: http.c:7783
Definition: tftpd.h:60
Definition: style.c:91
HMENU hmenuNext
Definition: winuser.h:3744
HMENU hmenuIn
Definition: winuser.h:3743
LPWSTR dwTypeData
Definition: winuser.h:3377
POINT ptMaxPosition
Definition: winuser.h:3737
POINT ptMaxSize
Definition: winuser.h:3736
POINT ptMinTrackSize
Definition: winuser.h:3738
POINT ptMaxTrackSize
Definition: winuser.h:3739
DWORD cbSize
Definition: winuser.h:3892
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
RECT rcClient
Definition: winuser.h:3876
DWORD cbSize
Definition: winuser.h:3874
#define max(a, b)
Definition: svc.c:63
PSYMCRYPT_PARALLEL_HASH_OPERATION next
HMENU hWindowMenu
Definition: taskmgr.c:26
#define MAX_THRESHOLD
Definition: tif_dirread.c:1187
#define ICON_BIG
Definition: tnclass.cpp:51
#define ICON_SMALL
Definition: tnclass.cpp:48
const char * LPCSTR
Definition: typedefs.h:52
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
#define MAXLONG
Definition: umtypes.h:116
#define WM_SETVISIBLE
Definition: undocuser.h:33
HINSTANCE User32Instance
Definition: dllmain.c:27
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2232
#define NtUserDrawMenuBar(HWND)
Definition: user_x.h:126
#define NtUserReleaseDC(HWND, HDC)
Definition: user_x.h:120
#define WIN_GetFullHandle(h)
Definition: user_x.h:108
#define NtUserSetMDIClientInfo(HWND, INFO)
Definition: user_x.h:134
#define MAKE_FNID(index)
Definition: user_x.h:143
#define NtUserGetWindowSysSubMenu(HWND)
Definition: user_x.h:128
#define NtUserArrangeIconicWindows(HWND)
Definition: user_x.h:125
#define NTUSER_WNDPROC_MDICLIENT
Definition: user_x.h:141
#define NtUserGetMDIClientInfo(HWND)
Definition: user_x.h:133
static void MDITile(HWND client, MDICLIENTINFO *ci, WPARAM wParam)
Definition: mdi.c:764
void WINAPI CalcChildScroll(HWND hwnd, INT scroll)
Definition: mdi.c:1774
HWND WINAPI CreateMDIWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, INT X, INT Y, INT nWidth, INT nHeight, HWND hWndParent, HINSTANCE hInstance, LPARAM lParam)
Definition: mdi.c:1709
LRESULT WINAPI DefMDIChildProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1476
#define IDS_MDI_MOREWINDOWS
Definition: mdi.c:95
#define MDI_MOREWINDOWSLIMIT
Definition: mdi.c:93
static LRESULT MDI_RefreshMenu(MDICLIENTINFO *)
Definition: mdi.c:392
static LRESULT MDISetMenu(HWND hwnd, HMENU hmenuFrame, HMENU hmenuWindow)
Definition: mdi.c:312
HWND * WIN_ListChildren(HWND hWndparent)
Definition: mdi.c:139
static void MDI_SwitchActiveChild(MDICLIENTINFO *ci, HWND hwndTo, BOOL activate)
Definition: mdi.c:518
LRESULT WINAPI MDIClientWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1341
static BOOL MDI_RestoreFrameMenu(HWND, HWND, HBITMAP)
Definition: mdi.c:951
#define MDIF_NEEDUPDATE
Definition: mdi.c:97
static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO *ci, WORD recalc)
Definition: mdi.c:194
static LRESULT MDIDestroyChild(HWND client, MDICLIENTINFO *ci, HWND child, BOOL flagDestroy)
Definition: mdi.c:552
static HBITMAP CreateMDIMenuBitmap(void)
Definition: mdi.c:673
static HWND MDI_GetChildByID(HWND hwnd, UINT id, MDICLIENTINFO *ci)
Definition: mdi.c:182
#define WM_MDICALCCHILDSCROLL
Definition: mdi.c:90
void MDI_CalcDefaultChildPos(HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id)
Definition: mdi.c:285
static void MDI_UpdateFrameText(HWND, HWND, BOOL, LPCWSTR)
Definition: mdi.c:1016
LRESULT WINAPI DefFrameProcW(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1384
static LONG MDICascade(HWND client, MDICLIENTINFO *ci)
Definition: mdi.c:707
static LONG MDI_ChildActivate(HWND, HWND)
Definition: mdi.c:624
LRESULT WINAPI DefMDIChildProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1517
LRESULT WINAPI DefFrameProcA(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1350
LRESULT WINAPI MDIClientWndProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1332
static MDICLIENTINFO * get_client_info(HWND client)
Definition: mdi.c:220
static HWND MDI_MoreWindowsDialog(HWND)
Definition: mdi.c:2504
LRESULT WINAPI MDIClientWndProc_common(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: mdi.c:1083
static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
Definition: mdi.c:225
HWND WINAPI CreateMDIWindowA(LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, INT X, INT Y, INT nWidth, INT nHeight, HWND hWndParent, HINSTANCE hInstance, LPARAM lParam)
Definition: mdi.c:1681
static INT_PTR WINAPI MDI_MoreWindowsDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:2435
#define MDI_IDC_LISTBOX
Definition: mdi.c:94
static BOOL MDI_AugmentFrameMenu(HWND, HWND)
Definition: mdi.c:854
void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1901
static void MDI_ChildGetMinMaxInfo(HWND client, HWND hwnd, MINMAXINFO *lpMinMax)
Definition: mdi.c:495
static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext, DWORD dwStyleMask)
Definition: mdi.c:244
#define MDI_MAXTITLELENGTH
Definition: mdi.c:88
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1382
DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext(HWND hwnd)
Definition: win.c:630
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
int WINAPI SetMapMode(_In_ HDC, _In_ int)
HGDIOBJ WINAPI GetStockObject(_In_ int)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define SRCCOPY
Definition: wingdi.h:333
#define BLACK_PEN
Definition: wingdi.h:903
#define MM_TEXT
Definition: wingdi.h:873
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)