ReactOS  0.4.15-dev-5446-g3f3714b
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
97 
98 #define MDIF_NEEDUPDATE 0x0001
99 
100 typedef 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  */
118  HWND *child; /* array of tracked children */
125  UINT sbRecalc; /* SB_xxx flags for scrollbar fixup */
126  HBITMAP hBmpClose; /* ReactOS modification */
127 } MDICLIENTINFO;
128 
129 //static HBITMAP hBmpClose = 0;
130 
131 /* ----------------- declarations ----------------- */
132 static void MDI_UpdateFrameText( HWND, HWND, BOOL, LPCWSTR);
135 static LONG MDI_ChildActivate( HWND, HWND );
137 
139 
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 #ifdef __REACTOS__
180 void WINAPI CalcChildScroll(HWND hwnd, INT scroll);
181 #endif
182 
183 /* -------- Miscellaneous service functions ----------
184  *
185  * MDI_GetChildByID
186  */
188 {
189  int i;
190 
191  for (i = 0; ci->nActiveChildren; i++)
192  {
193  if (GetWindowLongPtrW( ci->child[i], GWLP_ID ) == id)
194  return ci->child[i];
195  }
196  return 0;
197 }
198 
199 static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
200 {
201  if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
202  {
203  ci->mdiFlags |= MDIF_NEEDUPDATE;
205  }
206  ci->sbRecalc = recalc;
207 }
208 
209 
210 /*********************************************************************
211  * MDIClient class descriptor
212  */
214 {
215  L"MDIClient", /* name */
216  0, /* style */
217  MDIClientWndProcA, /* procA */
218  MDIClientWndProcW, /* procW */
219  sizeof(MDIWND), /* extra */
220  IDC_ARROW, /* cursor */
221  (HBRUSH)(COLOR_APPWORKSPACE+1) /* brush */
222 };
223 
224 
226 {
227 #ifdef __REACTOS__
229 #else
231  WND *win = WIN_GetPtr( client );
232  if (win)
233  {
234  if (win == WND_OTHER_PROCESS || win == WND_DESKTOP)
235  {
236  if (IsWindow(client)) WARN( "client %p belongs to other process\n", client );
237  return NULL;
238  }
239  if (win->flags & WIN_ISMDICLIENT)
240  ret = (MDICLIENTINFO *)win->wExtra;
241  else
242  WARN( "%p is not an MDI client\n", client );
243  WIN_ReleasePtr( win );
244  }
245  return ret;
246 #endif
247 }
248 
250 {
252 
253  if (!hSysMenu) hSysMenu = GetSystemMenu(hwnd, FALSE);
254  if (hSysMenu)
255  {
257  if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
258  return FALSE;
259  }
260  return TRUE;
261 }
262 
263 /**********************************************************************
264  * MDI_GetWindow
265  *
266  * returns "activatable" child different from the current or zero
267  */
268 static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
269  DWORD dwStyleMask )
270 {
271  int i;
272  HWND *list;
273  HWND last = 0;
274 
275  dwStyleMask |= WS_DISABLED | WS_VISIBLE;
276  if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
277 
278  if (!(list = WIN_ListChildren( GetParent(hWnd) ))) return 0;
279  i = 0;
280  /* start from next after hWnd */
281  while (list[i] && list[i] != hWnd) i++;
282  if (list[i]) i++;
283 
284  for ( ; list[i]; i++)
285  {
286  if (GetWindow( list[i], GW_OWNER )) continue;
287  if ((GetWindowLongPtrW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
288  last = list[i];
289  if (bNext) goto found;
290  }
291  /* now restart from the beginning */
292  for (i = 0; list[i] && list[i] != hWnd; i++)
293  {
294  if (GetWindow( list[i], GW_OWNER )) continue;
295  if ((GetWindowLongPtrW( list[i], GWL_STYLE ) & dwStyleMask) != WS_VISIBLE) continue;
296  last = list[i];
297  if (bNext) goto found;
298  }
299  found:
300  HeapFree( GetProcessHeap(), 0, list );
301  return last;
302 }
303 
304 /**********************************************************************
305  * MDI_CalcDefaultChildPos
306  *
307  * It seems that the default height is about 2/3 of the client rect
308  */
309 void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id )
310 {
311  INT nstagger;
312  RECT rect;
314 
315  if (total < 0) /* we are called from CreateWindow */
316  {
317  MDICLIENTINFO *ci = get_client_info(hwndClient);
318  total = ci ? ci->nTotalCreated : 0; // Do not portsync wine
319  *id = ci ? ci->idFirstChild + ci->nActiveChildren : 0; // Do not portsync wine
320  TRACE("MDI child id %04x\n", *id);
321  }
322 
323  GetClientRect( hwndClient, &rect );
324  if( rect.bottom - rect.top - delta >= spacing )
325  rect.bottom -= delta;
326 
327  nstagger = (rect.bottom - rect.top)/(3 * spacing);
328  lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
329  lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
330  lpPos[0].x = lpPos[0].y = spacing * (total%(nstagger+1));
331 }
332 
333 /**********************************************************************
334  * MDISetMenu
335  */
336 static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
337  HMENU hmenuWindow)
338 {
339  MDICLIENTINFO *ci;
340  HWND hwndFrame = GetParent(hwnd);
341 
342  TRACE("%p, frame menu %p, window menu %p\n", hwnd, hmenuFrame, hmenuWindow);
343 
344  if (hmenuFrame && !IsMenu(hmenuFrame))
345  {
346  WARN("hmenuFrame is not a menu handle\n");
347  return 0L;
348  }
349 
350  if (hmenuWindow && !IsMenu(hmenuWindow))
351  {
352  WARN("hmenuWindow is not a menu handle\n");
353  return 0L;
354  }
355 
356  if (!(ci = get_client_info( hwnd ))) return 0;
357 
358  TRACE("old frame menu %p, old window menu %p\n", ci->hFrameMenu, ci->hWindowMenu);
359 
360  if (hmenuFrame)
361  {
362  if (hmenuFrame == ci->hFrameMenu) return (LRESULT)hmenuFrame;
363 
364  if (ci->hwndChildMaximized)
365  MDI_RestoreFrameMenu( hwndFrame, ci->hwndChildMaximized, ci->hBmpClose );
366  }
367 
368  if( hmenuWindow && hmenuWindow != ci->hWindowMenu )
369  {
370  /* delete menu items from ci->hWindowMenu
371  * and add them to hmenuWindow */
372  /* Agent newsreader calls this function with ci->hWindowMenu == NULL */
373  if( ci->hWindowMenu && ci->nActiveChildren )
374  {
375  UINT nActiveChildren_old = ci->nActiveChildren;
376 
377  /* Remove all items from old Window menu */
378  ci->nActiveChildren = 0;
379  MDI_RefreshMenu(ci);
380 
381  ci->hWindowMenu = hmenuWindow;
382 
383  /* Add items to the new Window menu */
384  ci->nActiveChildren = nActiveChildren_old;
385  MDI_RefreshMenu(ci);
386  }
387  else
388  ci->hWindowMenu = hmenuWindow;
389  }
390 
391  if (hmenuFrame)
392  {
393  SetMenu(hwndFrame, hmenuFrame);
394  if( hmenuFrame != ci->hFrameMenu )
395  {
396  HMENU oldFrameMenu = ci->hFrameMenu;
397 
398  ci->hFrameMenu = hmenuFrame;
399  if (ci->hwndChildMaximized)
400  MDI_AugmentFrameMenu( hwndFrame, ci->hwndChildMaximized );
401 
402  return (LRESULT)oldFrameMenu;
403  }
404  }
405 
406  return 0;
407 }
408 
409 /**********************************************************************
410  * MDIRefreshMenu
411  */
413 {
414  UINT i, count, visible, id;
416 
417  TRACE("children %u, window menu %p\n", ci->nActiveChildren, ci->hWindowMenu);
418 
419  if (!ci->hWindowMenu)
420  return 0;
421 
422  if (!IsMenu(ci->hWindowMenu))
423  {
424  WARN("Window menu handle %p is no longer valid\n", ci->hWindowMenu);
425  return 0;
426  }
427 
428  /* Windows finds the last separator in the menu, and if after it
429  * there is a menu item with MDI magic ID removes all existing
430  * menu items after it, and then adds visible MDI children.
431  */
433  for (i = 0; i < count; i++)
434  {
435  MENUITEMINFOW mii;
436 
437  memset(&mii, 0, sizeof(mii));
438  mii.cbSize = sizeof(mii);
439  mii.fMask = MIIM_TYPE;
440  if (GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii))
441  {
442  if (mii.fType & MF_SEPARATOR)
443  {
444  /* Windows checks only ID of the menu item */
445  memset(&mii, 0, sizeof(mii));
446  mii.cbSize = sizeof(mii);
447  mii.fMask = MIIM_ID;
448  if (GetMenuItemInfoW(ci->hWindowMenu, i + 1, TRUE, &mii))
449  {
450  if (mii.wID == ci->idFirstChild)
451  {
452  TRACE("removing %u items including separator\n", count - i);
453  while (RemoveMenu(ci->hWindowMenu, i, MF_BYPOSITION))
454  /* nothing */;
455 
456  break;
457  }
458  }
459  }
460  }
461  }
462 
463  visible = 0;
464  for (i = 0; i < ci->nActiveChildren; i++)
465  {
467  {
468  id = ci->idFirstChild + visible;
469 
470  if (visible == MDI_MOREWINDOWSLIMIT)
471  {
474  break;
475  }
476 
477  if (!visible)
478  /* Visio expects that separator has id 0 */
480 
481  visible++;
482 
483  SetWindowLongPtrW(ci->child[i], GWLP_ID, id);
484 
485  buf[0] = '&';
486  buf[1] = '0' + visible;
487  buf[2] = ' ';
488  InternalGetWindowText(ci->child[i], buf + 3, sizeof(buf)/sizeof(WCHAR) - 3);
489  TRACE("Adding %p, id %u %s\n", ci->child[i], id, debugstr_w(buf));
491 
492  if (ci->child[i] == ci->hwndActiveChild)
494  }
495  else
496  TRACE("MDI child %p is not visible, skipping\n", ci->child[i]);
497  }
498 
499  return (LRESULT)ci->hFrameMenu;
500 }
501 
502 
503 /* ------------------ MDI child window functions ---------------------- */
504 
505 /**********************************************************************
506  * MDI_ChildGetMinMaxInfo
507  *
508  * Note: The rule here is that client rect of the maximized MDI child
509  * is equal to the client rect of the MDI client window.
510  */
512 {
513  RECT rect;
514 
518 
519  lpMinMax->ptMaxSize.x = rect.right -= rect.left;
520  lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
521 
522  lpMinMax->ptMaxPosition.x = rect.left;
523  lpMinMax->ptMaxPosition.y = rect.top;
524 
525  TRACE("max rect %s\n", wine_dbgstr_rect(&rect));
526 }
527 
528 /**********************************************************************
529  * MDI_SwitchActiveChild
530  *
531  * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
532  * being activated
533  */
534 static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo, BOOL activate )
535 {
536  HWND hwndPrev;
537 
538  hwndPrev = ci->hwndActiveChild;
539 
540  TRACE("from %p, to %p\n", hwndPrev, hwndTo);
541 
542  if ( hwndTo != hwndPrev )
543  {
544  BOOL was_zoomed = IsZoomed(hwndPrev);
545 
546  if (was_zoomed)
547  {
548  /* restore old MDI child */
549  SendMessageW( hwndPrev, WM_SETREDRAW, FALSE, 0 );
550  ShowWindow( hwndPrev, SW_RESTORE );
551  SendMessageW( hwndPrev, WM_SETREDRAW, TRUE, 0 );
552 
553  /* activate new MDI child */
554  SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
555  /* maximize new MDI child */
556  ShowWindow( hwndTo, SW_MAXIMIZE );
557  }
558  /* activate new MDI child */
559  SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | (activate ? 0 : SWP_NOACTIVATE) );
560  }
561 }
562 
563 
564 /**********************************************************************
565  * MDIDestroyChild
566  */
568  HWND child, BOOL flagDestroy )
569 {
570  UINT i;
571 
572  TRACE("# of managed children %u\n", ci->nActiveChildren);
573 
574  if( child == ci->hwndActiveChild )
575  {
576  HWND next = MDI_GetWindow(ci, child, TRUE, 0);
577  if (next)
579  else
580  {
582  if (child == ci->hwndChildMaximized)
583  {
584  HWND frame = GetParent(client);
585  MDI_RestoreFrameMenu(frame, child, ci->hBmpClose);
586  ci->hwndChildMaximized = 0;
588  }
589  if (flagDestroy)
591  }
592  }
593 
594  for (i = 0; i < ci->nActiveChildren; i++)
595  {
596  if (ci->child[i] == child)
597  {
598  HWND *new_child = HeapAlloc(GetProcessHeap(), 0, (ci->nActiveChildren - 1) * sizeof(HWND));
599  if (new_child != NULL)
600  {
601  memcpy(new_child, ci->child, i * sizeof(HWND));
602  if (i + 1 < ci->nActiveChildren)
603  memcpy(new_child + i, ci->child + i + 1, (ci->nActiveChildren - i - 1) * sizeof(HWND));
604  HeapFree(GetProcessHeap(), 0, ci->child);
605  ci->child = new_child;
606  }
607  else
608  {
609  UINT c;
610  for (c = i; c < ci->nActiveChildren - 1; c++)
611  {
612  ci->child[c] = ci->child[c+1];
613  }
614  }
615 
616  ci->nActiveChildren--;
617  break;
618  }
619  }
620 
621  if (flagDestroy)
622  {
626  }
627 
628  TRACE("child destroyed - %p\n", child);
629  return 0;
630 }
631 
632 
633 /**********************************************************************
634  * MDI_ChildActivate
635  *
636  * Called in response to WM_CHILDACTIVATE, or when last MDI child
637  * is being deactivated.
638  */
640 {
641  MDICLIENTINFO *clientInfo;
642  HWND prevActiveWnd, frame;
643  BOOL isActiveFrameWnd;
644 
645  clientInfo = get_client_info( client );
646 
647  if (clientInfo->hwndActiveChild == child) return 0;
648 
649  TRACE("%p\n", child);
650 
651  frame = GetParent(client);
652  isActiveFrameWnd = (GetActiveWindow() == frame);
653  prevActiveWnd = clientInfo->hwndActiveChild;
654 
655  /* deactivate prev. active child */
656  if(prevActiveWnd)
657  {
658  SendMessageW( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
659  SendMessageW( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
660  }
661 
662  MDI_SwitchActiveChild( clientInfo, child, FALSE );
663  clientInfo->hwndActiveChild = child;
664 
665  MDI_RefreshMenu(clientInfo);
666 
667  if( isActiveFrameWnd )
668  {
670  /* Let the client window manage focus for children, but if the focus
671  * is already on the client (for instance this is the 1st child) then
672  * SetFocus won't work. It appears that Windows sends WM_SETFOCUS
673  * manually in this case.
674  */
675  if (SetFocus(client) == client)
677  }
678 
679  SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
680  return TRUE;
681 }
682 
683 /* -------------------- MDI client window functions ------------------- */
684 
685 /**********************************************************************
686  * CreateMDIMenuBitmap
687  */
689 {
690  HDC hDCSrc = CreateCompatibleDC(0);
691  HDC hDCDest = CreateCompatibleDC(hDCSrc);
693  HBITMAP hbCopy;
694  HBITMAP hobjSrc, hobjDest;
695 
696  hobjSrc = SelectObject(hDCSrc, hbClose);
698  hobjDest = SelectObject(hDCDest, hbCopy);
699 
701  hDCSrc, GetSystemMetrics(SM_CXSIZE), 0, SRCCOPY);
702 
703  SelectObject(hDCSrc, hobjSrc);
704  DeleteObject(hbClose);
705  DeleteDC(hDCSrc);
706 
707  hobjSrc = SelectObject( hDCDest, GetStockObject(BLACK_PEN) );
708 
709  MoveToEx( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, 0, NULL );
711 
712  SelectObject(hDCDest, hobjSrc );
713  SelectObject(hDCDest, hobjDest);
714  DeleteDC(hDCDest);
715 
716  return hbCopy;
717 }
718 
719 /**********************************************************************
720  * MDICascade
721  */
723 {
724  HWND *win_array;
725  BOOL has_icons = FALSE;
726  int i, total;
727 
728  if (ci->hwndChildMaximized)
730 
731  if (ci->nActiveChildren == 0) return 0;
732 
733  if (!(win_array = WIN_ListChildren( client ))) return 0;
734 
735  /* remove all the windows we don't want */
736  for (i = total = 0; win_array[i]; i++)
737  {
738  if (!IsWindowVisible( win_array[i] )) continue;
739  if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows */
740  if (IsIconic( win_array[i] ))
741  {
742  has_icons = TRUE;
743  continue;
744  }
745  win_array[total++] = win_array[i];
746  }
747  win_array[total] = 0;
748 
749  if (total)
750  {
751  INT delta = 0, n = 0, i;
752  POINT pos[2];
753  if (has_icons) delta = GetSystemMetrics(SM_CYICONSPACING) + GetSystemMetrics(SM_CYICON);
754 
755  /* walk the list (backwards) and move windows */
756  for (i = total - 1; i >= 0; i--)
757  {
758  LONG style;
760 
761  MDI_CalcDefaultChildPos(client, n++, pos, delta, NULL);
762  TRACE("move %p to (%ld,%ld) size [%ld,%ld]\n",
763  win_array[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
764  style = GetWindowLongW(win_array[i], GWL_STYLE);
765 
766  if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
767  SetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
768  posOptions);
769  }
770  }
771  HeapFree( GetProcessHeap(), 0, win_array );
772 
773  if (has_icons) ArrangeIconicWindows( client );
774  return 0;
775 }
776 
777 /**********************************************************************
778  * MDITile
779  */
781 {
782  HWND *win_array;
783  int i, total, rows, columns;
784  BOOL has_icons = FALSE;
785 
786  if (ci->hwndChildMaximized)
788 
789  if (ci->nActiveChildren == 0) return;
790 
791  if (!(win_array = WIN_ListChildren( client ))) return;
792 
793  /* remove all the windows we don't want */
794  for (i = total = rows = 0; win_array[i]; i++)
795  {
796  if (!IsWindowVisible( win_array[i] )) continue;
797  if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows (icon titles) */
798  if (IsIconic( win_array[i] ))
799  {
800  has_icons = TRUE;
801  continue;
802  }
803  if ((wParam & MDITILE_SKIPDISABLED) && !IsWindowEnabled( win_array[i] )) continue;
804  if(total == (rows * (rows + 2))) rows++; /* total+1 == (rows+1)*(rows+1) */
805  win_array[total++] = win_array[i];
806  }
807  win_array[total] = 0;
808 
809  TRACE("%u windows to tile\n", total);
810 
811  if (total)
812  {
813  HWND *pWnd = win_array;
814  RECT rect;
815  int x, y, xsize, ysize;
816  int r, c, i;
817 
819  columns = total/rows;
820  //while(total < rows*columns) rows++;
821 
822  if( wParam & MDITILE_HORIZONTAL ) /* version >= 3.1 */
823  {
824  i = rows;
825  rows = columns; /* exchange r and c */
826  columns = i;
827  }
828 
829  if (has_icons)
830  {
832  rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
833  }
834 
835  ysize = rect.bottom / rows;
836  xsize = rect.right / columns;
837 
838  for (x = i = 0, c = 1; c <= columns && *pWnd; c++)
839  {
840  if (c == columns)
841  {
842  rows = total - i;
843  ysize = rect.bottom / rows;
844  }
845 
846  y = 0;
847  for (r = 1; r <= rows && *pWnd; r++, i++)
848  {
850  LONG style = GetWindowLongW(win_array[i], GWL_STYLE);
851  if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
852 
853  SetWindowPos(*pWnd, 0, x, y, xsize, ysize, posOptions);
854  y += ysize;
855  pWnd++;
856  }
857  x += xsize;
858  }
859  }
860  HeapFree( GetProcessHeap(), 0, win_array );
861  if (has_icons) ArrangeIconicWindows( client );
862 }
863 
864 /* ----------------------- Frame window ---------------------------- */
865 
866 
867 /**********************************************************************
868  * MDI_AugmentFrameMenu
869  */
871 {
872  HMENU menu = GetMenu( frame );
873  HMENU hSysPopup;
874  HBITMAP hSysMenuBitmap = 0;
875  HICON hIcon;
876  INT nItems;
877  UINT iId;
878 
879  TRACE("frame %p,child %p\n",frame,hChild);
880 
881  if( !menu ) return FALSE;
883  /* if the system buttons already exist do not add them again */
884  nItems = GetMenuItemCount(menu) - 1;
885  iId = GetMenuItemID(menu,nItems) ;
886  if (iId == SC_RESTORE || iId == SC_CLOSE)
887  {
888  ERR("system buttons already exist\n");
889  return FALSE;
890  }
892  /* create a copy of sysmenu popup and insert it into frame menu bar */
893  if (!(hSysPopup = GetSystemMenu(hChild, FALSE)))
894  {
895  TRACE("child %p doesn't have a system menu\n", hChild);
896  return FALSE;
897  }
898 
899  AppendMenuW(menu, MF_HELP | MF_BITMAP,
900  SC_CLOSE, is_close_enabled(hChild, hSysPopup) ?
902  AppendMenuW(menu, MF_HELP | MF_BITMAP,
904  AppendMenuW(menu, MF_HELP | MF_BITMAP,
906 
907  /* The system menu is replaced by the child icon */
908  hIcon = (HICON)SendMessageW(hChild, WM_GETICON, ICON_SMALL, 0);
909  if (!hIcon)
911  if (!hIcon)
912  hIcon = (HICON)SendMessageW(hChild, WM_GETICON, ICON_BIG, 0);
913  if (!hIcon)
915  if (!hIcon)
918  if (hIcon)
919  {
920  HDC hMemDC;
921  HBITMAP hBitmap, hOldBitmap;
922  HDC hdc = GetDC(hChild);
923 
924  if (hdc)
925  {
926  int cx, cy;
929  hMemDC = CreateCompatibleDC(hdc);
931  hOldBitmap = SelectObject(hMemDC, hBitmap);
932  SetMapMode(hMemDC, MM_TEXT);
933  DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL);
934  SelectObject (hMemDC, hOldBitmap);
935  DeleteDC(hMemDC);
936  ReleaseDC(hChild, hdc);
937  hSysMenuBitmap = hBitmap;
938  }
939  }
940 
942  (UINT_PTR)hSysPopup, (LPSTR)hSysMenuBitmap))
943  {
944  TRACE("not inserted\n");
945  DestroyMenu(hSysPopup);
946  return FALSE;
947  }
948 
952  SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
953 
954  /* redraw menu */
955  DrawMenuBar(frame);
956 
957  return TRUE;
958 }
959 
960 /**********************************************************************
961  * MDI_RestoreFrameMenu
962  */
963 static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild, HBITMAP hBmpClose )
964 {
965  MENUITEMINFOW menuInfo;
966  HMENU menu = GetMenu( frame );
967  INT nItems;
968  UINT iId;
969 
970  TRACE("frame %p,child %p\n",frame, hChild);
971 
972  if (!menu) return FALSE;
973 
974  /* if there is no system buttons then nothing to do */
975  nItems = GetMenuItemCount(menu) - 1;
976  iId = GetMenuItemID(menu, nItems);
977  if ( !(iId == SC_RESTORE || iId == SC_CLOSE) )
978  {
979  ERR("no system buttons then nothing to do\n");
980  return FALSE;
981  }
982 
983  /*
984  * Remove the system menu, If that menu is the icon of the window
985  * as it is in win95, we have to delete the bitmap.
986  */
987  memset(&menuInfo, 0, sizeof(menuInfo));
988  menuInfo.cbSize = sizeof(menuInfo);
989  menuInfo.fMask = MIIM_DATA | MIIM_TYPE | MIIM_BITMAP;
990 
991  GetMenuItemInfoW(menu,
992  0,
993  TRUE,
994  &menuInfo);
995 
996  RemoveMenu(menu,0,MF_BYPOSITION);
997 
998  if ( (menuInfo.fType & MFT_BITMAP) &&
999  (menuInfo.dwTypeData != 0) &&
1000  (menuInfo.dwTypeData != (LPWSTR)hBmpClose) )
1001  {
1002  DeleteObject(menuInfo.dwTypeData);
1003  }
1004 
1005  if ( menuInfo.hbmpItem != 0 )
1006  DeleteObject(menuInfo.hbmpItem);
1007 
1008  /* close */
1010  /* restore */
1012  /* minimize */
1014 
1015  DrawMenuBar(frame);
1016 
1017  return TRUE;
1018 }
1019 
1020 
1021 /**********************************************************************
1022  * MDI_UpdateFrameText
1023  *
1024  * used when child window is maximized/restored
1025  *
1026  * Note: lpTitle can be NULL
1027  */
1028 static void MDI_UpdateFrameText( HWND frame, HWND hClient, BOOL repaint, LPCWSTR lpTitle )
1029 {
1031  MDICLIENTINFO *ci = get_client_info( hClient );
1032 
1033  TRACE("frameText %s\n", debugstr_w(lpTitle));
1034 
1035  if (!ci) return;
1036 
1037  if (!lpTitle && !ci->frameTitle) /* first time around, get title from the frame window */
1038  {
1039  GetWindowTextW( frame, lpBuffer, sizeof(lpBuffer)/sizeof(WCHAR) );
1040  lpTitle = lpBuffer;
1041  }
1042 
1043  /* store new "default" title if lpTitle is not NULL */
1044  if (lpTitle)
1045  {
1046  HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1047  if ((ci->frameTitle = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpTitle)+1)*sizeof(WCHAR))))
1048  strcpyW( ci->frameTitle, lpTitle );
1049  }
1050 
1051  if (ci->frameTitle)
1052  {
1053  if (ci->hwndChildMaximized)
1054  {
1055  /* combine frame title and child title if possible */
1056 
1057  static const WCHAR lpBracket[] = {' ','-',' ','[',0};
1058  static const WCHAR lpBracket2[] = {']',0};
1059  int i_frame_text_length = strlenW(ci->frameTitle);
1060 
1062 
1063  if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
1064  {
1065  strcatW( lpBuffer, lpBracket );
1066  if (GetWindowTextW( ci->hwndActiveChild, lpBuffer + i_frame_text_length + 4,
1067  MDI_MAXTITLELENGTH - i_frame_text_length - 5 ))
1068  strcatW( lpBuffer, lpBracket2 );
1069  else
1070  lpBuffer[i_frame_text_length] = 0; /* remove bracket */
1071  }
1072  }
1073  else
1074  {
1076  }
1077  }
1078  else
1079  lpBuffer[0] = '\0';
1080 
1081  DefWindowProcW( frame, WM_SETTEXT, 0, (LPARAM)lpBuffer );
1082 
1083  if (repaint)
1084  {
1086  SetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
1088  }
1089 }
1090 
1091 
1092 /* ----------------------------- Interface ---------------------------- */
1093 
1094 
1095 /**********************************************************************
1096  * MDIClientWndProc_common
1097  */
1099 {
1100  MDICLIENTINFO *ci = NULL;
1101 
1102  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1103 
1104  if (!(ci = get_client_info( hwnd )))
1105  {
1106 #ifdef __REACTOS__
1107  if (message == WM_NCCREATE)
1108  {
1109  if (!(ci = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ci))))
1110  return FALSE;
1112  ci->hBmpClose = 0;
1113  NtUserSetWindowFNID( hwnd, FNID_MDICLIENT); // wine uses WIN_ISMDICLIENT
1114  }
1115 #else
1116  if (message == WM_NCCREATE) win_set_flags( hwnd, WIN_ISMDICLIENT, 0 );
1117 #endif
1118  return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1120  }
1121 
1122  switch (message)
1123  {
1124  case WM_CREATE:
1125  {
1126  /* Since we are using only cs->lpCreateParams, we can safely
1127  * cast to LPCREATESTRUCTA here */
1129  LPCLIENTCREATESTRUCT ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
1130 
1131  ci->hWindowMenu = ccs->hWindowMenu;
1132  ci->idFirstChild = ccs->idFirstChild;
1133  ci->hwndChildMaximized = 0;
1134  ci->child = NULL;
1135  ci->nActiveChildren = 0;
1136  ci->nTotalCreated = 0;
1137  ci->frameTitle = NULL;
1138  ci->mdiFlags = 0;
1139  ci->hFrameMenu = GetMenu(cs->hwndParent);
1140 
1141  if (!ci->hBmpClose) ci->hBmpClose = CreateMDIMenuBitmap();
1142 
1143  TRACE("Client created: hwnd %p, Window menu %p, idFirst = %04x\n",
1144  hwnd, ci->hWindowMenu, ci->idFirstChild );
1145  return 0;
1146  }
1147 
1148  case WM_DESTROY:
1149  {
1150  if( ci->hwndChildMaximized )
1152 
1153  ci->nActiveChildren = 0;
1154  MDI_RefreshMenu(ci);
1155 
1156  HeapFree( GetProcessHeap(), 0, ci->child );
1157  HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1158 #ifdef __REACTOS__
1159  HeapFree( GetProcessHeap(), 0, ci );
1161 #endif
1162  return 0;
1163  }
1164 
1165 #ifdef __REACTOS__
1166  case WM_NCDESTROY:
1167  {
1169  return 0;
1170  }
1171 #endif
1172 
1173  case WM_MDIACTIVATE:
1174  {
1175  if( ci->hwndActiveChild != (HWND)wParam )
1176  SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
1177  return 0;
1178  }
1179 
1180  case WM_MDICASCADE:
1181  return MDICascade(hwnd, ci);
1182 
1183  case WM_MDICREATE:
1184  if (lParam)
1185  {
1186  HWND child;
1187 
1188  if (unicode)
1189  {
1192  csW->szTitle, csW->style,
1193  csW->x, csW->y, csW->cx, csW->cy,
1194  hwnd, 0, csW->hOwner,
1195  (LPVOID)csW->lParam);
1196  }
1197  else
1198  {
1201  csA->szTitle, csA->style,
1202  csA->x, csA->y, csA->cx, csA->cy,
1203  hwnd, 0, csA->hOwner,
1204  (LPVOID)csA->lParam);
1205  }
1206  return (LRESULT)child;
1207  }
1208  return 0;
1209 
1210  case WM_MDIDESTROY:
1211  return MDIDestroyChild( hwnd, ci, (HWND)wParam, TRUE );
1212 
1213  case WM_MDIGETACTIVE:
1214  if (lParam) *(BOOL *)lParam = IsZoomed(ci->hwndActiveChild);
1215  return (LRESULT)ci->hwndActiveChild;
1216 
1217  case WM_MDIICONARRANGE:
1218  ci->mdiFlags |= MDIF_NEEDUPDATE;
1220  ci->sbRecalc = SB_BOTH+1;
1221 #ifdef __REACTOS__
1223 #else
1225 #endif
1226  return 0;
1227 
1228  case WM_MDIMAXIMIZE:
1230  return 0;
1231 
1232  case WM_MDINEXT: /* lParam != 0 means previous window */
1233  {
1235  HWND next = MDI_GetWindow( ci, hwnd, !lParam, 0 );
1237  if(!lParam)
1239  break;
1240  }
1241 
1242  case WM_MDIRESTORE:
1244  return 0;
1245 
1246  case WM_MDISETMENU:
1247  return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
1248 
1249  case WM_MDIREFRESHMENU:
1250  return MDI_RefreshMenu( ci );
1251 
1252  case WM_MDITILE:
1253  ci->mdiFlags |= MDIF_NEEDUPDATE;
1255  MDITile( hwnd, ci, wParam );
1256  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1257  return 0;
1258 
1259  case WM_VSCROLL:
1260  case WM_HSCROLL:
1261  ci->mdiFlags |= MDIF_NEEDUPDATE;
1263  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1264  return 0;
1265 
1266  case WM_SETFOCUS:
1267  if (ci->hwndActiveChild && !IsIconic( ci->hwndActiveChild ))
1268  SetFocus( ci->hwndActiveChild );
1269  return 0;
1270 
1271  case WM_NCACTIVATE:
1272  if( ci->hwndActiveChild )
1274  break;
1275 
1276  case WM_PARENTNOTIFY:
1277  switch (LOWORD(wParam))
1278  {
1279  case WM_CREATE:
1281  {
1282  // ReactOS See rev 33503
1283  if (!ci->child)
1284  ci->child = HeapAlloc(GetProcessHeap(), 0, sizeof(HWND));
1285  else
1286  ci->child = HeapReAlloc(GetProcessHeap(), 0, ci->child, sizeof(HWND) * (ci->nActiveChildren + 1));
1287 
1288  TRACE("Adding MDI child %p, # of children %d\n",
1289  (HWND)lParam, ci->nActiveChildren);
1290 
1291  if (ci->child != NULL)
1292  {
1293  ci->child[ci->nActiveChildren] = (HWND)lParam;
1294  ci->nTotalCreated++;
1295  ci->nActiveChildren++;
1296  }
1297  }
1298  break;
1299 
1300  case WM_LBUTTONDOWN:
1301  {
1302  HWND child;
1303  POINT pt;
1304  pt.x = (short)LOWORD(lParam);
1305  pt.y = (short)HIWORD(lParam);
1307 
1308  TRACE("notification from %p (%li,%li)\n",child,pt.x,pt.y);
1309 
1310  if( child && child != hwnd && child != ci->hwndActiveChild )
1311  SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
1312  break;
1313  }
1314 
1315  case WM_DESTROY:
1316  return MDIDestroyChild( hwnd, ci, WIN_GetFullHandle( (HWND)lParam ), FALSE );
1317  }
1318  return 0;
1319 
1320  case WM_SIZE:
1321  if( ci->hwndActiveChild && IsZoomed(ci->hwndActiveChild) )
1322  {
1323  RECT rect;
1324 
1325  SetRect(&rect, 0, 0, LOWORD(lParam), HIWORD(lParam));
1328  MoveWindow(ci->hwndActiveChild, rect.left, rect.top,
1329  rect.right - rect.left, rect.bottom - rect.top, 1);
1330  }
1331  else
1332  MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
1333 
1334  break;
1335 
1336  case WM_MDICALCCHILDSCROLL:
1337  if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
1338  {
1339  CalcChildScroll(hwnd, ci->sbRecalc-1);
1340  ci->sbRecalc = 0;
1341  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1342  }
1343  return 0;
1344  }
1345  return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1347 }
1348 
1349 /***********************************************************************
1350  * MDIClientWndProcA
1351  */
1353 {
1354  if (!IsWindow(hwnd)) return 0;
1356 }
1357 
1358 /***********************************************************************
1359  * MDIClientWndProcW
1360  */
1362 {
1363  if (!IsWindow(hwnd)) return 0;
1365 }
1366 
1367 /***********************************************************************
1368  * DefFrameProcA (USER32.@)
1369  */
1372 {
1373  if (hwndMDIClient)
1374  {
1375  switch (message)
1376  {
1377  case WM_SETTEXT:
1378  {
1379  DWORD len = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0 );
1380  LPWSTR text = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1381  if (text == NULL)
1382  return 0;
1385  HeapFree( GetProcessHeap(), 0, text );
1386  }
1387  return 1; /* success. FIXME: check text length */
1388 
1389  case WM_COMMAND:
1390  case WM_NCACTIVATE:
1391  case WM_NEXTMENU:
1392  case WM_SETFOCUS:
1393  case WM_SIZE:
1395  }
1396  }
1398 }
1399 
1400 
1401 /***********************************************************************
1402  * DefFrameProcW (USER32.@)
1403  */
1406 {
1408 
1409  TRACE("%p %p %04x (%s) %08lx %08lx\n", hwnd, hwndMDIClient, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1410 
1411  if (ci)
1412  {
1413  switch (message)
1414  {
1415  case WM_COMMAND:
1416  {
1417  WORD id = LOWORD(wParam);
1418  /* check for possible syscommands for maximized MDI child */
1419  if (id < ci->idFirstChild || id >= ci->idFirstChild + ci->nActiveChildren)
1420  {
1421  if( (id - 0xf000) & 0xf00f ) break;
1422  if( !ci->hwndChildMaximized ) break;
1423  switch( id )
1424  {
1425  case SC_CLOSE:
1426  if (!is_close_enabled(ci->hwndActiveChild, 0)) break;
1427  case SC_SIZE:
1428  case SC_MOVE:
1429  case SC_MINIMIZE:
1430  case SC_MAXIMIZE:
1431  case SC_NEXTWINDOW:
1432  case SC_PREVWINDOW:
1433  case SC_RESTORE:
1435  wParam, lParam);
1436  }
1437  }
1438  else
1439  {
1440  HWND childHwnd;
1441  if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
1442  /* User chose "More Windows..." */
1443  childHwnd = MDI_MoreWindowsDialog(hwndMDIClient);
1444  else
1445  /* User chose one of the windows listed in the "Windows" menu */
1446  childHwnd = MDI_GetChildByID(hwndMDIClient, id, ci);
1447 
1448  if( childHwnd )
1449  SendMessageW( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd, 0 );
1450  }
1451  }
1452  break;
1453 
1454  case WM_NCACTIVATE:
1456  break;
1457 
1458  case WM_SETTEXT:
1460  return 1; /* success. FIXME: check text length */
1461 
1462  case WM_SETFOCUS:
1464  break;
1465 
1466  case WM_SIZE:
1468  break;
1469 
1470  case WM_NEXTMENU:
1471  {
1472  MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1473 
1474  if (!IsIconic(hwnd) && ci->hwndActiveChild && !IsZoomed(ci->hwndActiveChild))
1475  {
1476  /* control menu is between the frame system menu and
1477  * the first entry of menu bar */
1478 // WND *wndPtr = WIN_GetPtr(hwnd);
1479 
1480  if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
1481  (wParam == VK_RIGHT && GetSubMenu(GetMenu(hwnd), 0) == next_menu->hmenuIn) )
1482  {
1483 // WIN_ReleasePtr(wndPtr);
1484 // wndPtr = WIN_GetPtr(ci->hwndActiveChild);
1485  next_menu->hmenuNext = GetSubMenu(GetMenu(ci->hwndActiveChild), 0);
1486  next_menu->hwndNext = ci->hwndActiveChild;
1487  }
1488 // WIN_ReleasePtr(wndPtr);
1489  }
1490  return 0;
1491  }
1492  }
1493  }
1494 
1495  return DefWindowProcW( hwnd, message, wParam, lParam );
1496 }
1497 
1498 /***********************************************************************
1499  * DefMDIChildProcA (USER32.@)
1500  */
1503 {
1506 
1507  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1508 
1510  if (!ci) return DefWindowProcA( hwnd, message, wParam, lParam );
1511 
1512  switch (message)
1513  {
1514  case WM_SETTEXT:
1516  if( ci->hwndChildMaximized == hwnd )
1518  MDI_RefreshMenu( ci );
1519  return 1; /* success. FIXME: check text length */
1520 
1521  case WM_GETMINMAXINFO:
1522  case WM_MENUCHAR:
1523  case WM_CLOSE:
1524  case WM_SETFOCUS:
1525  case WM_CHILDACTIVATE:
1526  case WM_SYSCOMMAND:
1527  case WM_SHOWWINDOW:
1528  case WM_SETVISIBLE:
1529  case WM_SIZE:
1530  case WM_NEXTMENU:
1531  case WM_SYSCHAR:
1532  case WM_DESTROY:
1533  return DefMDIChildProcW( hwnd, message, wParam, lParam );
1534  }
1536 }
1537 
1538 
1539 /***********************************************************************
1540  * DefMDIChildProcW (USER32.@)
1541  */
1544 {
1547 
1548  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1549 
1551  if (!ci) return DefWindowProcW( hwnd, message, wParam, lParam );
1552 
1553  switch (message)
1554  {
1555  case WM_SETTEXT:
1557  if( ci->hwndChildMaximized == hwnd )
1559  MDI_RefreshMenu( ci );
1560  return 1; /* success. FIXME: check text length */
1561 
1562  case WM_GETMINMAXINFO:
1564  return 0;
1565 
1566  case WM_MENUCHAR:
1567  return MAKELRESULT( 0, MNC_CLOSE ); /* MDI children don't have menu bars */
1568 
1569  case WM_CLOSE:
1571  return 0;
1572 
1573  case WM_SETFOCUS:
1574  if (ci->hwndActiveChild != hwnd)
1576  break;
1577 
1578  case WM_CHILDACTIVATE:
1579  if (IsWindowEnabled( hwnd ))
1581  return 0;
1582 
1583  case WM_SYSCOMMAND:
1584  switch (wParam & 0xfff0)
1585  {
1586  case SC_MOVE:
1587  if( ci->hwndChildMaximized == hwnd )
1588  return 0;
1589  break;
1590  case SC_RESTORE:
1591  case SC_MINIMIZE:
1592  break;
1593  case SC_MAXIMIZE:
1594  if (ci->hwndChildMaximized == hwnd)
1596  break;
1597  case SC_NEXTWINDOW:
1599  return 0;
1600  case SC_PREVWINDOW:
1602  return 0;
1603  }
1604  break;
1605 
1606  case WM_SHOWWINDOW:
1607  case WM_SETVISIBLE:
1609  /*if (ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1610  else*/ MDI_PostUpdate(client, ci, SB_BOTH+1);
1611  break;
1612 
1613  case WM_SIZE:
1614  /* This is the only place where we switch to/from maximized state */
1615  /* do not change */
1616  TRACE("current active %p, maximized %p\n", ci->hwndActiveChild, ci->hwndChildMaximized);
1617 
1618  if( ci->hwndChildMaximized == hwnd && wParam != SIZE_MAXIMIZED )
1619  {
1620  HWND frame;
1621 
1622  ci->hwndChildMaximized = 0;
1623 
1624  frame = GetParent(client);
1625  MDI_RestoreFrameMenu( frame, hwnd, ci->hBmpClose );
1626  MDI_UpdateFrameText( frame, client, TRUE, NULL );
1627  }
1628 
1629  if( wParam == SIZE_MAXIMIZED )
1630  {
1631  HWND frame, hMaxChild = ci->hwndChildMaximized;
1632 
1633  if( hMaxChild == hwnd ) break;
1634 
1635  if( hMaxChild)
1636  {
1637  SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
1638 
1639  MDI_RestoreFrameMenu( GetParent(client), hMaxChild, ci->hBmpClose );
1640  ShowWindow( hMaxChild, SW_SHOWNOACTIVATE );
1641 
1642  SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
1643  }
1644 
1645  TRACE("maximizing child %p\n", hwnd );
1646 
1647  /* keep track of the maximized window. */
1648  ci->hwndChildMaximized = hwnd; /* !!! */
1649 
1650  frame = GetParent(client);
1651  MDI_AugmentFrameMenu( frame, hwnd );
1652  MDI_UpdateFrameText( frame, client, TRUE, NULL );
1653  }
1654 
1655  if( wParam == SIZE_MINIMIZED )
1656  {
1657  HWND switchTo = MDI_GetWindow( ci, hwnd, TRUE, WS_MINIMIZE );
1658 
1659  if (!switchTo) switchTo = hwnd;
1660  SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0 );
1661  }
1662 
1663  MDI_PostUpdate(client, ci, SB_BOTH+1);
1664  break;
1665 
1666  case WM_NEXTMENU:
1667  {
1668  MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1670 
1671  if( wParam == VK_LEFT ) /* switch to frame system menu */
1672  {
1673 // WND *wndPtr = WIN_GetPtr( parent );
1674  next_menu->hmenuNext = GetSubMenu( GetMenu(parent), 0 );
1675 // WIN_ReleasePtr( wndPtr );
1676  }
1677  if( wParam == VK_RIGHT ) /* to frame menu bar */
1678  {
1679  next_menu->hmenuNext = GetMenu(parent);
1680  }
1681  next_menu->hwndNext = parent;
1682  return 0;
1683  }
1684 
1685  case WM_SYSCHAR:
1686  if (wParam == '-')
1687  {
1689  return 0;
1690  }
1691  break;
1692 
1693  case WM_DESTROY:
1694  /* Remove itself from the Window menu */
1695  MDI_RefreshMenu(ci);
1696  break;
1697  }
1699 }
1700 
1701 /**********************************************************************
1702  * CreateMDIWindowA (USER32.@) Creates a MDI child
1703  *
1704  * RETURNS
1705  * Success: Handle to created window
1706  * Failure: NULL
1707  */
1709  LPCSTR lpClassName, /* [in] Pointer to registered child class name */
1710  LPCSTR lpWindowName, /* [in] Pointer to window name */
1711  DWORD dwStyle, /* [in] Window style */
1712  INT X, /* [in] Horizontal position of window */
1713  INT Y, /* [in] Vertical position of window */
1714  INT nWidth, /* [in] Width of window */
1715  INT nHeight, /* [in] Height of window */
1716  HWND hWndParent, /* [in] Handle to parent window */
1717  HINSTANCE hInstance, /* [in] Handle to application instance */
1718  LPARAM lParam) /* [in] Application-defined value */
1719 {
1720  TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
1721  debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
1722  nWidth,nHeight,hWndParent,hInstance,lParam);
1723 
1724  return CreateWindowExA(WS_EX_MDICHILD, lpClassName, lpWindowName,
1725  dwStyle, X, Y, nWidth, nHeight, hWndParent,
1726  0, hInstance, (LPVOID)lParam);
1727 }
1728 
1729 /***********************************************************************
1730  * CreateMDIWindowW (USER32.@) Creates a MDI child
1731  *
1732  * RETURNS
1733  * Success: Handle to created window
1734  * Failure: NULL
1735  */
1737  LPCWSTR lpClassName, /* [in] Pointer to registered child class name */
1738  LPCWSTR lpWindowName, /* [in] Pointer to window name */
1739  DWORD dwStyle, /* [in] Window style */
1740  INT X, /* [in] Horizontal position of window */
1741  INT Y, /* [in] Vertical position of window */
1742  INT nWidth, /* [in] Width of window */
1743  INT nHeight, /* [in] Height of window */
1744  HWND hWndParent, /* [in] Handle to parent window */
1745  HINSTANCE hInstance, /* [in] Handle to application instance */
1746  LPARAM lParam) /* [in] Application-defined value */
1747 {
1748  TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
1749  debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
1750  nWidth, nHeight, hWndParent, hInstance, lParam);
1751 
1752  return CreateWindowExW(WS_EX_MDICHILD, lpClassName, lpWindowName,
1753  dwStyle, X, Y, nWidth, nHeight, hWndParent,
1754  0, hInstance, (LPVOID)lParam);
1755 }
1756 
1757 /**********************************************************************
1758  * TranslateMDISysAccel (USER32.@)
1759  */
1761 {
1762  if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
1763  {
1764  MDICLIENTINFO *ci = get_client_info( hwndClient );
1765  WPARAM wParam = 0;
1766 
1767  if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
1768 
1769  /* translate if the Ctrl key is down and Alt not. */
1770 
1771  if( (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
1772  {
1773  switch( msg->wParam )
1774  {
1775  case VK_F6:
1776  case VK_TAB:
1778  break;
1779  case VK_F4:
1780  case VK_RBUTTON:
1781  if (is_close_enabled(ci->hwndActiveChild, 0))
1782  {
1783  wParam = SC_CLOSE;
1784  break;
1785  }
1786  /* fall through */
1787  default:
1788  return FALSE;
1789  }
1790  TRACE("wParam = %04lx\n", wParam);
1792  return TRUE;
1793  }
1794  }
1795  return FALSE; /* failure */
1796 }
1797 
1798 /***********************************************************************
1799  * CalcChildScroll (USER32.@)
1800  */
1802 {
1803  SCROLLINFO info;
1804  RECT childRect, clientRect;
1805  HWND *list;
1806  DWORD style;
1807  WINDOWINFO WindowInfo;
1808 
1809  GetClientRect( hwnd, &clientRect );
1810  SetRectEmpty( &childRect );
1811 
1812  /* The rectangle returned by GetClientRect always has 0,0 as top left
1813  * because it is in client coordinates. The rectangles returned by
1814  * GetWindowRect are in screen coordinates to make this complicated.
1815  *
1816  * Apparently (in ReactOS at least) the rcClient returned by GetWindowInfo
1817  * is in screen coordinates too.
1818  */
1819  WindowInfo.cbSize = sizeof(WindowInfo);
1820  if (!GetWindowInfo(hwnd, &WindowInfo))
1821  {
1822  ERR("Can't get window info\n");
1823  return;
1824  }
1825 
1826  TRACE("CalcChildScroll 1\n");
1827  if ((list = WIN_ListChildren( hwnd )))
1828  {
1829  int i;
1830  for (i = 0; list[i]; i++)
1831  {
1833  if (style & WS_MAXIMIZE)
1834  {
1835  HeapFree( GetProcessHeap(), 0, list );
1837  ERR("CalcChildScroll 2\n");
1838  return;
1839  }
1840  if (style & WS_VISIBLE)
1841  {
1842  RECT rect;
1843  GetWindowRect( list[i], &rect );
1844  OffsetRect(&rect, -WindowInfo.rcClient.left,
1845  -WindowInfo.rcClient.top);
1846  //WIN_GetRectangles( list[i], COORDS_PARENT, &rect, NULL );
1847  TRACE("CalcChildScroll L\n");
1848  UnionRect( &childRect, &rect, &childRect );
1849  }
1850  }
1851  HeapFree( GetProcessHeap(), 0, list );
1852  }
1853  UnionRect( &childRect, &clientRect, &childRect );
1854  TRACE("CalcChildScroll 3\n");
1855  /* set common info values */
1856  info.cbSize = sizeof(info);
1857  info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
1858  info.nPos = 0;
1859 
1860  /* set the specific values and apply but only if window style allows */
1861  /* Note how we set nPos to 0 because we scroll the clients instead of
1862  * the window, and we set nPage to 1 bigger than the clientRect because
1863  * otherwise the scrollbar never disables. This causes a somewhat ugly
1864  * effect though while scrolling.
1865  */
1867  switch( scroll )
1868  {
1869  case SB_BOTH:
1870  case SB_HORZ:
1871  if (style & (WS_HSCROLL | WS_VSCROLL))
1872  {
1873  info.nMin = childRect.left;
1874  info.nMax = childRect.right;
1875  info.nPage = 1 + clientRect.right - clientRect.left;
1876  //info.nMax = childRect.right - clientRect.right;
1877  //info.nPos = clientRect.left - childRect.left;
1879  }
1880  if (scroll == SB_HORZ) break;
1881  /* fall through */
1882  case SB_VERT:
1883  if (style & (WS_HSCROLL | WS_VSCROLL))
1884  {
1885  info.nMin = childRect.top;
1886  info.nMax = childRect.bottom;
1887  info.nPage = 1 + clientRect.bottom - clientRect.top;
1888  //info.nMax = childRect.bottom - clientRect.bottom;
1889  //info.nPos = clientRect.top - childRect.top;
1891  }
1892  break;
1893  }
1894 }
1895 
1896 
1897 /***********************************************************************
1898  * ScrollChildren (USER32.@)
1899  */
1901  LPARAM lParam)
1902 {
1903  INT newPos = -1;
1904  INT curPos, length, minPos, maxPos, shift;
1905  RECT rect;
1906 
1907  GetClientRect( hWnd, &rect );
1908 
1909  switch(uMsg)
1910  {
1911  case WM_HSCROLL:
1912  GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
1913  curPos = GetScrollPos(hWnd,SB_HORZ);
1914  length = (rect.right - rect.left) / 2;
1916  break;
1917  case WM_VSCROLL:
1918  GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
1919  curPos = GetScrollPos(hWnd,SB_VERT);
1920  length = (rect.bottom - rect.top) / 2;
1922  break;
1923  default:
1924  return;
1925  }
1926 
1927  switch( wParam )
1928  {
1929  case SB_LINEUP:
1930  newPos = curPos - shift;
1931  break;
1932  case SB_LINEDOWN:
1933  newPos = curPos + shift;
1934  break;
1935  case SB_PAGEUP:
1936  newPos = curPos - length;
1937  break;
1938  case SB_PAGEDOWN:
1939  newPos = curPos + length;
1940  break;
1941 
1942  case SB_THUMBPOSITION:
1943  newPos = LOWORD(lParam);
1944  break;
1945 
1946  case SB_THUMBTRACK:
1947  return;
1948 
1949  case SB_TOP:
1950  newPos = minPos;
1951  break;
1952  case SB_BOTTOM:
1953  newPos = maxPos;
1954  break;
1955  case SB_ENDSCROLL:
1957  return;
1958  }
1959 
1960  if( newPos > maxPos )
1961  newPos = maxPos;
1962  else
1963  if( newPos < minPos )
1964  newPos = minPos;
1965 
1966  SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
1967 
1968  if( uMsg == WM_VSCROLL )
1969  ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
1971  else
1972  ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
1974 }
1975 
1976 /******************************************************************************
1977  * CascadeWindows (USER32.@) Cascades MDI child windows
1978  *
1979  * RETURNS
1980  * Success: Number of cascaded windows.
1981  * Failure: 0
1982  */
1983 
1984 typedef struct CASCADE_INFO
1985 {
1994 } CASCADE_INFO;
1995 
1996 static BOOL CALLBACK
1998 {
1999  DWORD count, size;
2000  HWND *ahwnd;
2001  CASCADE_INFO *pInfo = (CASCADE_INFO *)lParam;
2002 
2003  if (hwnd == pInfo->hwndDesktop || hwnd == pInfo->hTrayWnd ||
2004  hwnd == pInfo->hwndProgman || hwnd == pInfo->hwndTop)
2005  {
2006  return TRUE;
2007  }
2008 
2009  if (pInfo->hwndParent && GetParent(hwnd) != pInfo->hwndParent)
2010  return TRUE;
2011 
2012  if ((pInfo->wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2013  return TRUE;
2014 
2015  if (!IsWindowVisible(hwnd) || IsIconic(hwnd))
2016  return TRUE;
2017 
2018  count = pInfo->chwnd;
2019  size = (count + 1) * sizeof(HWND);
2020 
2021  if (count == 0 || pInfo->ahwnd == NULL)
2022  {
2023  count = 0;
2024  pInfo->ahwnd = (HWND *)HeapAlloc(GetProcessHeap(), 0, size);
2025  }
2026  else
2027  {
2028  ahwnd = (HWND *)HeapReAlloc(GetProcessHeap(), 0, pInfo->ahwnd, size);
2029  if (ahwnd == NULL)
2030  {
2031  HeapFree(GetProcessHeap(), 0, pInfo->ahwnd);
2032  }
2033  pInfo->ahwnd = ahwnd;
2034  }
2035 
2036  if (pInfo->ahwnd == NULL)
2037  {
2038  pInfo->chwnd = 0;
2039  return FALSE;
2040  }
2041 
2042  pInfo->ahwnd[count] = hwnd;
2043  pInfo->chwnd = count + 1;
2044  return TRUE;
2045 }
2046 
2047 static BOOL
2049 {
2050  MINMAXINFO mmi;
2051  DWORD_PTR dwResult;
2052 
2053  mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 0;
2054  mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = MAXLONG;
2056  SMTO_ABORTIFHUNG | SMTO_NORMAL, 120, &dwResult))
2057  {
2058  *pcx = min(max(*pcx, mmi.ptMinTrackSize.x), mmi.ptMaxTrackSize.x);
2059  *pcy = min(max(*pcy, mmi.ptMinTrackSize.y), mmi.ptMaxTrackSize.y);
2060  return TRUE;
2061  }
2062  return FALSE;
2063 }
2064 
2065 WORD WINAPI
2067  UINT cKids, const HWND *lpKids)
2068 {
2070  HWND hwnd, hwndTop, hwndPrev;
2071  HMONITOR hMon;
2072  MONITORINFO mi;
2073  RECT rcWork, rcWnd;
2074  DWORD i, ret = 0;
2075  INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, dx, dy;
2076  HDWP hDWP;
2077  POINT pt;
2078 
2079  TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2080 
2081  hwndTop = GetTopWindow(hwndParent);
2082 
2083  ZeroMemory(&info, sizeof(info));
2084  info.hwndDesktop = GetDesktopWindow();
2085  info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2086  info.hwndProgman = FindWindowW(L"Progman", NULL);
2087  info.hwndParent = hwndParent;
2088  info.wFlags = wFlags;
2089 
2090  if (cKids == 0 || lpKids == NULL)
2091  {
2092  info.hwndTop = hwndTop;
2094 
2095  info.hwndTop = NULL;
2096  GetCascadeChildProc(hwndTop, (LPARAM)&info);
2097  }
2098  else
2099  {
2100  info.chwnd = cKids;
2101  info.ahwnd = (HWND *)lpKids;
2102  }
2103 
2104  if (info.chwnd == 0 || info.ahwnd == NULL)
2105  return ret;
2106 
2107  if (lpRect)
2108  {
2109  rcWork = *lpRect;
2110  }
2111  else if (hwndParent)
2112  {
2113  GetClientRect(hwndParent, &rcWork);
2114  }
2115  else
2116  {
2117  pt.x = pt.y = 0;
2118  hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2119  mi.cbSize = sizeof(mi);
2120  GetMonitorInfoW(hMon, &mi);
2121  rcWork = mi.rcWork;
2122  }
2123 
2124  hDWP = BeginDeferWindowPos(info.chwnd);
2125  if (hDWP == NULL)
2126  goto cleanup;
2127 
2128  x = rcWork.left;
2129  y = rcWork.top;
2132  cxWork = rcWork.right - rcWork.left;
2133  cyWork = rcWork.bottom - rcWork.top;
2134  hwndPrev = NULL;
2135  for (i = info.chwnd; i > 0;) /* in reverse order */
2136  {
2137  --i;
2138  hwnd = info.ahwnd[i];
2139 
2140  if (!IsWindowVisible(hwnd) || IsIconic(hwnd))
2141  continue;
2142 
2143  if ((info.wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2144  continue;
2145 
2146  if (IsZoomed(hwnd))
2148 
2149  GetWindowRect(hwnd, &rcWnd);
2150  cxNew = cx = rcWnd.right - rcWnd.left;
2151  cyNew = cy = rcWnd.bottom - rcWnd.top;
2152 
2153  /* if we can change the window size and it is not only one */
2154  if (info.chwnd != 1 && (GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_THICKFRAME))
2155  {
2156  /* check the size */
2157 #define MIN_THRESHOLD(xy) (((xy) * 4) / 7) /* in the rate 4/7 */
2158 #define MAX_THRESHOLD(xy) (((xy) * 5) / 7) /* in the rate 5/7 */
2159  cxNew = max(min(cxNew, MAX_THRESHOLD(cxWork)), MIN_THRESHOLD(cxWork));
2160  cyNew = max(min(cyNew, MAX_THRESHOLD(cyWork)), MIN_THRESHOLD(cyWork));
2161 #undef MIN_THRESHOLD
2162 #undef MAX_THRESHOLD
2163  if (cx != cxNew || cy != cyNew)
2164  {
2165  /* too large. shrink if we can */
2166  if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2167  {
2168  cx = cxNew;
2169  cy = cyNew;
2170  }
2171  }
2172  }
2173 
2174  if (x + cx > rcWork.right)
2175  x = rcWork.left;
2176  if (y + cy > rcWork.bottom)
2177  y = rcWork.top;
2178 
2179  hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2180  if (hDWP == NULL)
2181  {
2182  ret = 0;
2183  goto cleanup;
2184  }
2185 
2186  x += dx;
2187  y += dy;
2188  hwndPrev = hwnd;
2189  ++ret;
2190  }
2191 
2193 
2194  if (hwndPrev)
2195  SetForegroundWindow(hwndPrev);
2196 
2197 cleanup:
2198  if (cKids == 0 || lpKids == NULL)
2199  HeapFree(GetProcessHeap(), 0, info.ahwnd);
2200 
2201  return (WORD)ret;
2202 }
2203 
2204 
2205 /***********************************************************************
2206  * CascadeChildWindows (USER32.@)
2207  */
2209 {
2210  return CascadeWindows( parent, flags, NULL, 0, NULL );
2211 }
2212 
2213 
2214 /******************************************************************************
2215  * TileWindows (USER32.@) Tiles MDI child windows
2216  *
2217  * RETURNS
2218  * Success: Number of tiled windows.
2219  * Failure: 0
2220  */
2221 WORD WINAPI
2223  UINT cKids, const HWND *lpKids)
2224 {
2225  HWND hwnd, hwndTop, hwndPrev;
2227  RECT rcWork, rcWnd;
2228  DWORD i, iRow, iColumn, cRows, cColumns, ret = 0;
2229  INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, cxCell, cyCell, cxMin2, cyMin3;
2230  HDWP hDWP;
2231  MONITORINFO mi;
2232  HMONITOR hMon;
2233  POINT pt;
2234 
2235  TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2236 
2237  hwndTop = GetTopWindow(hwndParent);
2238 
2239  ZeroMemory(&info, sizeof(info));
2240  info.hwndDesktop = GetDesktopWindow();
2241  info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2242  info.hwndProgman = FindWindowW(L"Progman", NULL);
2243  info.hwndParent = hwndParent;
2244  info.wFlags = wFlags;
2245 
2246  if (cKids == 0 || lpKids == NULL)
2247  {
2248  info.hwndTop = hwndTop;
2250 
2251  info.hwndTop = NULL;
2252  GetCascadeChildProc(hwndTop, (LPARAM)&info);
2253  }
2254  else
2255  {
2256  info.chwnd = cKids;
2257  info.ahwnd = (HWND *)lpKids;
2258  }
2259 
2260  if (info.chwnd == 0 || info.ahwnd == NULL)
2261  return ret;
2262 
2263  if (lpRect)
2264  {
2265  rcWork = *lpRect;
2266  }
2267  else if (hwndParent)
2268  {
2269  GetClientRect(hwndParent, &rcWork);
2270  }
2271  else
2272  {
2273  pt.x = pt.y = 0;
2274  hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2275  mi.cbSize = sizeof(mi);
2276  GetMonitorInfoW(hMon, &mi);
2277  rcWork = mi.rcWork;
2278  }
2279 
2280  cxWork = rcWork.right - rcWork.left;
2281  cyWork = rcWork.bottom - rcWork.top;
2282 
2283  cxMin2 = GetSystemMetrics(SM_CXMIN) * 2;
2284  cyMin3 = GetSystemMetrics(SM_CYMIN) * 3;
2285 
2286  /* calculate the numbers and widths of columns and rows */
2287  if (info.wFlags & MDITILE_HORIZONTAL)
2288  {
2289  cColumns = info.chwnd;
2290  cRows = 1;
2291  for (;;)
2292  {
2293  cxCell = cxWork / cColumns;
2294  cyCell = cyWork / cRows;
2295  if (cyCell <= cyMin3 || cxCell >= cxMin2)
2296  break;
2297 
2298  ++cRows;
2299  cColumns = (info.chwnd + cRows - 1) / cRows;
2300  }
2301  }
2302  else
2303  {
2304  cRows = info.chwnd;
2305  cColumns = 1;
2306  for (;;)
2307  {
2308  cxCell = cxWork / cColumns;
2309  cyCell = cyWork / cRows;
2310  if (cxCell <= cxMin2 || cyCell >= cyMin3)
2311  break;
2312 
2313  ++cColumns;
2314  cRows = (info.chwnd + cColumns - 1) / cColumns;
2315  }
2316  }
2317 
2318  hDWP = BeginDeferWindowPos(info.chwnd);
2319  if (hDWP == NULL)
2320  goto cleanup;
2321 
2322  x = rcWork.left;
2323  y = rcWork.top;
2324  hwndPrev = NULL;
2325  iRow = iColumn = 0;
2326  for (i = info.chwnd; i > 0;) /* in reverse order */
2327  {
2328  --i;
2329  hwnd = info.ahwnd[i];
2330 
2331  if (IsZoomed(hwnd))
2333 
2334  GetWindowRect(hwnd, &rcWnd);
2335  cx = rcWnd.right - rcWnd.left;
2336  cy = rcWnd.bottom - rcWnd.top;
2337 
2338  /* if we can change the window size */
2340  {
2341  cxNew = cxCell;
2342  cyNew = cyCell;
2343  /* shrink if we can */
2344  if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2345  {
2346  cx = cxNew;
2347  cy = cyNew;
2348  }
2349  }
2350 
2351  hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2352  if (hDWP == NULL)
2353  {
2354  ret = 0;
2355  goto cleanup;
2356  }
2357 
2358  if (info.wFlags & MDITILE_HORIZONTAL)
2359  {
2360  x += cxCell;
2361  ++iColumn;
2362  if (iColumn >= cColumns)
2363  {
2364  iColumn = 0;
2365  ++iRow;
2366  x = rcWork.left;
2367  y += cyCell;
2368  }
2369  }
2370  else
2371  {
2372  y += cyCell;
2373  ++iRow;
2374  if (iRow >= cRows)
2375  {
2376  iRow = 0;
2377  ++iColumn;
2378  x += cxCell;
2379  y = rcWork.top;
2380  }
2381  }
2382  hwndPrev = hwnd;
2383  ++ret;
2384  }
2385 
2387 
2388  if (hwndPrev)
2389  SetForegroundWindow(hwndPrev);
2390 
2391 cleanup:
2392  if (cKids == 0 || lpKids == NULL)
2393  HeapFree(GetProcessHeap(), 0, info.ahwnd);
2394 
2395  return (WORD)ret;
2396 }
2397 
2398 
2399 /***********************************************************************
2400  * TileChildWindows (USER32.@)
2401  */
2403 {
2404  return TileWindows( parent, flags, NULL, 0, NULL );
2405 }
2406 
2407 
2408 /************************************************************************
2409  * "More Windows..." functionality
2410  */
2411 
2412 /* MDI_MoreWindowsDlgProc
2413  *
2414  * This function will process the messages sent to the "More Windows..."
2415  * dialog.
2416  * Return values: 0 = cancel pressed
2417  * HWND = ok pressed or double-click in the list...
2418  *
2419  */
2420 
2422 {
2423  switch (iMsg)
2424  {
2425  case WM_INITDIALOG:
2426  {
2427  UINT widest = 0;
2428  UINT length;
2429  UINT i;
2432 
2433  for (i = 0; i < ci->nActiveChildren; i++)
2434  {
2436 
2437  if (!InternalGetWindowText( ci->child[i], buffer, sizeof(buffer)/sizeof(WCHAR) ))
2438  continue;
2441  length = strlenW(buffer); /* FIXME: should use GetTextExtentPoint */
2442  if (length > widest)
2443  widest = length;
2444  }
2445  /* Make sure the horizontal scrollbar scrolls ok */
2446  SendMessageW(hListBox, LB_SETHORIZONTALEXTENT, widest * 6, 0);
2447 
2448  /* Set the current selection */
2450  return TRUE;
2451  }
2452 
2453  case WM_COMMAND:
2454  switch (LOWORD(wParam))
2455  {
2456  default:
2457  if (HIWORD(wParam) != LBN_DBLCLK) break;
2458  /* fall through */
2459  case IDOK:
2460  {
2461  /* windows are sorted by menu ID, so we must return the
2462  * window associated to the given id
2463  */
2467  EndDialog(hDlg, res);
2468  return TRUE;
2469  }
2470  case IDCANCEL:
2471  EndDialog(hDlg, 0);
2472  return TRUE;
2473  }
2474  break;
2475  }
2476  return FALSE;
2477 }
2478 
2479 /*
2480  *
2481  * MDI_MoreWindowsDialog
2482  *
2483  * Prompts the user with a listbox containing the opened
2484  * documents. The user can then choose a windows and click
2485  * on OK to set the current window to the one selected, or
2486  * CANCEL to cancel. The function returns a handle to the
2487  * selected window.
2488  */
2489 
2491 {
2492  LPCVOID template;
2493  HRSRC hRes;
2494  HANDLE hDlgTmpl;
2495 
2496  hRes = FindResourceA(User32Instance, "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
2497 
2498  if (hRes == 0)
2499  return 0;
2500 
2501  hDlgTmpl = LoadResource(User32Instance, hRes );
2502 
2503  if (hDlgTmpl == 0)
2504  return 0;
2505 
2506  template = LockResource( hDlgTmpl );
2507 
2508  if (template == 0)
2509  return 0;
2510 
2511  return (HWND) DialogBoxIndirectParamA(User32Instance, template, hwnd,
2513 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define LB_SETCURSEL
Definition: winuser.h:2053
POINT ptMinTrackSize
Definition: winuser.h:3620
BOOL WINAPI EnumChildWindows(_In_opt_ HWND, _In_ WNDENUMPROC, _In_ LPARAM)
HMONITOR WINAPI MonitorFromPoint(POINT, DWORD)
HMENU hWindowMenu
Definition: mdi.c:120
#define WS_DISABLED
Definition: pedump.c:621
BOOL WINAPI GetScrollRange(_In_ HWND, _In_ int, _Out_ LPINT, _Out_ LPINT)
#define WS_THICKFRAME
Definition: pedump.c:630
#define SB_PAGEDOWN
Definition: winuser.h:569
#define SWP_DRAWFRAME
Definition: winuser.h:1229
static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext, DWORD dwStyleMask)
Definition: mdi.c:268
#define SB_PAGEUP
Definition: winuser.h:568
#define max(a, b)
Definition: svc.c:63
Definition: tftpd.h:59
static HICON
Definition: imagelist.c:84
HDWP WINAPI BeginDeferWindowPos(_In_ int)
#define MF_DISABLED
Definition: winuser.h:130
#define SM_CYHSCROLL
Definition: winuser.h:956
DWORD cbSize
Definition: winuser.h:3756
UINT wFlags
Definition: mdi.c:1987
#define IDOK
Definition: winuser.h:824
static void MDI_UpdateFrameText(HWND, HWND, BOOL, LPCWSTR)
Definition: mdi.c:1028
#define shift
Definition: input.c:1756
#define IMAGE_ICON
Definition: winuser.h:212
BOOL WINAPI DrawMenuBar(_In_ HWND)
#define SC_KEYMENU
Definition: winuser.h:2586
#define SM_CYSIZE
Definition: winuser.h:986
static MDICLIENTINFO * get_client_info(HWND client)
Definition: mdi.c:225
#define SIF_RANGE
Definition: winuser.h:1225
#define MF_BYCOMMAND
Definition: winuser.h:202
HWND hwndProgman
Definition: mdi.c:1991
HWND hwndMDIClient
Definition: mmc.c:26
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static HBITMAP CreateMDIMenuBitmap(void)
Definition: mdi.c:688
#define SC_RESTORE
Definition: winuser.h:2588
#define SW_SHOWNOACTIVATE
Definition: winuser.h:768
long y
Definition: polytest.cpp:48
HWND hwndChildMaximized
Definition: mdi.c:116
#define WM_LBUTTONDOWN
Definition: winuser.h:1766
#define MNC_CLOSE
Definition: winuser.h:2557
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2054
#define VK_F6
Definition: winuser.h:2250
POINT ptMaxSize
Definition: winuser.h:3618
#define Y(I)
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define LB_ADDSTRING
Definition: winuser.h:2021
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define MAXLONG
Definition: umtypes.h:116
long x
Definition: polytest.cpp:48
#define WM_MENUCHAR
Definition: winuser.h:1738
HDC WINAPI GetDC(_In_opt_ HWND)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define SB_VERT
Definition: winuser.h:553
POINT last
Definition: font.c:46
#define SIZE_MAXIMIZED
Definition: winuser.h:2497
static HTREEITEM hChild
Definition: treeview.c:381
#define TRUE
Definition: types.h:120
#define HBMMENU_MBAR_CLOSE_D
Definition: winuser.h:2625
#define pt(x, y)
Definition: drawing.c:79
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
DWORD chwnd
Definition: mdi.c:1993
#define SW_HIDE
Definition: winuser.h:762
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define MAKELRESULT(l, h)
Definition: winuser.h:4000
static LRESULT MDISetMenu(HWND hwnd, HMENU hmenuFrame, HMENU hmenuWindow)
Definition: mdi.c:336
const WCHAR * text
Definition: package.c:1799
#define CP_ACP
Definition: compat.h:109
#define LB_GETITEMDATA
Definition: winuser.h:2031
HWND hTrayWnd
Definition: mdi.c:1990
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
#define SB_HORZ
Definition: winuser.h:552
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
#define WM_MDICASCADE
Definition: winuser.h:1809
UINT WINAPI GetMenuState(_In_ HMENU, _In_ UINT, _In_ UINT)
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
UINT WINAPI ArrangeIconicWindows(_In_ HWND)
#define WM_SETREDRAW
Definition: winuser.h:1606
#define MF_STRING
Definition: winuser.h:138
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)
HWND hWnd
Definition: settings.c:17
GLdouble n
Definition: glext.h:7729
LONG top
Definition: windef.h:307
BOOL NTAPI NtUserEndDeferWindowPosEx(HDWP WinPosInfo, BOOL bAsync)
Definition: winpos.c:3192
HANDLE HWND
Definition: compat.h:19
#define CS_NOCLOSE
Definition: winuser.h:649
struct CASCADE_INFO CASCADE_INFO
#define VK_LEFT
Definition: winuser.h:2214
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define WM_SHOWWINDOW
Definition: winuser.h:1618
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
BOOL WINAPI AdjustWindowRectEx(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define ZeroMemory
Definition: winbase.h:1670
#define HBMMENU_MBAR_MINIMIZE
Definition: winuser.h:2623
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define WS_SIZEBOX
Definition: pedump.c:642
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
#define GWL_EXSTYLE
Definition: winuser.h:845
#define HWND_TOP
Definition: winuser.h:1197
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
GLuint buffer
Definition: glext.h:5915
#define SM_CYSMICON
Definition: winuser.h:1007
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define COLOR_APPWORKSPACE
Definition: winuser.h:919
HWND WINAPI SetFocus(_In_opt_ HWND)
LPWSTR dwTypeData
Definition: winuser.h:3259
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
static INT_PTR WINAPI MDI_MoreWindowsDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:2421
static MONITORINFO mi
Definition: win.c:7338
#define MFT_BITMAP
Definition: winuser.h:733
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
Definition: mdi.c:1760
#define VK_TAB
Definition: winuser.h:2189
#define GWLP_MDIWND
Definition: ntuser.h:781
#define VK_MENU
Definition: winuser.h:2194
#define GetWindowLongPtrW
Definition: winuser.h:4819
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1237
#define SM_CYFRAME
Definition: winuser.h:990
#define FNID_DESTROY
Definition: ntuser.h:893
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MDISETMENU
Definition: winuser.h:1812
int32_t INT_PTR
Definition: typedefs.h:64
HBITMAP hBmpClose
Definition: mdi.c:126
char * LPSTR
Definition: xmlstorage.h:182
#define MIN_THRESHOLD(xy)
#define SW_RESTORE
Definition: winuser.h:773
LONG right
Definition: windef.h:308
WORD WINAPI TileChildWindows(HWND parent, UINT flags)
Definition: mdi.c:2402
BOOL WINAPI IsIconic(_In_ HWND)
UINT sbRecalc
Definition: mdi.c:125
#define WM_NCCREATE
Definition: winuser.h:1673
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
HINSTANCE User32Instance
Definition: dllmain.c:27
int32_t INT
Definition: typedefs.h:58
#define SIF_PAGE
Definition: winuser.h:1223
static void MDI_SwitchActiveChild(MDICLIENTINFO *ci, HWND hwndTo, BOOL activate)
Definition: mdi.c:534
static HWND child
Definition: cursoricon.c:298
& rect
Definition: startmenu.cpp:1413
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
#define MIIM_BITMAP
Definition: winuser.h:723
HWND WINAPI GetTopWindow(_In_opt_ HWND)
#define SMTO_ABORTIFHUNG
Definition: winuser.h:1213
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define lstrcpynW
Definition: compat.h:738
#define SMTO_NORMAL
Definition: winuser.h:1215
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2218
#define HBMMENU_MBAR_CLOSE
Definition: winuser.h:2624
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define ICON_SMALL
Definition: tnclass.cpp:48
void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1900
static BOOL QuerySizeFix(HWND hwnd, LPINT pcx, LPINT pcy)
Definition: mdi.c:2048
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:1736
struct tagCREATESTRUCTA * LPCREATESTRUCTA
#define WM_NEXTMENU
Definition: winuser.h:1796
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static HWND MDI_GetChildByID(HWND hwnd, UINT id, MDICLIENTINFO *ci)
Definition: mdi.c:187
#define GCL_STYLE
Definition: winuser.h:665
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
WORD WINAPI CascadeChildWindows(HWND parent, UINT flags)
Definition: mdi.c:2208
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define WM_MDIICONARRANGE
Definition: winuser.h:1810
uint32_t cs
Definition: isohybrid.c:75
HINSTANCE hInstance
Definition: charmap.c:19
#define WS_EX_MDICHILD
Definition: winuser.h:394
#define L(x)
Definition: ntvdm.h:50
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
HWND hwndActiveChild
Definition: mdi.c:117
#define VK_RBUTTON
Definition: winuser.h:2181
#define FALSE
Definition: types.h:117
#define WM_NCACTIVATE
Definition: winuser.h:1678
LRESULT WINAPI MDIClientWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1361
#define WS_MINIMIZE
Definition: pedump.c:622
#define WM_PARENTNOTIFY
Definition: winuser.h:1793
WINE_DEFAULT_DEBUG_CHANNEL(mdi)
#define WM_CHILDACTIVATE
Definition: winuser.h:1628
unsigned int BOOL
Definition: ntddk_ex.h:94
LRESULT WINAPI DefMDIChildProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1542
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2172
long LONG
Definition: pedump.c:60
int WINAPI SetMapMode(_In_ HDC, _In_ int)
LRESULT WINAPI MDIClientWndProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1352
#define MF_BYPOSITION
Definition: winuser.h:203
static struct _test_info info[]
Definition: SetCursorPos.c:19
#define MDITILE_HORIZONTAL
Definition: winuser.h:2178
#define debugstr_w
Definition: kernel32.h:32
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define WM_SYSCHAR
Definition: winuser.h:1711
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
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:1708
UINT mdiFlags
Definition: mdi.c:124
#define HBMMENU_MBAR_RESTORE
Definition: winuser.h:2622
#define VK_F4
Definition: winuser.h:2248
#define SW_ERASE
Definition: winuser.h:2570
#define SC_MAXIMIZE
Definition: winuser.h:2578
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:585
#define VK_SHIFT
Definition: winuser.h:2192
int nItems
Definition: appswitch.c:56
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
NTSTATUS NTAPI NtUserBuildHwndList(HDESK hDesktop, HWND hwndParent, BOOLEAN bChildren, ULONG dwThreadId, ULONG cHwnd, HWND *phwndList, ULONG *pcHwndNeeded)
Definition: window.c:1504
#define WM_MDICALCCHILDSCROLL
Definition: mdi.c:90
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
#define WM_MDINEXT
Definition: winuser.h:1806
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
static HWND hwndParent
Definition: cryptui.c:300
#define COLOR_MENU
Definition: winuser.h:911
#define SM_CYSIZEFRAME
Definition: winuser.h:989
HMENU hmenuIn
Definition: winuser.h:3625
#define SB_THUMBPOSITION
Definition: winuser.h:572
#define WM_KEYDOWN
Definition: winuser.h:1705
#define MF_SEPARATOR
Definition: winuser.h:137
LONG_PTR LPARAM
Definition: windef.h:208
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
#define SB_ENDSCROLL
Definition: winuser.h:574
#define FNID_MDICLIENT
Definition: ntuser.h:867
#define SM_CYMIN
Definition: winuser.h:984
#define WM_SETTEXT
Definition: winuser.h:1607
static BOOL MDI_RestoreFrameMenu(HWND, HWND, HBITMAP)
Definition: mdi.c:963
#define IDS_MDI_MOREWINDOWS
Definition: mdi.c:96
static HWND MDI_MoreWindowsDialog(HWND)
Definition: mdi.c:2490
#define WM_DESTROY
Definition: winuser.h:1599
#define MIIM_ID
Definition: winuser.h:717
#define RT_DIALOG
Definition: pedump.c:367
SHORT WINAPI GetKeyState(_In_ int)
#define SM_CXSIZEFRAME
Definition: winuser.h:987
#define DC_ACTIVE
Definition: winuser.h:427
#define GetWindowLongPtrA
Definition: winuser.h:4818
LRESULT WINAPI DefFrameProcA(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1370
Status
Definition: gdiplustypes.h:24
BOOL WINAPI InsertMenuA(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
#define MF_CHECKED
Definition: winuser.h:132
#define GCLP_HICONSM
Definition: winuser.h:670
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define HWND_BOTTOM
Definition: winuser.h:1195
#define TRACE(s)
Definition: solgame.cpp:4
HWND hwndDesktop
Definition: mdi.c:1989
GLsizeiptr size
Definition: glext.h:5919
HDWP WINAPI DeferWindowPos(_In_ HDWP, _In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define GetProcessHeap()
Definition: compat.h:736
#define SM_CYCAPTION
Definition: winuser.h:957
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MDI_MAXTITLELENGTH
Definition: mdi.c:88
r parent
Definition: btrfs.c:3010
#define MDITILE_SKIPDISABLED
Definition: winuser.h:2177
UINT nTotalCreated
Definition: mdi.c:123
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
HWND WINAPI FindWindowW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SB_THUMBTRACK
Definition: winuser.h:573
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:1997
#define WM_SIZE
Definition: winuser.h:1601
#define debugstr_a
Definition: kernel32.h:31
static void MDITile(HWND client, MDICLIENTINFO *ci, WPARAM wParam)
Definition: mdi.c:780
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
BOOL WINAPI SetMenu(_In_ HWND, _In_opt_ HMENU)
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define SWP_NOACTIVATE
Definition: winuser.h:1232
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define WM_CLOSE
Definition: winuser.h:1611
#define WM_NCDESTROY
Definition: winuser.h:1674
#define WINAPI
Definition: msvc.h:6
const GLubyte * c
Definition: glext.h:8905
const char * wine_dbgstr_rect(const RECT *rect)
#define IDI_WINLOGO
Definition: winuser.h:704
static FILE * client
Definition: client.c:41
unsigned short WORD
Definition: ntddk_ex.h:93
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
static LRESULT MDI_RefreshMenu(MDICLIENTINFO *)
Definition: mdi.c:412
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SetLastError(x)
Definition: compat.h:752
#define SIZE_MINIMIZED
Definition: winuser.h:2496
BOOL WINAPI UnionRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define LB_SETITEMDATA
Definition: winuser.h:2055
#define LBN_DBLCLK
Definition: winuser.h:2061
#define WS_HSCROLL
Definition: pedump.c:628
GLbitfield flags
Definition: glext.h:7161
#define SC_PREVWINDOW
Definition: winuser.h:2581
HWND hwndTop
Definition: mdi.c:1986
#define SM_CXSMICON
Definition: winuser.h:1006
INT_PTR WINAPI DialogBoxIndirectParamA(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
LRESULT WINAPI MDIClientWndProc_common(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: mdi.c:1098
#define WM_MDIGETACTIVE
Definition: winuser.h:1811
POINT ptMaxPosition
Definition: winuser.h:3619
int ret
#define MF_POPUP
Definition: winuser.h:136
#define SM_CYICON
Definition: winuser.h:967
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define SM_CYICONSPACING
Definition: winuser.h:996
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)
HDC hdc
Definition: main.c:9
#define GCLP_HICON
Definition: winuser.h:669
void WINAPI CalcChildScroll(HWND hwnd, INT scroll)
Definition: mdi.c:1801
#define MIIM_TYPE
Definition: winuser.h:720
HWND hwndParent
Definition: mdi.c:1988
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define DI_NORMAL
Definition: wingdi.h:72
#define SWP_FRAMECHANGED
Definition: winuser.h:1230
#define WM_SETVISIBLE
Definition: undocuser.h:31
#define MAX_THRESHOLD(xy)
Definition: _list.h:228
#define SB_BOTH
Definition: winuser.h:555
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI IsMenu(_In_ HMENU)
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_COMMAND
Definition: winuser.h:1730
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_MDIACTIVATE
Definition: winuser.h:1804
#define MF_BITMAP
Definition: winuser.h:131
HWND * WIN_ListChildren(HWND hWndparent)
Definition: mdi.c:140
uint32_t DWORD_PTR
Definition: typedefs.h:65
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
#define SW_SHOWNA
Definition: winuser.h:772
#define WM_MDIDESTROY
Definition: winuser.h:1803
#define MDI_IDC_LISTBOX
Definition: mdi.c:95
struct tagCLIENTCREATESTRUCT * LPCLIENTCREATESTRUCT
#define SW_INVALIDATE
Definition: winuser.h:2569
BOOL WINAPI DestroyMenu(_In_ HMENU)
struct _MDIWND MDIWND
#define SIF_POS
Definition: winuser.h:1224
HMENU hmenuNext
Definition: winuser.h:3626
#define VK_RIGHT
Definition: winuser.h:2216
#define SC_MINIMIZE
Definition: winuser.h:2576
static LONG MDI_ChildActivate(HWND, HWND)
Definition: mdi.c:639
#define SWP_NOSIZE
Definition: winuser.h:1235
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
#define ERR(fmt,...)
Definition: debug.h:110
#define GWL_STYLE
Definition: winuser.h:846
Definition: ntuser.h:688
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
WORD WINAPI TileWindows(HWND hwndParent, UINT wFlags, LPCRECT lpRect, UINT cKids, const HWND *lpKids)
Definition: mdi.c:2222
#define SB_TOP
Definition: winuser.h:578
#define SW_SHOWNORMAL
Definition: winuser.h:764
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define WM_MDIREFRESHMENU
Definition: winuser.h:1816
static unsigned __int64 next
Definition: rand_nt.c:6
BOOL WINAPI GetWindowInfo(_In_ HWND, _Inout_ PWINDOWINFO)
LONG reserved
Definition: mdi.c:114
#define WM_MDIRESTORE
Definition: winuser.h:1805
static real win[4][36]
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
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
BOOL WINAPI DeleteDC(_In_ HDC)
#define MDIF_NEEDUPDATE
Definition: mdi.c:98
INT WINAPI InternalGetWindowText(_In_ HWND hWnd, _Out_writes_to_(cchMaxCount, return+1) LPWSTR pString, _In_ int cchMaxCount)
#define BLACK_PEN
Definition: wingdi.h:903
static LRESULT MDIDestroyChild(HWND client, MDICLIENTINFO *ci, HWND child, BOOL flagDestroy)
Definition: mdi.c:567
HICON hIcon
Definition: msconfig.c:44
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2132
DWORD cbSize
Definition: winuser.h:3774
BOOL WINAPI RemoveMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SC_SIZE
Definition: winuser.h:2574
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:734
static LONG MDICascade(HWND client, MDICLIENTINFO *ci)
Definition: mdi.c:722
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
static BOOL MDI_AugmentFrameMenu(HWND, HWND)
Definition: mdi.c:870
#define list
Definition: rosglue.h:35
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define min(a, b)
Definition: monoChain.cc:55
#define LB_GETCURSEL
Definition: winuser.h:2029
unsigned int UINT
Definition: ndis.h:50
#define SB_LINEDOWN
Definition: winuser.h:565
BOOL WINAPI IsZoomed(_In_ HWND)
#define NULL
Definition: types.h:112
#define WM_HSCROLL
Definition: winuser.h:1733
#define VK_SPACE
Definition: winuser.h:2209
#define SB_LINEUP
Definition: winuser.h:564
#define SB_BOTTOM
Definition: winuser.h:577
#define WS_VSCROLL
Definition: pedump.c:627
#define GW_OWNER
Definition: winuser.h:761
#define SW_SCROLLCHILDREN
Definition: winuser.h:2568
#define SM_CXVSCROLL
Definition: winuser.h:955
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
size_t total
GLint dx
Definition: linetemp.h:97
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define MultiByteToWideChar
Definition: compat.h:110
LRESULT WINAPI SendMessageTimeoutW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define VK_CONTROL
Definition: winuser.h:2193
#define WM_MDICREATE
Definition: winuser.h:1802
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
CONST void * LPCVOID
Definition: windef.h:191
static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
Definition: mdi.c:249
#define SC_MOVE
Definition: winuser.h:2575
_Out_opt_ int * cx
Definition: commctrl.h:585
#define SC_CLOSE
Definition: winuser.h:2582
#define MM_TEXT
Definition: wingdi.h:873
#define WM_CREATE
Definition: winuser.h:1598
#define SM_CXSIZE
Definition: winuser.h:985
GLuint res
Definition: glext.h:9613
DWORD_PTR NTAPI NtUserCallTwoParam(DWORD_PTR Param1, DWORD_PTR Param2, DWORD Routine)
Definition: simplecall.c:434
HWND WINAPI ChildWindowFromPoint(_In_ HWND, _In_ POINT)
#define WM_SYSKEYDOWN
Definition: winuser.h:1709
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)
TCHAR lpTitle[80]
Definition: ctm.c:69
#define c
Definition: ke_i.h:80
#define HIWORD(l)
Definition: typedefs.h:247
GLenum GLuint id
Definition: glext.h:5579
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
LONG bottom
Definition: windef.h:309
BOOL NTAPI NtUserSetWindowFNID(HWND hWnd, WORD fnID)
Definition: window.c:4336
static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO *ci, WORD recalc)
Definition: mdi.c:199
char * cleanup(char *str)
Definition: wpickclick.c:99
#define SWP_NOMOVE
Definition: winuser.h:1234
HWND * child
Definition: mdi.c:118
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SetWindowLongPtrW
Definition: winuser.h:5336
static HBITMAP
Definition: button.c:44
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define MDI_MOREWINDOWSLIMIT
Definition: mdi.c:93
RECT rcClient
Definition: winuser.h:3758
#define SC_NEXTWINDOW
Definition: winuser.h:2580
#define OBM_OLD_CLOSE
Definition: winuser.h:1135
POINT ptMaxTrackSize
Definition: winuser.h:3621
#define MF_HELP
Definition: winuser.h:142
#define GetWindowLongPtr
Definition: treelist.c:73
#define WM_SETFOCUS
Definition: winuser.h:1603
#define MF_GRAYED
Definition: winuser.h:129
LPWSTR frameTitle
Definition: mdi.c:122
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
UINT idFirstChild
Definition: mdi.c:121
#define MIIM_DATA
Definition: winuser.h:721
LONG_PTR LRESULT
Definition: windef.h:209
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
static void MDI_ChildGetMinMaxInfo(HWND client, HWND hwnd, MINMAXINFO *lpMinMax)
Definition: mdi.c:511
UINT nActiveChildren
Definition: mdi.c:115
#define LR_DEFAULTCOLOR
Definition: winuser.h:1081
Arabic default style
Definition: afstyles.h:93
#define WS_VISIBLE
Definition: pedump.c:620
HBRUSH WINAPI GetSysColorBrush(_In_ int)
WORD WINAPI CascadeWindows(HWND hwndParent, UINT wFlags, LPCRECT lpRect, UINT cKids, const HWND *lpKids)
Definition: mdi.c:2066
#define memset(x, y, z)
Definition: compat.h:39
HWND hListBox
Definition: enumfonts.cpp:27
void MDI_CalcDefaultChildPos(HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id)
Definition: mdi.c:309
HMENU WINAPI GetMenu(_In_ HWND)
#define SW_MAXIMIZE
Definition: winuser.h:766
HWND * ahwnd
Definition: mdi.c:1992
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define WM_SYSCOMMAND
Definition: winuser.h:1731
LRESULT WINAPI DefMDIChildProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1501
#define WM_INITDIALOG
Definition: winuser.h:1729
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
static HBITMAP hBitmap
Definition: timezone.c:26
LRESULT WINAPI DefFrameProcW(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1404
LPARAM lParam
Definition: combotst.c:139
#define WM_GETMINMAXINFO
Definition: winuser.h:1630
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
#define LOWORD(l)
Definition: pedump.c:82
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define HeapFree(x, y, z)
Definition: compat.h:735
#define GetClassLongPtrW
Definition: winuser.h:4554
#define GWLP_ID
Definition: winuser.h:854
#define SRCCOPY
Definition: wingdi.h:333
const struct builtin_class_descr MDICLIENT_builtin_class
Definition: mdi.c:213
static BOOL CALLBACK GetCascadeChildProc(HWND hwnd, LPARAM lParam)
Definition: mdi.c:1997
#define WIN_GetFullHandle(h)
Definition: user_x.h:108
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
#define WM_MDITILE
Definition: winuser.h:1808
#define ICON_BIG
Definition: tnclass.cpp:51
#define WM_VSCROLL
Definition: winuser.h:1734
HMENU hFrameMenu
Definition: mdi.c:119
int * LPINT
Definition: windef.h:178
#define SM_CXMIN
Definition: winuser.h:983
#define WM_MDIMAXIMIZE
Definition: winuser.h:1807
#define WS_MAXIMIZE
Definition: pedump.c:623