ReactOS  0.4.14-dev-606-g14ebc0b
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, 0, 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, 0, 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  HBRUSH hBrush;
923  HDC hdc = GetDC(hChild);
924 
925  if (hdc)
926  {
927  int cx, cy;
930  hMemDC = CreateCompatibleDC(hdc);
932  hOldBitmap = SelectObject(hMemDC, hBitmap);
933  SetMapMode(hMemDC, MM_TEXT);
935  DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
936  SelectObject (hMemDC, hOldBitmap);
937  DeleteObject(hBrush);
938  DeleteDC(hMemDC);
939  ReleaseDC(hChild, hdc);
940  hSysMenuBitmap = hBitmap;
941  }
942  }
943 
945  (UINT_PTR)hSysPopup, (LPSTR)hSysMenuBitmap))
946  {
947  TRACE("not inserted\n");
948  DestroyMenu(hSysPopup);
949  return FALSE;
950  }
951 
955  SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
956 
957  /* redraw menu */
958  DrawMenuBar(frame);
959 
960  return TRUE;
961 }
962 
963 /**********************************************************************
964  * MDI_RestoreFrameMenu
965  */
966 static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild, HBITMAP hBmpClose )
967 {
968  MENUITEMINFOW menuInfo;
969  HMENU menu = GetMenu( frame );
970  INT nItems;
971  UINT iId;
972 
973  TRACE("frame %p,child %p\n",frame, hChild);
974 
975  if (!menu) return FALSE;
976 
977  /* if there is no system buttons then nothing to do */
978  nItems = GetMenuItemCount(menu) - 1;
979  iId = GetMenuItemID(menu, nItems);
980  if ( !(iId == SC_RESTORE || iId == SC_CLOSE) )
981  {
982  ERR("no system buttons then nothing to do\n");
983  return FALSE;
984  }
985 
986  /*
987  * Remove the system menu, If that menu is the icon of the window
988  * as it is in win95, we have to delete the bitmap.
989  */
990  memset(&menuInfo, 0, sizeof(menuInfo));
991  menuInfo.cbSize = sizeof(menuInfo);
992  menuInfo.fMask = MIIM_DATA | MIIM_TYPE | MIIM_BITMAP;
993 
994  GetMenuItemInfoW(menu,
995  0,
996  TRUE,
997  &menuInfo);
998 
999  RemoveMenu(menu,0,MF_BYPOSITION);
1000 
1001  if ( (menuInfo.fType & MFT_BITMAP) &&
1002  (menuInfo.dwTypeData != 0) &&
1003  (menuInfo.dwTypeData != (LPWSTR)hBmpClose) )
1004  {
1005  DeleteObject(menuInfo.dwTypeData);
1006  }
1007 
1008  if ( menuInfo.hbmpItem != 0 )
1009  DeleteObject(menuInfo.hbmpItem);
1010 
1011  /* close */
1013  /* restore */
1015  /* minimize */
1017 
1018  DrawMenuBar(frame);
1019 
1020  return TRUE;
1021 }
1022 
1023 
1024 /**********************************************************************
1025  * MDI_UpdateFrameText
1026  *
1027  * used when child window is maximized/restored
1028  *
1029  * Note: lpTitle can be NULL
1030  */
1031 static void MDI_UpdateFrameText( HWND frame, HWND hClient, BOOL repaint, LPCWSTR lpTitle )
1032 {
1034  MDICLIENTINFO *ci = get_client_info( hClient );
1035 
1036  TRACE("frameText %s\n", debugstr_w(lpTitle));
1037 
1038  if (!ci) return;
1039 
1040  if (!lpTitle && !ci->frameTitle) /* first time around, get title from the frame window */
1041  {
1042  GetWindowTextW( frame, lpBuffer, sizeof(lpBuffer)/sizeof(WCHAR) );
1043  lpTitle = lpBuffer;
1044  }
1045 
1046  /* store new "default" title if lpTitle is not NULL */
1047  if (lpTitle)
1048  {
1049  HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1050  if ((ci->frameTitle = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpTitle)+1)*sizeof(WCHAR))))
1051  strcpyW( ci->frameTitle, lpTitle );
1052  }
1053 
1054  if (ci->frameTitle)
1055  {
1056  if (ci->hwndChildMaximized)
1057  {
1058  /* combine frame title and child title if possible */
1059 
1060  static const WCHAR lpBracket[] = {' ','-',' ','[',0};
1061  static const WCHAR lpBracket2[] = {']',0};
1062  int i_frame_text_length = strlenW(ci->frameTitle);
1063 
1065 
1066  if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
1067  {
1068  strcatW( lpBuffer, lpBracket );
1069  if (GetWindowTextW( ci->hwndActiveChild, lpBuffer + i_frame_text_length + 4,
1070  MDI_MAXTITLELENGTH - i_frame_text_length - 5 ))
1071  strcatW( lpBuffer, lpBracket2 );
1072  else
1073  lpBuffer[i_frame_text_length] = 0; /* remove bracket */
1074  }
1075  }
1076  else
1077  {
1079  }
1080  }
1081  else
1082  lpBuffer[0] = '\0';
1083 
1084  DefWindowProcW( frame, WM_SETTEXT, 0, (LPARAM)lpBuffer );
1085 
1086  if (repaint)
1087  {
1089  SetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
1091  }
1092 }
1093 
1094 
1095 /* ----------------------------- Interface ---------------------------- */
1096 
1097 
1098 /**********************************************************************
1099  * MDIClientWndProc_common
1100  */
1102 {
1103  MDICLIENTINFO *ci = NULL;
1104 
1105  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1106 
1107  if (!(ci = get_client_info( hwnd )))
1108  {
1109  if (message == WM_NCCREATE)
1110  {
1111 #ifdef __REACTOS__
1112  if (!(ci = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ci))))
1113  return FALSE;
1115  ci->hBmpClose = 0;
1116  NtUserSetWindowFNID( hwnd, FNID_MDICLIENT); // wine uses WIN_ISMDICLIENT
1117 #else
1118  if (message == WM_NCCREATE) win_set_flags( hwnd, WIN_ISMDICLIENT, 0 );
1119 #endif
1120  }
1121  return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1123  }
1124 
1125  switch (message)
1126  {
1127  case WM_CREATE:
1128  {
1129  /* Since we are using only cs->lpCreateParams, we can safely
1130  * cast to LPCREATESTRUCTA here */
1132  LPCLIENTCREATESTRUCT ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
1133 
1134  ci->hWindowMenu = ccs->hWindowMenu;
1135  ci->idFirstChild = ccs->idFirstChild;
1136  ci->hwndChildMaximized = 0;
1137  ci->child = NULL;
1138  ci->nActiveChildren = 0;
1139  ci->nTotalCreated = 0;
1140  ci->frameTitle = NULL;
1141  ci->mdiFlags = 0;
1142  ci->hFrameMenu = GetMenu(cs->hwndParent);
1143 
1144  if (!ci->hBmpClose) ci->hBmpClose = CreateMDIMenuBitmap();
1145 
1146  TRACE("Client created: hwnd %p, Window menu %p, idFirst = %04x\n",
1147  hwnd, ci->hWindowMenu, ci->idFirstChild );
1148  return 0;
1149  }
1150 
1151  case WM_DESTROY:
1152  {
1153  if( ci->hwndChildMaximized )
1155 
1156  ci->nActiveChildren = 0;
1157  MDI_RefreshMenu(ci);
1158 
1159  HeapFree( GetProcessHeap(), 0, ci->child );
1160  HeapFree( GetProcessHeap(), 0, ci->frameTitle );
1161 #ifdef __REACTOS__
1162  HeapFree( GetProcessHeap(), 0, ci );
1164 #endif
1165  return 0;
1166  }
1167 
1168 #ifdef __REACTOS__
1169  case WM_NCDESTROY:
1170  {
1172  return 0;
1173  }
1174 #endif
1175 
1176  case WM_MDIACTIVATE:
1177  {
1178  if( ci->hwndActiveChild != (HWND)wParam )
1179  SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
1180  return 0;
1181  }
1182 
1183  case WM_MDICASCADE:
1184  return MDICascade(hwnd, ci);
1185 
1186  case WM_MDICREATE:
1187  if (lParam)
1188  {
1189  HWND child;
1190 
1191  if (unicode)
1192  {
1195  csW->szTitle, csW->style,
1196  csW->x, csW->y, csW->cx, csW->cy,
1197  hwnd, 0, csW->hOwner,
1198  (LPVOID)csW->lParam);
1199  }
1200  else
1201  {
1204  csA->szTitle, csA->style,
1205  csA->x, csA->y, csA->cx, csA->cy,
1206  hwnd, 0, csA->hOwner,
1207  (LPVOID)csA->lParam);
1208  }
1209  return (LRESULT)child;
1210  }
1211  return 0;
1212 
1213  case WM_MDIDESTROY:
1214  return MDIDestroyChild( hwnd, ci, (HWND)wParam, TRUE );
1215 
1216  case WM_MDIGETACTIVE:
1217  if (lParam) *(BOOL *)lParam = IsZoomed(ci->hwndActiveChild);
1218  return (LRESULT)ci->hwndActiveChild;
1219 
1220  case WM_MDIICONARRANGE:
1221  ci->mdiFlags |= MDIF_NEEDUPDATE;
1223  ci->sbRecalc = SB_BOTH+1;
1224 #ifdef __REACTOS__
1226 #else
1228 #endif
1229  return 0;
1230 
1231  case WM_MDIMAXIMIZE:
1233  return 0;
1234 
1235  case WM_MDINEXT: /* lParam != 0 means previous window */
1236  {
1238  HWND next = MDI_GetWindow( ci, hwnd, !lParam, 0 );
1240  if(!lParam)
1242  break;
1243  }
1244 
1245  case WM_MDIRESTORE:
1247  return 0;
1248 
1249  case WM_MDISETMENU:
1250  return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
1251 
1252  case WM_MDIREFRESHMENU:
1253  return MDI_RefreshMenu( ci );
1254 
1255  case WM_MDITILE:
1256  ci->mdiFlags |= MDIF_NEEDUPDATE;
1258  MDITile( hwnd, ci, wParam );
1259  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1260  return 0;
1261 
1262  case WM_VSCROLL:
1263  case WM_HSCROLL:
1264  ci->mdiFlags |= MDIF_NEEDUPDATE;
1266  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1267  return 0;
1268 
1269  case WM_SETFOCUS:
1270  if (ci->hwndActiveChild && !IsIconic( ci->hwndActiveChild ))
1271  SetFocus( ci->hwndActiveChild );
1272  return 0;
1273 
1274  case WM_NCACTIVATE:
1275  if( ci->hwndActiveChild )
1277  break;
1278 
1279  case WM_PARENTNOTIFY:
1280  switch (LOWORD(wParam))
1281  {
1282  case WM_CREATE:
1284  {
1285  // ReactOS See rev 33503
1286  if (!ci->child)
1287  ci->child = HeapAlloc(GetProcessHeap(), 0, sizeof(HWND));
1288  else
1289  ci->child = HeapReAlloc(GetProcessHeap(), 0, ci->child, sizeof(HWND) * (ci->nActiveChildren + 1));
1290 
1291  TRACE("Adding MDI child %p, # of children %d\n",
1292  (HWND)lParam, ci->nActiveChildren);
1293 
1294  if (ci->child != NULL)
1295  {
1296  ci->child[ci->nActiveChildren] = (HWND)lParam;
1297  ci->nTotalCreated++;
1298  ci->nActiveChildren++;
1299  }
1300  }
1301  break;
1302 
1303  case WM_LBUTTONDOWN:
1304  {
1305  HWND child;
1306  POINT pt;
1307  pt.x = (short)LOWORD(lParam);
1308  pt.y = (short)HIWORD(lParam);
1310 
1311  TRACE("notification from %p (%li,%li)\n",child,pt.x,pt.y);
1312 
1313  if( child && child != hwnd && child != ci->hwndActiveChild )
1314  SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
1315  break;
1316  }
1317 
1318  case WM_DESTROY:
1319  return MDIDestroyChild( hwnd, ci, WIN_GetFullHandle( (HWND)lParam ), FALSE );
1320  }
1321  return 0;
1322 
1323  case WM_SIZE:
1324  if( ci->hwndActiveChild && IsZoomed(ci->hwndActiveChild) )
1325  {
1326  RECT rect;
1327 
1328  SetRect(&rect, 0, 0, LOWORD(lParam), HIWORD(lParam));
1331  MoveWindow(ci->hwndActiveChild, rect.left, rect.top,
1332  rect.right - rect.left, rect.bottom - rect.top, 1);
1333  }
1334  else
1335  MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
1336 
1337  break;
1338 
1339  case WM_MDICALCCHILDSCROLL:
1340  if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
1341  {
1342  CalcChildScroll(hwnd, ci->sbRecalc-1);
1343  ci->sbRecalc = 0;
1344  ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1345  }
1346  return 0;
1347  }
1348  return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
1350 }
1351 
1352 /***********************************************************************
1353  * MDIClientWndProcA
1354  */
1356 {
1357  if (!IsWindow(hwnd)) return 0;
1359 }
1360 
1361 /***********************************************************************
1362  * MDIClientWndProcW
1363  */
1365 {
1366  if (!IsWindow(hwnd)) return 0;
1368 }
1369 
1370 /***********************************************************************
1371  * DefFrameProcA (USER32.@)
1372  */
1375 {
1376  if (hwndMDIClient)
1377  {
1378  switch (message)
1379  {
1380  case WM_SETTEXT:
1381  {
1382  DWORD len = MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0 );
1383  LPWSTR text = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1384  if (text == NULL)
1385  return 0;
1388  HeapFree( GetProcessHeap(), 0, text );
1389  }
1390  return 1; /* success. FIXME: check text length */
1391 
1392  case WM_COMMAND:
1393  case WM_NCACTIVATE:
1394  case WM_NEXTMENU:
1395  case WM_SETFOCUS:
1396  case WM_SIZE:
1398  }
1399  }
1401 }
1402 
1403 
1404 /***********************************************************************
1405  * DefFrameProcW (USER32.@)
1406  */
1409 {
1411 
1412  TRACE("%p %p %04x (%s) %08lx %08lx\n", hwnd, hwndMDIClient, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1413 
1414  if (ci)
1415  {
1416  switch (message)
1417  {
1418  case WM_COMMAND:
1419  {
1420  WORD id = LOWORD(wParam);
1421  /* check for possible syscommands for maximized MDI child */
1422  if (id < ci->idFirstChild || id >= ci->idFirstChild + ci->nActiveChildren)
1423  {
1424  if( (id - 0xf000) & 0xf00f ) break;
1425  if( !ci->hwndChildMaximized ) break;
1426  switch( id )
1427  {
1428  case SC_CLOSE:
1429  if (!is_close_enabled(ci->hwndActiveChild, 0)) break;
1430  case SC_SIZE:
1431  case SC_MOVE:
1432  case SC_MINIMIZE:
1433  case SC_MAXIMIZE:
1434  case SC_NEXTWINDOW:
1435  case SC_PREVWINDOW:
1436  case SC_RESTORE:
1438  wParam, lParam);
1439  }
1440  }
1441  else
1442  {
1443  HWND childHwnd;
1444  if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
1445  /* User chose "More Windows..." */
1446  childHwnd = MDI_MoreWindowsDialog(hwndMDIClient);
1447  else
1448  /* User chose one of the windows listed in the "Windows" menu */
1449  childHwnd = MDI_GetChildByID(hwndMDIClient, id, ci);
1450 
1451  if( childHwnd )
1452  SendMessageW( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd, 0 );
1453  }
1454  }
1455  break;
1456 
1457  case WM_NCACTIVATE:
1459  break;
1460 
1461  case WM_SETTEXT:
1463  return 1; /* success. FIXME: check text length */
1464 
1465  case WM_SETFOCUS:
1467  break;
1468 
1469  case WM_SIZE:
1471  break;
1472 
1473  case WM_NEXTMENU:
1474  {
1475  MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1476 
1477  if (!IsIconic(hwnd) && ci->hwndActiveChild && !IsZoomed(ci->hwndActiveChild))
1478  {
1479  /* control menu is between the frame system menu and
1480  * the first entry of menu bar */
1481 // WND *wndPtr = WIN_GetPtr(hwnd);
1482 
1483  if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
1484  (wParam == VK_RIGHT && GetSubMenu(GetMenu(hwnd), 0) == next_menu->hmenuIn) )
1485  {
1486 // WIN_ReleasePtr(wndPtr);
1487 // wndPtr = WIN_GetPtr(ci->hwndActiveChild);
1488  next_menu->hmenuNext = GetSubMenu(GetMenu(ci->hwndActiveChild), 0);
1489  next_menu->hwndNext = ci->hwndActiveChild;
1490  }
1491 // WIN_ReleasePtr(wndPtr);
1492  }
1493  return 0;
1494  }
1495  }
1496  }
1497 
1498  return DefWindowProcW( hwnd, message, wParam, lParam );
1499 }
1500 
1501 /***********************************************************************
1502  * DefMDIChildProcA (USER32.@)
1503  */
1506 {
1509 
1510  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1511 
1513  if (!ci) return DefWindowProcA( hwnd, message, wParam, lParam );
1514 
1515  switch (message)
1516  {
1517  case WM_SETTEXT:
1519  if( ci->hwndChildMaximized == hwnd )
1521  MDI_RefreshMenu( ci );
1522  return 1; /* success. FIXME: check text length */
1523 
1524  case WM_GETMINMAXINFO:
1525  case WM_MENUCHAR:
1526  case WM_CLOSE:
1527  case WM_SETFOCUS:
1528  case WM_CHILDACTIVATE:
1529  case WM_SYSCOMMAND:
1530  case WM_SHOWWINDOW:
1531  case WM_SETVISIBLE:
1532  case WM_SIZE:
1533  case WM_NEXTMENU:
1534  case WM_SYSCHAR:
1535  case WM_DESTROY:
1536  return DefMDIChildProcW( hwnd, message, wParam, lParam );
1537  }
1539 }
1540 
1541 
1542 /***********************************************************************
1543  * DefMDIChildProcW (USER32.@)
1544  */
1547 {
1550 
1551  TRACE("%p %04x (%s) %08lx %08lx\n", hwnd, message, SPY_GetMsgName(message, hwnd), wParam, lParam);
1552 
1554  if (!ci) return DefWindowProcW( hwnd, message, wParam, lParam );
1555 
1556  switch (message)
1557  {
1558  case WM_SETTEXT:
1560  if( ci->hwndChildMaximized == hwnd )
1562  MDI_RefreshMenu( ci );
1563  return 1; /* success. FIXME: check text length */
1564 
1565  case WM_GETMINMAXINFO:
1567  return 0;
1568 
1569  case WM_MENUCHAR:
1570  return MAKELRESULT( 0, MNC_CLOSE ); /* MDI children don't have menu bars */
1571 
1572  case WM_CLOSE:
1574  return 0;
1575 
1576  case WM_SETFOCUS:
1577  if (ci->hwndActiveChild != hwnd)
1579  break;
1580 
1581  case WM_CHILDACTIVATE:
1582  if (IsWindowEnabled( hwnd ))
1584  return 0;
1585 
1586  case WM_SYSCOMMAND:
1587  switch (wParam & 0xfff0)
1588  {
1589  case SC_MOVE:
1590  if( ci->hwndChildMaximized == hwnd )
1591  return 0;
1592  break;
1593  case SC_RESTORE:
1594  case SC_MINIMIZE:
1595  break;
1596  case SC_MAXIMIZE:
1597  if (ci->hwndChildMaximized == hwnd)
1599  break;
1600  case SC_NEXTWINDOW:
1602  return 0;
1603  case SC_PREVWINDOW:
1605  return 0;
1606  }
1607  break;
1608 
1609  case WM_SHOWWINDOW:
1610  case WM_SETVISIBLE:
1612  /*if (ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
1613  else*/ MDI_PostUpdate(client, ci, SB_BOTH+1);
1614  break;
1615 
1616  case WM_SIZE:
1617  /* This is the only place where we switch to/from maximized state */
1618  /* do not change */
1619  TRACE("current active %p, maximized %p\n", ci->hwndActiveChild, ci->hwndChildMaximized);
1620 
1621  if( ci->hwndChildMaximized == hwnd && wParam != SIZE_MAXIMIZED )
1622  {
1623  HWND frame;
1624 
1625  ci->hwndChildMaximized = 0;
1626 
1627  frame = GetParent(client);
1628  MDI_RestoreFrameMenu( frame, hwnd, ci->hBmpClose );
1629  MDI_UpdateFrameText( frame, client, TRUE, NULL );
1630  }
1631 
1632  if( wParam == SIZE_MAXIMIZED )
1633  {
1634  HWND frame, hMaxChild = ci->hwndChildMaximized;
1635 
1636  if( hMaxChild == hwnd ) break;
1637 
1638  if( hMaxChild)
1639  {
1640  SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
1641 
1642  MDI_RestoreFrameMenu( GetParent(client), hMaxChild, ci->hBmpClose );
1643  ShowWindow( hMaxChild, SW_SHOWNOACTIVATE );
1644 
1645  SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
1646  }
1647 
1648  TRACE("maximizing child %p\n", hwnd );
1649 
1650  /* keep track of the maximized window. */
1651  ci->hwndChildMaximized = hwnd; /* !!! */
1652 
1653  frame = GetParent(client);
1654  MDI_AugmentFrameMenu( frame, hwnd );
1655  MDI_UpdateFrameText( frame, client, TRUE, NULL );
1656  }
1657 
1658  if( wParam == SIZE_MINIMIZED )
1659  {
1660  HWND switchTo = MDI_GetWindow( ci, hwnd, TRUE, WS_MINIMIZE );
1661 
1662  if (!switchTo) switchTo = hwnd;
1663  SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0 );
1664  }
1665 
1666  MDI_PostUpdate(client, ci, SB_BOTH+1);
1667  break;
1668 
1669  case WM_NEXTMENU:
1670  {
1671  MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
1673 
1674  if( wParam == VK_LEFT ) /* switch to frame system menu */
1675  {
1676 // WND *wndPtr = WIN_GetPtr( parent );
1677  next_menu->hmenuNext = GetSubMenu( GetMenu(parent), 0 );
1678 // WIN_ReleasePtr( wndPtr );
1679  }
1680  if( wParam == VK_RIGHT ) /* to frame menu bar */
1681  {
1682  next_menu->hmenuNext = GetMenu(parent);
1683  }
1684  next_menu->hwndNext = parent;
1685  return 0;
1686  }
1687 
1688  case WM_SYSCHAR:
1689  if (wParam == '-')
1690  {
1692  return 0;
1693  }
1694  break;
1695 
1696  case WM_DESTROY:
1697  /* Remove itself from the Window menu */
1698  MDI_RefreshMenu(ci);
1699  break;
1700  }
1702 }
1703 
1704 /**********************************************************************
1705  * CreateMDIWindowA (USER32.@) Creates a MDI child
1706  *
1707  * RETURNS
1708  * Success: Handle to created window
1709  * Failure: NULL
1710  */
1712  LPCSTR lpClassName, /* [in] Pointer to registered child class name */
1713  LPCSTR lpWindowName, /* [in] Pointer to window name */
1714  DWORD dwStyle, /* [in] Window style */
1715  INT X, /* [in] Horizontal position of window */
1716  INT Y, /* [in] Vertical position of window */
1717  INT nWidth, /* [in] Width of window */
1718  INT nHeight, /* [in] Height of window */
1719  HWND hWndParent, /* [in] Handle to parent window */
1720  HINSTANCE hInstance, /* [in] Handle to application instance */
1721  LPARAM lParam) /* [in] Application-defined value */
1722 {
1723  TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
1724  debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
1725  nWidth,nHeight,hWndParent,hInstance,lParam);
1726 
1727  return CreateWindowExA(WS_EX_MDICHILD, lpClassName, lpWindowName,
1728  dwStyle, X, Y, nWidth, nHeight, hWndParent,
1729  0, hInstance, (LPVOID)lParam);
1730 }
1731 
1732 /***********************************************************************
1733  * CreateMDIWindowW (USER32.@) Creates a MDI child
1734  *
1735  * RETURNS
1736  * Success: Handle to created window
1737  * Failure: NULL
1738  */
1740  LPCWSTR lpClassName, /* [in] Pointer to registered child class name */
1741  LPCWSTR lpWindowName, /* [in] Pointer to window name */
1742  DWORD dwStyle, /* [in] Window style */
1743  INT X, /* [in] Horizontal position of window */
1744  INT Y, /* [in] Vertical position of window */
1745  INT nWidth, /* [in] Width of window */
1746  INT nHeight, /* [in] Height of window */
1747  HWND hWndParent, /* [in] Handle to parent window */
1748  HINSTANCE hInstance, /* [in] Handle to application instance */
1749  LPARAM lParam) /* [in] Application-defined value */
1750 {
1751  TRACE("(%s,%s,%08lx,%d,%d,%d,%d,%p,%p,%08lx)\n",
1752  debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
1753  nWidth, nHeight, hWndParent, hInstance, lParam);
1754 
1755  return CreateWindowExW(WS_EX_MDICHILD, lpClassName, lpWindowName,
1756  dwStyle, X, Y, nWidth, nHeight, hWndParent,
1757  0, hInstance, (LPVOID)lParam);
1758 }
1759 
1760 /**********************************************************************
1761  * TranslateMDISysAccel (USER32.@)
1762  */
1764 {
1765  if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
1766  {
1767  MDICLIENTINFO *ci = get_client_info( hwndClient );
1768  WPARAM wParam = 0;
1769 
1770  if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
1771 
1772  /* translate if the Ctrl key is down and Alt not. */
1773 
1774  if( (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
1775  {
1776  switch( msg->wParam )
1777  {
1778  case VK_F6:
1779  case VK_TAB:
1781  break;
1782  case VK_F4:
1783  case VK_RBUTTON:
1784  if (is_close_enabled(ci->hwndActiveChild, 0))
1785  {
1786  wParam = SC_CLOSE;
1787  break;
1788  }
1789  /* fall through */
1790  default:
1791  return FALSE;
1792  }
1793  TRACE("wParam = %04lx\n", wParam);
1795  return TRUE;
1796  }
1797  }
1798  return FALSE; /* failure */
1799 }
1800 
1801 /***********************************************************************
1802  * CalcChildScroll (USER32.@)
1803  */
1805 {
1806  SCROLLINFO info;
1807  RECT childRect, clientRect;
1808  HWND *list;
1809  DWORD style;
1810  WINDOWINFO WindowInfo;
1811 
1812  GetClientRect( hwnd, &clientRect );
1813  SetRectEmpty( &childRect );
1814 
1815  /* The rectangle returned by GetClientRect always has 0,0 as top left
1816  * because it is in client coordinates. The rectangles returned by
1817  * GetWindowRect are in screen coordinates to make this complicated.
1818  *
1819  * Apparently (in ReactOS at least) the rcClient returned by GetWindowInfo
1820  * is in screen coordinates too.
1821  */
1822  WindowInfo.cbSize = sizeof(WindowInfo);
1823  if (!GetWindowInfo(hwnd, &WindowInfo))
1824  {
1825  ERR("Can't get window info\n");
1826  return;
1827  }
1828 
1829  TRACE("CalcChildScroll 1\n");
1830  if ((list = WIN_ListChildren( hwnd )))
1831  {
1832  int i;
1833  for (i = 0; list[i]; i++)
1834  {
1836  if (style & WS_MAXIMIZE)
1837  {
1838  HeapFree( GetProcessHeap(), 0, list );
1840  ERR("CalcChildScroll 2\n");
1841  return;
1842  }
1843  if (style & WS_VISIBLE)
1844  {
1845  RECT rect;
1846  GetWindowRect( list[i], &rect );
1847  OffsetRect(&rect, -WindowInfo.rcClient.left,
1848  -WindowInfo.rcClient.top);
1849  //WIN_GetRectangles( list[i], COORDS_PARENT, &rect, NULL );
1850  TRACE("CalcChildScroll L\n");
1851  UnionRect( &childRect, &rect, &childRect );
1852  }
1853  }
1854  HeapFree( GetProcessHeap(), 0, list );
1855  }
1856  UnionRect( &childRect, &clientRect, &childRect );
1857  TRACE("CalcChildScroll 3\n");
1858  /* set common info values */
1859  info.cbSize = sizeof(info);
1860  info.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
1861  info.nPos = 0;
1862 
1863  /* set the specific values and apply but only if window style allows */
1864  /* Note how we set nPos to 0 because we scroll the clients instead of
1865  * the window, and we set nPage to 1 bigger than the clientRect because
1866  * otherwise the scrollbar never disables. This causes a somewhat ugly
1867  * effect though while scrolling.
1868  */
1870  switch( scroll )
1871  {
1872  case SB_BOTH:
1873  case SB_HORZ:
1874  if (style & (WS_HSCROLL | WS_VSCROLL))
1875  {
1876  info.nMin = childRect.left;
1877  info.nMax = childRect.right;
1878  info.nPage = 1 + clientRect.right - clientRect.left;
1879  //info.nMax = childRect.right - clientRect.right;
1880  //info.nPos = clientRect.left - childRect.left;
1882  }
1883  if (scroll == SB_HORZ) break;
1884  /* fall through */
1885  case SB_VERT:
1886  if (style & (WS_HSCROLL | WS_VSCROLL))
1887  {
1888  info.nMin = childRect.top;
1889  info.nMax = childRect.bottom;
1890  info.nPage = 1 + clientRect.bottom - clientRect.top;
1891  //info.nMax = childRect.bottom - clientRect.bottom;
1892  //info.nPos = clientRect.top - childRect.top;
1894  }
1895  break;
1896  }
1897 }
1898 
1899 
1900 /***********************************************************************
1901  * ScrollChildren (USER32.@)
1902  */
1904  LPARAM lParam)
1905 {
1906  INT newPos = -1;
1907  INT curPos, length, minPos, maxPos, shift;
1908  RECT rect;
1909 
1910  GetClientRect( hWnd, &rect );
1911 
1912  switch(uMsg)
1913  {
1914  case WM_HSCROLL:
1915  GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
1916  curPos = GetScrollPos(hWnd,SB_HORZ);
1917  length = (rect.right - rect.left) / 2;
1919  break;
1920  case WM_VSCROLL:
1921  GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
1922  curPos = GetScrollPos(hWnd,SB_VERT);
1923  length = (rect.bottom - rect.top) / 2;
1925  break;
1926  default:
1927  return;
1928  }
1929 
1930  switch( wParam )
1931  {
1932  case SB_LINEUP:
1933  newPos = curPos - shift;
1934  break;
1935  case SB_LINEDOWN:
1936  newPos = curPos + shift;
1937  break;
1938  case SB_PAGEUP:
1939  newPos = curPos - length;
1940  break;
1941  case SB_PAGEDOWN:
1942  newPos = curPos + length;
1943  break;
1944 
1945  case SB_THUMBPOSITION:
1946  newPos = LOWORD(lParam);
1947  break;
1948 
1949  case SB_THUMBTRACK:
1950  return;
1951 
1952  case SB_TOP:
1953  newPos = minPos;
1954  break;
1955  case SB_BOTTOM:
1956  newPos = maxPos;
1957  break;
1958  case SB_ENDSCROLL:
1960  return;
1961  }
1962 
1963  if( newPos > maxPos )
1964  newPos = maxPos;
1965  else
1966  if( newPos < minPos )
1967  newPos = minPos;
1968 
1969  SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
1970 
1971  if( uMsg == WM_VSCROLL )
1972  ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
1974  else
1975  ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
1977 }
1978 
1979 /******************************************************************************
1980  * CascadeWindows (USER32.@) Cascades MDI child windows
1981  *
1982  * RETURNS
1983  * Success: Number of cascaded windows.
1984  * Failure: 0
1985  */
1986 
1987 typedef struct CASCADE_INFO
1988 {
1997 } CASCADE_INFO;
1998 
1999 static BOOL CALLBACK
2001 {
2002  DWORD count, size;
2003  HWND *ahwnd;
2004  CASCADE_INFO *pInfo = (CASCADE_INFO *)lParam;
2005 
2006  if (hwnd == pInfo->hwndDesktop || hwnd == pInfo->hTrayWnd ||
2007  hwnd == pInfo->hwndProgman || hwnd == pInfo->hwndTop)
2008  {
2009  return TRUE;
2010  }
2011 
2012  if (pInfo->hwndParent && GetParent(hwnd) != pInfo->hwndParent)
2013  return TRUE;
2014 
2015  if ((pInfo->wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2016  return TRUE;
2017 
2018  if (!IsWindowVisible(hwnd) || IsIconic(hwnd))
2019  return TRUE;
2020 
2021  count = pInfo->chwnd;
2022  size = (count + 1) * sizeof(HWND);
2023 
2024  if (count == 0 || pInfo->ahwnd == NULL)
2025  {
2026  count = 0;
2027  pInfo->ahwnd = (HWND *)HeapAlloc(GetProcessHeap(), 0, size);
2028  }
2029  else
2030  {
2031  ahwnd = (HWND *)HeapReAlloc(GetProcessHeap(), 0, pInfo->ahwnd, size);
2032  if (ahwnd == NULL)
2033  {
2034  HeapFree(GetProcessHeap(), 0, pInfo->ahwnd);
2035  }
2036  pInfo->ahwnd = ahwnd;
2037  }
2038 
2039  if (pInfo->ahwnd == NULL)
2040  {
2041  pInfo->chwnd = 0;
2042  return FALSE;
2043  }
2044 
2045  pInfo->ahwnd[count] = hwnd;
2046  pInfo->chwnd = count + 1;
2047  return TRUE;
2048 }
2049 
2050 static BOOL
2052 {
2053  MINMAXINFO mmi;
2054  DWORD_PTR dwResult;
2055 
2056  mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 0;
2057  mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = MAXLONG;
2059  SMTO_ABORTIFHUNG | SMTO_NORMAL, 120, &dwResult))
2060  {
2061  *pcx = min(max(*pcx, mmi.ptMinTrackSize.x), mmi.ptMaxTrackSize.x);
2062  *pcy = min(max(*pcy, mmi.ptMinTrackSize.y), mmi.ptMaxTrackSize.y);
2063  return TRUE;
2064  }
2065  return FALSE;
2066 }
2067 
2068 WORD WINAPI
2070  UINT cKids, const HWND *lpKids)
2071 {
2073  HWND hwnd, hwndTop, hwndPrev;
2074  HMONITOR hMon;
2075  MONITORINFO mi;
2076  RECT rcWork, rcWnd;
2077  DWORD i, ret = 0;
2078  INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, dx, dy;
2079  HDWP hDWP;
2080  POINT pt;
2081 
2082  TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2083 
2084  hwndTop = GetTopWindow(hwndParent);
2085 
2086  ZeroMemory(&info, sizeof(info));
2087  info.hwndDesktop = GetDesktopWindow();
2088  info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2089  info.hwndProgman = FindWindowW(L"Progman", NULL);
2090  info.hwndParent = hwndParent;
2091  info.wFlags = wFlags;
2092 
2093  if (cKids == 0 || lpKids == NULL)
2094  {
2095  info.hwndTop = hwndTop;
2097 
2098  info.hwndTop = NULL;
2099  GetCascadeChildProc(hwndTop, (LPARAM)&info);
2100  }
2101  else
2102  {
2103  info.chwnd = cKids;
2104  info.ahwnd = (HWND *)lpKids;
2105  }
2106 
2107  if (info.chwnd == 0 || info.ahwnd == NULL)
2108  return ret;
2109 
2110  if (lpRect)
2111  {
2112  rcWork = *lpRect;
2113  }
2114  else if (hwndParent)
2115  {
2116  GetClientRect(hwndParent, &rcWork);
2117  }
2118  else
2119  {
2120  pt.x = pt.y = 0;
2121  hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2122  mi.cbSize = sizeof(mi);
2123  GetMonitorInfoW(hMon, &mi);
2124  rcWork = mi.rcWork;
2125  }
2126 
2127  hDWP = BeginDeferWindowPos(info.chwnd);
2128  if (hDWP == NULL)
2129  goto cleanup;
2130 
2131  x = rcWork.left;
2132  y = rcWork.top;
2135  cxWork = rcWork.right - rcWork.left;
2136  cyWork = rcWork.bottom - rcWork.top;
2137  hwndPrev = NULL;
2138  for (i = info.chwnd; i > 0;) /* in reverse order */
2139  {
2140  --i;
2141  hwnd = info.ahwnd[i];
2142 
2143  if (!IsWindowVisible(hwnd) || IsIconic(hwnd))
2144  continue;
2145 
2146  if ((info.wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwnd))
2147  continue;
2148 
2149  if (IsZoomed(hwnd))
2151 
2152  GetWindowRect(hwnd, &rcWnd);
2153  cxNew = cx = rcWnd.right - rcWnd.left;
2154  cyNew = cy = rcWnd.bottom - rcWnd.top;
2155 
2156  /* if we can change the window size and it is not only one */
2157  if (info.chwnd != 1 && (GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_THICKFRAME))
2158  {
2159  /* check the size */
2160 #define THRESHOLD(xy) (((xy) * 5) / 7) /* in the rate 5/7 */
2161  cxNew = min(cxNew, THRESHOLD(cxWork));
2162  cyNew = min(cyNew, THRESHOLD(cyWork));
2163 #undef THRESHOLD
2164  if (cx != cxNew || cy != cyNew)
2165  {
2166  /* too large. shrink if we can */
2167  if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2168  {
2169  cx = cxNew;
2170  cy = cyNew;
2171  }
2172  }
2173  }
2174 
2175  if (x + cx > rcWork.right)
2176  x = rcWork.left;
2177  if (y + cy > rcWork.bottom)
2178  y = rcWork.top;
2179 
2180  hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2181  if (hDWP == NULL)
2182  {
2183  ret = 0;
2184  goto cleanup;
2185  }
2186 
2187  x += dx;
2188  y += dy;
2189  hwndPrev = hwnd;
2190  ++ret;
2191  }
2192 
2193  EndDeferWindowPos(hDWP);
2194 
2195  if (hwndPrev)
2196  SetForegroundWindow(hwndPrev);
2197 
2198 cleanup:
2199  if (cKids == 0 || lpKids == NULL)
2200  HeapFree(GetProcessHeap(), 0, info.ahwnd);
2201 
2202  return (WORD)ret;
2203 }
2204 
2205 
2206 /***********************************************************************
2207  * CascadeChildWindows (USER32.@)
2208  */
2210 {
2211  return CascadeWindows( parent, flags, NULL, 0, NULL );
2212 }
2213 
2214 
2215 /******************************************************************************
2216  * TileWindows (USER32.@) Tiles MDI child windows
2217  *
2218  * RETURNS
2219  * Success: Number of tiled windows.
2220  * Failure: 0
2221  */
2222 WORD WINAPI
2224  UINT cKids, const HWND *lpKids)
2225 {
2226  HWND hwnd, hwndTop, hwndPrev;
2228  RECT rcWork, rcWnd;
2229  DWORD i, iRow, iColumn, cRows, cColumns, ret = 0;
2230  INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, cxCell, cyCell, cxMin2, cyMin3;
2231  HDWP hDWP;
2232  MONITORINFO mi;
2233  HMONITOR hMon;
2234  POINT pt;
2235 
2236  TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
2237 
2238  hwndTop = GetTopWindow(hwndParent);
2239 
2240  ZeroMemory(&info, sizeof(info));
2241  info.hwndDesktop = GetDesktopWindow();
2242  info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
2243  info.hwndProgman = FindWindowW(L"Progman", NULL);
2244  info.hwndParent = hwndParent;
2245  info.wFlags = wFlags;
2246 
2247  if (cKids == 0 || lpKids == NULL)
2248  {
2249  info.hwndTop = hwndTop;
2251 
2252  info.hwndTop = NULL;
2253  GetCascadeChildProc(hwndTop, (LPARAM)&info);
2254  }
2255  else
2256  {
2257  info.chwnd = cKids;
2258  info.ahwnd = (HWND *)lpKids;
2259  }
2260 
2261  if (info.chwnd == 0 || info.ahwnd == NULL)
2262  return ret;
2263 
2264  if (lpRect)
2265  {
2266  rcWork = *lpRect;
2267  }
2268  else if (hwndParent)
2269  {
2270  GetClientRect(hwndParent, &rcWork);
2271  }
2272  else
2273  {
2274  pt.x = pt.y = 0;
2275  hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
2276  mi.cbSize = sizeof(mi);
2277  GetMonitorInfoW(hMon, &mi);
2278  rcWork = mi.rcWork;
2279  }
2280 
2281  cxWork = rcWork.right - rcWork.left;
2282  cyWork = rcWork.bottom - rcWork.top;
2283 
2284  cxMin2 = GetSystemMetrics(SM_CXMIN) * 2;
2285  cyMin3 = GetSystemMetrics(SM_CYMIN) * 3;
2286 
2287  /* calculate the numbers and widths of columns and rows */
2288  if (info.wFlags & MDITILE_HORIZONTAL)
2289  {
2290  cColumns = info.chwnd;
2291  cRows = 1;
2292  for (;;)
2293  {
2294  cxCell = cxWork / cColumns;
2295  cyCell = cyWork / cRows;
2296  if (cyCell <= cyMin3 || cxCell >= cxMin2)
2297  break;
2298 
2299  ++cRows;
2300  cColumns = (info.chwnd + cRows - 1) / cRows;
2301  }
2302  }
2303  else
2304  {
2305  cRows = info.chwnd;
2306  cColumns = 1;
2307  for (;;)
2308  {
2309  cxCell = cxWork / cColumns;
2310  cyCell = cyWork / cRows;
2311  if (cxCell <= cxMin2 || cyCell >= cyMin3)
2312  break;
2313 
2314  ++cColumns;
2315  cRows = (info.chwnd + cColumns - 1) / cColumns;
2316  }
2317  }
2318 
2319  hDWP = BeginDeferWindowPos(info.chwnd);
2320  if (hDWP == NULL)
2321  goto cleanup;
2322 
2323  x = rcWork.left;
2324  y = rcWork.top;
2325  hwndPrev = NULL;
2326  iRow = iColumn = 0;
2327  for (i = info.chwnd; i > 0;) /* in reverse order */
2328  {
2329  --i;
2330  hwnd = info.ahwnd[i];
2331 
2332  if (IsZoomed(hwnd))
2334 
2335  GetWindowRect(hwnd, &rcWnd);
2336  cx = rcWnd.right - rcWnd.left;
2337  cy = rcWnd.bottom - rcWnd.top;
2338 
2339  /* if we can change the window size */
2341  {
2342  cxNew = cxCell;
2343  cyNew = cyCell;
2344  /* shrink if we can */
2345  if (QuerySizeFix(hwnd, &cxNew, &cyNew))
2346  {
2347  cx = cxNew;
2348  cy = cyNew;
2349  }
2350  }
2351 
2352  hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
2353  if (hDWP == NULL)
2354  {
2355  ret = 0;
2356  goto cleanup;
2357  }
2358 
2359  if (info.wFlags & MDITILE_HORIZONTAL)
2360  {
2361  x += cxCell;
2362  ++iColumn;
2363  if (iColumn >= cColumns)
2364  {
2365  iColumn = 0;
2366  ++iRow;
2367  x = rcWork.left;
2368  y += cyCell;
2369  }
2370  }
2371  else
2372  {
2373  y += cyCell;
2374  ++iRow;
2375  if (iRow >= cRows)
2376  {
2377  iRow = 0;
2378  ++iColumn;
2379  x += cxCell;
2380  y = rcWork.top;
2381  }
2382  }
2383  hwndPrev = hwnd;
2384  ++ret;
2385  }
2386 
2387  EndDeferWindowPos(hDWP);
2388 
2389  if (hwndPrev)
2390  SetForegroundWindow(hwndPrev);
2391 
2392 cleanup:
2393  if (cKids == 0 || lpKids == NULL)
2394  HeapFree(GetProcessHeap(), 0, info.ahwnd);
2395 
2396  return (WORD)ret;
2397 }
2398 
2399 
2400 /***********************************************************************
2401  * TileChildWindows (USER32.@)
2402  */
2404 {
2405  return TileWindows( parent, flags, NULL, 0, NULL );
2406 }
2407 
2408 
2409 /************************************************************************
2410  * "More Windows..." functionality
2411  */
2412 
2413 /* MDI_MoreWindowsDlgProc
2414  *
2415  * This function will process the messages sent to the "More Windows..."
2416  * dialog.
2417  * Return values: 0 = cancel pressed
2418  * HWND = ok pressed or double-click in the list...
2419  *
2420  */
2421 
2423 {
2424  switch (iMsg)
2425  {
2426  case WM_INITDIALOG:
2427  {
2428  UINT widest = 0;
2429  UINT length;
2430  UINT i;
2433 
2434  for (i = 0; i < ci->nActiveChildren; i++)
2435  {
2437 
2438  if (!InternalGetWindowText( ci->child[i], buffer, sizeof(buffer)/sizeof(WCHAR) ))
2439  continue;
2442  length = strlenW(buffer); /* FIXME: should use GetTextExtentPoint */
2443  if (length > widest)
2444  widest = length;
2445  }
2446  /* Make sure the horizontal scrollbar scrolls ok */
2447  SendMessageW(hListBox, LB_SETHORIZONTALEXTENT, widest * 6, 0);
2448 
2449  /* Set the current selection */
2451  return TRUE;
2452  }
2453 
2454  case WM_COMMAND:
2455  switch (LOWORD(wParam))
2456  {
2457  default:
2458  if (HIWORD(wParam) != LBN_DBLCLK) break;
2459  /* fall through */
2460  case IDOK:
2461  {
2462  /* windows are sorted by menu ID, so we must return the
2463  * window associated to the given id
2464  */
2468  EndDialog(hDlg, res);
2469  return TRUE;
2470  }
2471  case IDCANCEL:
2472  EndDialog(hDlg, 0);
2473  return TRUE;
2474  }
2475  break;
2476  }
2477  return FALSE;
2478 }
2479 
2480 /*
2481  *
2482  * MDI_MoreWindowsDialog
2483  *
2484  * Prompts the user with a listbox containing the opened
2485  * documents. The user can then choose a windows and click
2486  * on OK to set the current window to the one selected, or
2487  * CANCEL to cancel. The function returns a handle to the
2488  * selected window.
2489  */
2490 
2492 {
2493  LPCVOID template;
2494  HRSRC hRes;
2495  HANDLE hDlgTmpl;
2496 
2497  hRes = FindResourceA(User32Instance, "MDI_MOREWINDOWS", (LPSTR)RT_DIALOG);
2498 
2499  if (hRes == 0)
2500  return 0;
2501 
2502  hDlgTmpl = LoadResource(User32Instance, hRes );
2503 
2504  if (hDlgTmpl == 0)
2505  return 0;
2506 
2507  template = LockResource( hDlgTmpl );
2508 
2509  if (template == 0)
2510  return 0;
2511 
2512  return (HWND) DialogBoxIndirectParamA(User32Instance, template, hwnd,
2514 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define LB_SETCURSEL
Definition: winuser.h:2045
POINT ptMinTrackSize
Definition: winuser.h:3605
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
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define SB_PAGEDOWN
Definition: winuser.h:569
#define SWP_DRAWFRAME
Definition: winuser.h:1224
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:952
#define TRUE
Definition: types.h:120
DWORD cbSize
Definition: winuser.h:3741
UINT wFlags
Definition: mdi.c:1990
#define IDOK
Definition: winuser.h:824
static void MDI_UpdateFrameText(HWND, HWND, BOOL, LPCWSTR)
Definition: mdi.c:1031
#define shift
Definition: input.c:1761
#define IMAGE_ICON
Definition: winuser.h:212
BOOL WINAPI DrawMenuBar(_In_ HWND)
#define SC_KEYMENU
Definition: winuser.h:2571
#define SM_CYSIZE
Definition: winuser.h:982
static MDICLIENTINFO * get_client_info(HWND client)
Definition: mdi.c:225
#define SIF_RANGE
Definition: winuser.h:1221
#define MF_BYCOMMAND
Definition: winuser.h:202
HWND hwndProgman
Definition: mdi.c:1994
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:2573
#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:1758
#define MNC_CLOSE
Definition: winuser.h:2542
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2046
#define VK_F6
Definition: winuser.h:2235
POINT ptMaxSize
Definition: winuser.h:3603
#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:2013
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define MAXLONG
Definition: umtypes.h:116
long x
Definition: polytest.cpp:48
#define WM_MENUCHAR
Definition: winuser.h:1730
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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
POINT last
Definition: font.c:46
#define SIZE_MAXIMIZED
Definition: winuser.h:2482
static HTREEITEM hChild
Definition: treeview.c:381
#define HBMMENU_MBAR_CLOSE_D
Definition: winuser.h:2610
#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:1996
#define SW_HIDE
Definition: winuser.h:762
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define MAKELRESULT(l, h)
Definition: winuser.h:3985
static LRESULT MDISetMenu(HWND hwnd, HMENU hmenuFrame, HMENU hmenuWindow)
Definition: mdi.c:336
const WCHAR * text
Definition: package.c:1827
#define CP_ACP
Definition: compat.h:99
#define LB_GETITEMDATA
Definition: winuser.h:2023
HWND hTrayWnd
Definition: mdi.c:1993
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:111
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:1801
UINT WINAPI GetMenuState(_In_ HMENU, _In_ UINT, _In_ UINT)
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
UINT WINAPI ArrangeIconicWindows(_In_ HWND)
#define WM_SETREDRAW
Definition: winuser.h:1598
#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
HANDLE HWND
Definition: compat.h:13
#define CS_NOCLOSE
Definition: winuser.h:649
struct CASCADE_INFO CASCADE_INFO
#define VK_LEFT
Definition: winuser.h:2199
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define WM_SHOWWINDOW
Definition: winuser.h:1610
#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:1642
#define HBMMENU_MBAR_MINIMIZE
Definition: winuser.h:2608
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:1193
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
GLuint buffer
Definition: glext.h:5915
#define SM_CYSMICON
Definition: winuser.h:1003
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define COLOR_APPWORKSPACE
Definition: winuser.h:915
HWND WINAPI SetFocus(_In_opt_ HWND)
LPWSTR dwTypeData
Definition: winuser.h:3244
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
static INT_PTR WINAPI MDI_MoreWindowsDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:2422
static MONITORINFO mi
Definition: win.c:7339
#define MFT_BITMAP
Definition: winuser.h:733
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
Definition: mdi.c:1763
#define VK_TAB
Definition: winuser.h:2174
#define GWLP_MDIWND
Definition: ntuser.h:748
#define VK_MENU
Definition: winuser.h:2179
#define GetWindowLongPtrW
Definition: winuser.h:4804
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
#define SM_CYFRAME
Definition: winuser.h:986
#define FNID_DESTROY
Definition: ntuser.h:859
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MDISETMENU
Definition: winuser.h:1804
int32_t INT_PTR
Definition: typedefs.h:62
HBITMAP hBmpClose
Definition: mdi.c:126
char * LPSTR
Definition: xmlstorage.h:182
#define SW_RESTORE
Definition: winuser.h:773
LONG right
Definition: windef.h:308
WORD WINAPI TileChildWindows(HWND parent, UINT flags)
Definition: mdi.c:2403
BOOL WINAPI IsIconic(_In_ HWND)
UINT sbRecalc
Definition: mdi.c:125
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:410
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:56
#define SIF_PAGE
Definition: winuser.h:1219
static void MDI_SwitchActiveChild(MDICLIENTINFO *ci, HWND hwndTo, BOOL activate)
Definition: mdi.c:534
static HWND child
Definition: cursoricon.c:298
DWORD WINAPI GetSysColor(_In_ int)
& 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:1209
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define lstrcpynW
Definition: compat.h:405
#define SMTO_NORMAL
Definition: winuser.h:1211
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2218
#define HBMMENU_MBAR_CLOSE
Definition: winuser.h:2609
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define ICON_SMALL
Definition: tnclass.cpp:48
struct _test_info info[]
Definition: SetCursorPos.c:19
void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1903
static BOOL QuerySizeFix(HWND hwnd, LPINT pcx, LPINT pcy)
Definition: mdi.c:2051
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:1739
struct tagCREATESTRUCTA * LPCREATESTRUCTA
#define WM_NEXTMENU
Definition: winuser.h:1788
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:2209
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define WM_MDIICONARRANGE
Definition: winuser.h:1802
uint32_t cs
Definition: isohybrid.c:75
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
HINSTANCE hInstance
Definition: charmap.c:20
#define WS_EX_MDICHILD
Definition: winuser.h:394
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
HWND hwndActiveChild
Definition: mdi.c:117
#define VK_RBUTTON
Definition: winuser.h:2166
#define WM_NCACTIVATE
Definition: winuser.h:1670
LRESULT WINAPI MDIClientWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1364
#define WS_MINIMIZE
Definition: pedump.c:622
#define WM_PARENTNOTIFY
Definition: winuser.h:1785
WINE_DEFAULT_DEBUG_CHANNEL(mdi)
#define WM_CHILDACTIVATE
Definition: winuser.h:1620
unsigned int BOOL
Definition: ntddk_ex.h:94
LRESULT WINAPI DefMDIChildProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1545
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:1355
#define MF_BYPOSITION
Definition: winuser.h:203
#define MDITILE_HORIZONTAL
Definition: winuser.h:2163
BOOL WINAPI EndDeferWindowPos(_In_ HDWP)
#define debugstr_w
Definition: kernel32.h:32
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
#define WM_SYSCHAR
Definition: winuser.h:1703
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:1711
UINT mdiFlags
Definition: mdi.c:124
#define HBMMENU_MBAR_RESTORE
Definition: winuser.h:2607
#define VK_F4
Definition: winuser.h:2233
#define SW_ERASE
Definition: winuser.h:2555
#define SC_MAXIMIZE
Definition: winuser.h:2563
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
#define VK_SHIFT
Definition: winuser.h:2177
int nItems
Definition: appswitch.c:56
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define WM_MDICALCCHILDSCROLL
Definition: mdi.c:90
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
smooth NULL
Definition: ftsmooth.c:416
#define WM_MDINEXT
Definition: winuser.h:1798
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
static HWND hwndParent
Definition: cryptui.c:300
#define COLOR_MENU
Definition: winuser.h:907
#define SM_CYSIZEFRAME
Definition: winuser.h:985
HMENU hmenuIn
Definition: winuser.h:3610
#define SB_THUMBPOSITION
Definition: winuser.h:572
#define WM_KEYDOWN
Definition: winuser.h:1697
#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:834
#define SM_CYMIN
Definition: winuser.h:980
#define WM_SETTEXT
Definition: winuser.h:1599
static BOOL MDI_RestoreFrameMenu(HWND, HWND, HBITMAP)
Definition: mdi.c:966
#define IDS_MDI_MOREWINDOWS
Definition: mdi.c:96
static HWND MDI_MoreWindowsDialog(HWND)
Definition: mdi.c:2491
#define WM_DESTROY
Definition: winuser.h:1591
#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:983
#define DC_ACTIVE
Definition: winuser.h:427
#define GetWindowLongPtrA
Definition: winuser.h:4803
LRESULT WINAPI DefFrameProcA(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1373
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:1191
#define TRACE(s)
Definition: solgame.cpp:4
HWND hwndDesktop
Definition: mdi.c:1992
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:403
#define SM_CYCAPTION
Definition: winuser.h:953
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MDI_MAXTITLELENGTH
Definition: mdi.c:88
r parent
Definition: btrfs.c:2869
#define MDITILE_SKIPDISABLED
Definition: winuser.h:2162
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:1593
#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)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
BOOL WINAPI SetMenu(_In_ HWND, _In_opt_ HMENU)
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define SWP_NOACTIVATE
Definition: winuser.h:1227
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define WM_CLOSE
Definition: winuser.h:1603
#define WM_NCDESTROY
Definition: winuser.h:1666
#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:417
#define SIZE_MINIMIZED
Definition: winuser.h:2481
BOOL WINAPI UnionRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define LB_SETITEMDATA
Definition: winuser.h:2047
#define LBN_DBLCLK
Definition: winuser.h:2053
#define WS_HSCROLL
Definition: pedump.c:628
GLbitfield flags
Definition: glext.h:7161
#define SC_PREVWINDOW
Definition: winuser.h:2566
HWND hwndTop
Definition: mdi.c:1989
#define SM_CXSMICON
Definition: winuser.h:1002
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:1101
#define WM_MDIGETACTIVE
Definition: winuser.h:1803
POINT ptMaxPosition
Definition: winuser.h:3604
int ret
#define MF_POPUP
Definition: winuser.h:136
#define SM_CYICON
Definition: winuser.h:963
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
static const WCHAR L[]
Definition: oid.c:1250
#define SM_CYICONSPACING
Definition: winuser.h:992
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 THRESHOLD(xy)
#define GCLP_HICON
Definition: winuser.h:669
void WINAPI CalcChildScroll(HWND hwnd, INT scroll)
Definition: mdi.c:1804
#define MIIM_TYPE
Definition: winuser.h:720
HWND hwndParent
Definition: mdi.c:1991
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:1225
#define WM_SETVISIBLE
Definition: undocuser.h:31
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:1722
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_MDIACTIVATE
Definition: winuser.h:1796
#define MF_BITMAP
Definition: winuser.h:131
HWND * WIN_ListChildren(HWND hWndparent)
Definition: mdi.c:140
uint32_t DWORD_PTR
Definition: typedefs.h:63
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:1795
#define MDI_IDC_LISTBOX
Definition: mdi.c:95
struct tagCLIENTCREATESTRUCT * LPCLIENTCREATESTRUCT
#define SW_INVALIDATE
Definition: winuser.h:2554
BOOL WINAPI DestroyMenu(_In_ HMENU)
struct _MDIWND MDIWND
Status
Definition: gdiplustypes.h:24
#define SIF_POS
Definition: winuser.h:1220
HMENU hmenuNext
Definition: winuser.h:3611
#define VK_RIGHT
Definition: winuser.h:2201
#define SC_MINIMIZE
Definition: winuser.h:2561
static LONG MDI_ChildActivate(HWND, HWND)
Definition: mdi.c:639
#define SWP_NOSIZE
Definition: winuser.h:1230
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
#define ERR(fmt,...)
Definition: debug.h:109
#define GWL_STYLE
Definition: winuser.h:846
Definition: ntuser.h:657
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:2223
#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:1808
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:1797
static real win[4][36]
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1408
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:902
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:3759
BOOL WINAPI RemoveMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SC_SIZE
Definition: winuser.h:2559
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:401
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:2021
unsigned int UINT
Definition: ndis.h:50
#define SB_LINEDOWN
Definition: winuser.h:565
BOOL WINAPI IsZoomed(_In_ HWND)
#define WM_HSCROLL
Definition: winuser.h:1725
#define VK_SPACE
Definition: winuser.h:2194
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#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:2553
#define SM_CXVSCROLL
Definition: winuser.h:951
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
NTSTATUS NTAPI NtUserBuildHwndList(HDESK hDesktop, HWND hwndParent, BOOLEAN bChildren, ULONG dwThreadId, ULONG lParam, HWND *pWnd, ULONG *pBufSize)
Definition: window.c:1338
#define MultiByteToWideChar
Definition: compat.h:100
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:2178
#define WM_MDICREATE
Definition: winuser.h:1794
#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:2560
_Out_opt_ int * cx
Definition: commctrl.h:581
#define SC_CLOSE
Definition: winuser.h:2567
#define MM_TEXT
Definition: wingdi.h:872
#define WM_CREATE
Definition: winuser.h:1590
#define SM_CXSIZE
Definition: winuser.h:981
GLuint res
Definition: glext.h:9613
DWORD_PTR NTAPI NtUserCallTwoParam(DWORD_PTR Param1, DWORD_PTR Param2, DWORD Routine)
Definition: simplecall.c:426
HWND WINAPI ChildWindowFromPoint(_In_ HWND, _In_ POINT)
#define WM_SYSKEYDOWN
Definition: winuser.h:1701
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:246
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:4126
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:1229
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:5321
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:3743
#define SC_NEXTWINDOW
Definition: winuser.h:2565
#define OBM_OLD_CLOSE
Definition: winuser.h:1131
POINT ptMaxTrackSize
Definition: winuser.h:3606
#define MF_HELP
Definition: winuser.h:142
#define GetWindowLongPtr
Definition: treelist.c:73
#define WM_SETFOCUS
Definition: winuser.h:1595
#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
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:1077
Arabic default style
Definition: afstyles.h:93
#define WS_VISIBLE
Definition: pedump.c:620
WORD WINAPI CascadeWindows(HWND hwndParent, UINT wFlags, LPCRECT lpRect, UINT cKids, const HWND *lpKids)
Definition: mdi.c:2069
#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:1995
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:1723
LRESULT WINAPI DefMDIChildProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1504
#define WM_INITDIALOG
Definition: winuser.h:1721
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
static HBITMAP hBitmap
Definition: timezone.c:35
LRESULT WINAPI DefFrameProcW(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam)
Definition: mdi.c:1407
LPARAM lParam
Definition: combotst.c:139
#define WM_GETMINMAXINFO
Definition: winuser.h:1622
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:402
#define GetClassLongPtrW
Definition: winuser.h:4539
#define GWLP_ID
Definition: winuser.h:854
#define SRCCOPY
Definition: wingdi.h:332
const struct builtin_class_descr MDICLIENT_builtin_class
Definition: mdi.c:213
static BOOL CALLBACK GetCascadeChildProc(HWND hwnd, LPARAM lParam)
Definition: mdi.c:2000
#define WIN_GetFullHandle(h)
Definition: user_x.h:108
#define WM_MDITILE
Definition: winuser.h:1800
#define ICON_BIG
Definition: tnclass.cpp:51
#define WM_VSCROLL
Definition: winuser.h:1726
HMENU hFrameMenu
Definition: mdi.c:119
int * LPINT
Definition: windef.h:178
#define SM_CXMIN
Definition: winuser.h:979
#define WM_MDIMAXIMIZE
Definition: winuser.h:1799
#define WS_MAXIMIZE
Definition: pedump.c:623