Release 951003
[wine/multimedia.git] / windows / mdi.c
blob76f6d87f545f52c468e3b91f514680009c6c4822
1 /* MDI.C
3 * Copyright 1994, Bob Amstadt
5 * This file contains routines to support MDI features.
6 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <math.h>
10 #include "windows.h"
11 #include "win.h"
12 #include "nonclient.h"
13 #include "mdi.h"
14 #include "user.h"
15 #include "menu.h"
16 #include "sysmetrics.h"
17 #include "stddebug.h"
18 #include "debug.h"
20 /**********************************************************************
21 * MDIRecreateMenuList
23 void MDIRecreateMenuList(MDICLIENTINFO *ci)
25 HLOCAL hinfo;
27 char buffer[128];
28 int id, n, index;
30 dprintf_mdi(stddeb, "MDIRecreateMenuList: hWindowMenu "NPFMT"\n",
31 ci->hWindowMenu);
33 id = ci->idFirstChild;
34 while (DeleteMenu(ci->hWindowMenu, id, MF_BYCOMMAND))
35 id++;
37 dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, idFirstChild %04x\n",
38 id, ci->idFirstChild);
40 if (!ci->flagMenuAltered)
42 ci->flagMenuAltered = TRUE;
43 AppendMenu(ci->hWindowMenu, MF_SEPARATOR, 0, NULL);
46 id = ci->idFirstChild;
47 index = 1;
48 for (hinfo = ci->infoActiveChildren; hinfo != 0;)
50 MDICHILDINFO *chi = USER_HEAP_LIN_ADDR(hinfo);
52 n = sprintf(buffer, "%d ", index++);
53 GetWindowText(chi->hwnd, buffer + n, sizeof(buffer) - n - 1);
55 dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, '%s'\n",
56 id, buffer);
58 AppendMenu(ci->hWindowMenu, MF_STRING, id++, buffer);
59 hinfo = chi->next;
63 /**********************************************************************
64 * MDISetMenu
65 * FIXME: This is not complete.
67 HMENU MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU hmenuFrame, HMENU hmenuWindow)
69 dprintf_mdi(stddeb, "WM_MDISETMENU: "NPFMT" %04x "NPFMT" "NPFMT"\n", hwnd, fRefresh, hmenuFrame, hmenuWindow);
70 if (!fRefresh) {
71 HWND hwndFrame = GetParent(hwnd);
72 HMENU oldFrameMenu = GetMenu(hwndFrame);
73 SetMenu(hwndFrame, hmenuFrame);
74 return oldFrameMenu;
76 return 0;
79 /**********************************************************************
80 * MDIIconArrange
82 WORD MDIIconArrange(HWND parent)
84 return ArrangeIconicWindows(parent); /* Any reason why the */
85 /* existing icon arrange */
86 /* can't be used here? */
87 /* -DRP */
90 /**********************************************************************
91 * MDICreateChild
93 HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
95 MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
96 HWND hwnd;
97 int spacing;
100 * Create child window
102 cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
104 /* The child windows should probably */
105 /* stagger, shouldn't they? -DRP */
106 spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
107 cs->x = ci->nActiveChildren * spacing;
108 cs->y = ci->nActiveChildren * spacing;
110 hwnd = CreateWindow( cs->szClass, cs->szTitle,
111 WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
112 WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
113 WS_THICKFRAME | WS_VISIBLE | cs->style,
114 cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0,
115 w->hInstance, (SEGPTR)lParam);
117 if (hwnd)
119 HANDLE h = USER_HEAP_ALLOC( sizeof(MDICHILDINFO) );
120 MDICHILDINFO *child_info = USER_HEAP_LIN_ADDR(h);
122 if (!h)
124 DestroyWindow(hwnd);
125 return 0;
128 ci->nActiveChildren++;
130 child_info->next = ci->infoActiveChildren;
131 child_info->prev = 0;
132 child_info->hwnd = hwnd;
134 if (ci->infoActiveChildren) {
135 MDICHILDINFO *nextinfo = USER_HEAP_LIN_ADDR(ci->infoActiveChildren);
136 nextinfo->prev = h;
139 ci->infoActiveChildren = h;
141 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
144 return hwnd;
147 /**********************************************************************
148 * MDIDestroyChild
150 HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
151 HWND child, BOOL flagDestroy)
153 MDICHILDINFO *chi;
154 HLOCAL hinfo;
156 hinfo = ci->infoActiveChildren;
157 while (hinfo != 0) {
158 chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
159 if (chi->hwnd == child) break;
160 hinfo = chi->next;
163 if (hinfo != 0)
165 if (chi->prev)
166 ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next;
167 if (chi->next)
168 ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev;
169 if (ci->infoActiveChildren == hinfo)
170 ci->infoActiveChildren = chi->next;
172 ci->nActiveChildren--;
174 if (chi->hwnd == ci->hwndActiveChild)
175 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
177 USER_HEAP_FREE(hinfo);
179 if (flagDestroy)
180 DestroyWindow(child);
183 return 0;
186 /**********************************************************************
187 * MDIBringChildToTop
189 void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom)
191 HLOCAL hinfo;
192 MDICHILDINFO *chi;
193 MDICLIENTINFO *ci;
194 WND *w;
195 int i;
197 w = WIN_FindWndPtr(parent);
198 ci = (MDICLIENTINFO *) w->wExtra;
200 dprintf_mdi(stddeb, "MDIBringToTop: id %04x, by_id %d\n", id, by_id);
202 if (by_id)
203 id -= ci->idFirstChild;
204 if (!by_id || id < ci->nActiveChildren)
206 hinfo = ci->infoActiveChildren;
208 if (by_id)
210 for (i = 0; i < id; i++)
211 hinfo = ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo))->next;
212 chi = USER_HEAP_LIN_ADDR(hinfo);
214 else
216 while (hinfo != 0) {
217 chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
218 if (chi->hwnd == (HWND)id) break;
219 hinfo = chi->next;
223 if (hinfo == 0)
224 return;
226 dprintf_mdi(stddeb, "MDIBringToTop: child "NPFMT"\n", chi->hwnd);
227 if (hinfo != ci->infoActiveChildren)
229 if (ci->flagChildMaximized)
231 RECT rectOldRestore, rect;
233 w = WIN_FindWndPtr(chi->hwnd);
235 rectOldRestore = ci->rectRestore;
236 GetWindowRect(chi->hwnd, &ci->rectRestore);
238 rect.top = (ci->rectMaximize.top -
239 (w->rectClient.top - w->rectWindow.top));
240 rect.bottom = (ci->rectMaximize.bottom +
241 (w->rectWindow.bottom - w->rectClient.bottom));
242 rect.left = (ci->rectMaximize.left -
243 (w->rectClient.left - w->rectWindow.left));
244 rect.right = (ci->rectMaximize.right +
245 (w->rectWindow.right - w->rectClient.right));
246 w->dwStyle |= WS_MAXIMIZE;
247 SetWindowPos(chi->hwnd, HWND_TOP, rect.left, rect.top,
248 rect.right - rect.left + 1,
249 rect.bottom - rect.top + 1, 0);
250 SendMessage(chi->hwnd, WM_SIZE, SIZE_MAXIMIZED,
251 MAKELONG(w->rectClient.right-w->rectClient.left,
252 w->rectClient.bottom-w->rectClient.top));
254 w = WIN_FindWndPtr(ci->hwndActiveChild);
255 w->dwStyle &= ~WS_MAXIMIZE;
256 SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM,
257 rectOldRestore.left, rectOldRestore.top,
258 rectOldRestore.right - rectOldRestore.left + 1,
259 rectOldRestore.bottom - rectOldRestore.top + 1,
260 SWP_NOACTIVATE |
261 (send_to_bottom ? 0 : SWP_NOZORDER));
263 else
265 SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0,
266 SWP_NOMOVE | SWP_NOSIZE );
267 if (send_to_bottom)
269 SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 0, 0, 0, 0,
270 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
274 if (chi->next)
275 ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev;
277 if (chi->prev)
278 ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next;
280 chi->prev = 0;
281 chi->next = ci->infoActiveChildren;
282 ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = hinfo;
283 ci->infoActiveChildren = hinfo;
285 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
288 dprintf_mdi(stddeb, "MDIBringToTop: pos %04x, hwnd "NPFMT"\n",
289 id, chi->hwnd);
293 /**********************************************************************
294 * MDIMaximizeChild
296 LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
298 WND *w = WIN_FindWndPtr(child);
299 RECT rect;
301 MDIBringChildToTop(parent, child, FALSE, FALSE);
302 ci->rectRestore = w->rectWindow;
304 rect.top = (ci->rectMaximize.top -
305 (w->rectClient.top - w->rectWindow.top));
306 rect.bottom = (ci->rectMaximize.bottom +
307 (w->rectWindow.bottom - w->rectClient.bottom));
308 rect.left = (ci->rectMaximize.left -
309 (w->rectClient.left - w->rectWindow.left));
310 rect.right = (ci->rectMaximize.right +
311 (w->rectWindow.right - w->rectClient.right));
312 w->dwStyle |= WS_MAXIMIZE;
313 SetWindowPos(child, 0, rect.left, rect.top,
314 rect.right - rect.left + 1, rect.bottom - rect.top + 1,
315 SWP_NOACTIVATE | SWP_NOZORDER);
317 ci->flagChildMaximized = TRUE;
319 SendMessage(child, WM_SIZE, SIZE_MAXIMIZED,
320 MAKELONG(w->rectClient.right-w->rectClient.left,
321 w->rectClient.bottom-w->rectClient.top));
322 SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
324 return 0;
327 /**********************************************************************
328 * MDIRestoreChild
330 LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
332 HWND child;
334 dprintf_mdi(stddeb,"restoring mdi child\n");
336 child = ci->hwndActiveChild;
337 ci->flagChildMaximized = FALSE;
339 ShowWindow(child, SW_RESTORE); /* display the window */
340 MDIBringChildToTop(parent, child, FALSE, FALSE);
341 SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
343 return 0;
346 /**********************************************************************
347 * MDIChildActivated
349 LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent)
351 HLOCAL hinfo;
352 MDICHILDINFO *chi;
353 HWND deact_hwnd;
354 HWND act_hwnd;
355 LONG lParam;
357 dprintf_mdi(stddeb, "MDIChildActivate: top "NPFMT"\n", w->hwndChild);
359 hinfo = ci->infoActiveChildren;
360 if (hinfo)
362 chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
363 deact_hwnd = ci->hwndActiveChild;
364 act_hwnd = chi->hwnd; /* FIX: Hack */
365 lParam = ((LONG) deact_hwnd << 16) | (LONG)act_hwnd;
367 dprintf_mdi(stddeb, "MDIChildActivate: deact "NPFMT", act "NPFMT"\n",
368 deact_hwnd, act_hwnd);
370 ci->hwndActiveChild = act_hwnd;
372 if (deact_hwnd != act_hwnd)
374 MDIRecreateMenuList(ci);
375 SendMessage(deact_hwnd, WM_NCACTIVATE, FALSE, 0);
376 SendMessage(deact_hwnd, WM_MDIACTIVATE, FALSE, lParam);
379 SendMessage(act_hwnd, WM_NCACTIVATE, TRUE, 0);
380 SendMessage(act_hwnd, WM_MDIACTIVATE, TRUE, lParam);
383 if (hinfo || ci->nActiveChildren == 0)
385 MDIRecreateMenuList(ci);
386 SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
389 return 0;
392 /**********************************************************************
393 * MDICascade
395 LONG MDICascade(HWND parent, MDICLIENTINFO *ci)
397 HLOCAL hinfo;
398 MDICHILDINFO *chi;
399 RECT rect;
400 int spacing, xsize, ysize;
401 int x, y;
403 if (ci->flagChildMaximized)
404 MDIRestoreChild(parent, ci);
406 /* If there aren't any children, don't even bother.
408 if (ci->nActiveChildren == 0)
409 return 0;
411 GetClientRect(parent, &rect);
412 spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
413 ysize = rect.bottom - 8 * spacing;
414 xsize = rect.right - 8 * spacing;
416 dprintf_mdi(stddeb,
417 "MDICascade: Client wnd at (%d,%d) - (%d,%d), spacing %d\n",
418 rect.left, rect.top, rect.right, rect.bottom, spacing);
419 dprintf_mdi(stddeb, "MDICascade: searching for last child\n");
420 hinfo = ci->infoActiveChildren;
421 while(1) {
422 chi = USER_HEAP_LIN_ADDR(hinfo);
423 if (chi->next == 0) break;
424 hinfo = chi->next;
427 dprintf_mdi(stddeb, "MDICascade: last child is "NPFMT"\n", chi->hwnd);
428 x = 0;
429 y = 0;
430 while (hinfo != 0)
432 chi = USER_HEAP_LIN_ADDR(hinfo);
433 dprintf_mdi(stddeb, "MDICascade: move "NPFMT" to (%d,%d) size [%d,%d]\n",
434 chi->hwnd, x, y, xsize, ysize);
435 if (IsIconic(chi->hwnd)) continue;
436 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
437 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
439 x += spacing;
440 y += spacing;
442 hinfo = chi->prev;
445 return 0;
448 /**********************************************************************
449 * MDITile
451 LONG MDITile(HWND parent, MDICLIENTINFO *ci)
453 HLOCAL hinfo;
454 MDICHILDINFO *chi;
455 RECT rect;
456 int xsize, ysize;
457 int x, y;
458 int rows, columns;
459 int r, c;
460 int i;
462 if (ci->flagChildMaximized)
463 MDIRestoreChild(parent, ci);
465 /* If there aren't any children, don't even bother.
467 if (ci->nActiveChildren == 0)
468 return 0;
470 GetClientRect(parent, &rect);
471 rows = (int) sqrt((double) ci->nActiveChildren);
472 columns = ci->nActiveChildren / rows;
473 ysize = rect.bottom / rows;
474 xsize = rect.right / columns;
476 hinfo = ci->infoActiveChildren;
477 x = 0;
478 i = 0;
479 for (c = 1; c <= columns; c++)
481 if (c == columns)
483 rows = ci->nActiveChildren - i;
484 ysize = rect.bottom / rows;
487 y = 0;
488 for (r = 1; r <= rows; r++, i++)
490 chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
491 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
492 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
494 y += ysize;
495 hinfo = chi->next;
498 x += xsize;
502 return 0;
505 /**********************************************************************
506 * MDIHandleLButton
508 BOOL MDIHandleLButton(HWND hwndFrame, HWND hwndClient,
509 WORD wParam, LONG lParam)
511 MDICLIENTINFO *ci;
512 WND *w;
513 RECT rect;
514 WORD x;
516 w = WIN_FindWndPtr(hwndClient);
517 ci = (MDICLIENTINFO *) w->wExtra;
519 if (wParam == HTMENU && ci->flagChildMaximized)
521 x = LOWORD(lParam);
523 NC_GetInsideRect(hwndFrame, &rect);
524 if (x < rect.left + SYSMETRICS_CXSIZE)
526 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
527 SC_CLOSE, lParam);
528 return TRUE;
530 else if (x >= rect.right - SYSMETRICS_CXSIZE)
532 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
533 SC_RESTORE, lParam);
534 return TRUE;
538 return FALSE;
541 /**********************************************************************
542 * MDIPaintMaximized
544 LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
545 WORD wParam, LONG lParam)
547 static HBITMAP hbitmapClose = 0;
548 static HBITMAP hbitmapMaximized = 0;
550 MDICLIENTINFO *ci;
551 WND *w;
552 HDC hdc, hdcMem;
553 RECT rect;
554 WND *wndPtr = WIN_FindWndPtr(hwndFrame);
556 w = WIN_FindWndPtr(hwndClient);
557 ci = (MDICLIENTINFO *) w->wExtra;
559 dprintf_mdi(stddeb, "MDIPaintMaximized: frame "NPFMT", client "NPFMT
560 ", max flag %d, menu %04x\n", hwndFrame, hwndClient,
561 ci->flagChildMaximized, wndPtr ? wndPtr->wIDmenu : 0);
563 if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0)
565 NC_DoNCPaint(hwndFrame, wParam, TRUE);
567 hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW);
568 if (!hdc) return 0;
570 hdcMem = CreateCompatibleDC(hdc);
572 if (hbitmapClose == 0)
574 hbitmapClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_OLD_CLOSE));
575 hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
578 dprintf_mdi(stddeb,
579 "MDIPaintMaximized: hdcMem "NPFMT", close bitmap "NPFMT", "
580 "maximized bitmap "NPFMT"\n",
581 hdcMem, hbitmapClose, hbitmapMaximized);
583 NC_GetInsideRect(hwndFrame, &rect);
584 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
585 SelectObject(hdcMem, hbitmapClose);
586 BitBlt(hdc, rect.left, rect.top + 1,
587 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
588 hdcMem, 1, 1, SRCCOPY);
590 NC_GetInsideRect(hwndFrame, &rect);
591 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
592 rect.left = rect.right - SYSMETRICS_CXSIZE;
593 SelectObject(hdcMem, hbitmapMaximized);
594 BitBlt(hdc, rect.left, rect.top + 1,
595 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
596 hdcMem, 1, 1, SRCCOPY);
598 NC_GetInsideRect(hwndFrame, &rect);
599 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
600 rect.left += SYSMETRICS_CXSIZE;
601 rect.right -= SYSMETRICS_CXSIZE;
602 rect.bottom = rect.top + SYSMETRICS_CYMENU;
604 MENU_DrawMenuBar(hdc, &rect, hwndFrame, FALSE);
606 DeleteDC(hdcMem);
607 ReleaseDC(hwndFrame, hdc);
609 else
610 return DefWindowProc(hwndFrame, message, wParam, lParam);
612 return 0;
615 /**********************************************************************
616 * MDIClientWndProc
618 * This function is the handler for all MDI requests.
620 LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
622 LPCREATESTRUCT cs;
623 LPCLIENTCREATESTRUCT ccs;
624 MDICLIENTINFO *ci;
625 WND *w;
627 w = WIN_FindWndPtr(hwnd);
628 ci = (MDICLIENTINFO *) w->wExtra;
630 switch (message)
632 case WM_CHILDACTIVATE:
633 return MDIChildActivated(w, ci, hwnd);
635 case WM_CREATE:
636 cs = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam);
637 ccs = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams);
638 ci->hWindowMenu = ccs->hWindowMenu;
639 ci->idFirstChild = ccs->idFirstChild;
640 ci->infoActiveChildren = 0;
641 ci->flagMenuAltered = FALSE;
642 ci->flagChildMaximized = FALSE;
643 w->dwStyle |= WS_CLIPCHILDREN;
645 GetClientRect(w->hwndParent, &ci->rectMaximize);
646 MoveWindow(hwnd, 0, 0,
647 ci->rectMaximize.right, ci->rectMaximize.bottom, 1);
649 return 0;
651 case WM_MDIACTIVATE:
652 MDIBringChildToTop(hwnd, wParam, FALSE, FALSE);
653 return 0;
655 case WM_MDICASCADE:
656 return MDICascade(hwnd, ci);
658 case WM_MDICREATE:
659 return (LONG)MDICreateChild(w, ci, hwnd, lParam );
661 case WM_MDIDESTROY:
662 return MDIDestroyChild(w, ci, hwnd, wParam, TRUE);
664 case WM_MDIGETACTIVE:
665 return ((LONG) ci->hwndActiveChild |
666 ((LONG) ci->flagChildMaximized << 16));
668 case WM_MDIICONARRANGE:
669 return MDIIconArrange(hwnd);
671 case WM_MDIMAXIMIZE:
672 return MDIMaximizeChild(hwnd, wParam, ci);
674 case WM_MDINEXT:
675 MDIBringChildToTop(hwnd, wParam, FALSE, TRUE);
676 break;
678 case WM_MDIRESTORE:
679 return MDIRestoreChild(hwnd, ci);
681 case WM_MDISETMENU:
682 return MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
684 case WM_MDITILE:
685 return MDITile(hwnd, ci);
687 case WM_NCACTIVATE:
688 SendMessage(ci->hwndActiveChild, message, wParam, lParam);
689 break;
691 case WM_PARENTNOTIFY:
692 if (wParam == WM_DESTROY)
693 #ifdef WINELIB32
694 return MDIDestroyChild(w, ci, hwnd, lParam, FALSE);
695 #else
696 return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE);
697 #endif
698 else if (wParam == WM_LBUTTONDOWN)
699 MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE);
700 break;
702 case WM_SIZE:
703 GetClientRect(w->hwndParent, &ci->rectMaximize);
704 break;
708 return DefWindowProc(hwnd, message, wParam, lParam);
711 /**********************************************************************
712 * DefFrameProc (USER.445)
715 LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message,
716 WPARAM wParam, LPARAM lParam)
718 if (hwndMDIClient)
720 switch (message)
722 case WM_COMMAND:
723 MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE);
724 break;
726 case WM_NCLBUTTONDOWN:
727 if (MDIHandleLButton(hwnd, hwndMDIClient, wParam, lParam))
728 return 0;
729 break;
731 case WM_NCACTIVATE:
732 SendMessage(hwndMDIClient, message, wParam, lParam);
733 return MDIPaintMaximized(hwnd, hwndMDIClient,
734 message, wParam, lParam);
736 case WM_NCPAINT:
737 return MDIPaintMaximized(hwnd, hwndMDIClient,
738 message, wParam, lParam);
740 case WM_SETFOCUS:
741 SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam);
742 break;
744 case WM_SIZE:
745 MoveWindow(hwndMDIClient, 0, 0,
746 LOWORD(lParam), HIWORD(lParam), TRUE);
747 break;
751 return DefWindowProc(hwnd, message, wParam, lParam);
754 /**********************************************************************
755 * DefMDIChildProc (USER.447)
758 #ifdef WINELIB32
759 LONG DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
760 #else
761 LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
762 #endif
764 MDICLIENTINFO *ci;
765 WND *w;
767 w = WIN_FindWndPtr(GetParent(hwnd));
768 ci = (MDICLIENTINFO *) w->wExtra;
770 switch (message)
772 case WM_NCHITTEST:
773 ci->hwndHitTest = hwnd;
774 break;
776 case WM_NCPAINT:
777 NC_DoNCPaint( hwnd, hwnd == ci->hwndActiveChild, FALSE );
778 return 0;
780 case WM_SYSCOMMAND:
781 switch (wParam)
783 case SC_MAXIMIZE:
784 return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, (WPARAM)hwnd, 0);
786 case SC_RESTORE:
787 return SendMessage(GetParent(hwnd), WM_MDIRESTORE, (WPARAM)hwnd, 0);
789 break;
793 return DefWindowProc(hwnd, message, wParam, lParam);
796 /**********************************************************************
797 * TranslateMDISysAccel (USER.451)
800 BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
802 return 0;
806 /***********************************************************************
807 * CalcChildScroll (USER.462)
809 void CalcChildScroll( HWND hwnd, WORD scroll )
811 RECT childRect, clientRect;
812 HWND hwndChild;
814 GetClientRect( hwnd, &clientRect );
815 SetRectEmpty( &childRect );
816 hwndChild = GetWindow( hwnd, GW_CHILD );
817 while (hwndChild)
819 WND *wndPtr = WIN_FindWndPtr( hwndChild );
820 UnionRect( &childRect, &wndPtr->rectWindow, &childRect );
821 hwndChild = wndPtr->hwndNext;
823 UnionRect( &childRect, &clientRect, &childRect );
825 if ((scroll == SB_HORZ) || (scroll == SB_BOTH))
827 SetScrollRange( hwnd, SB_HORZ, childRect.left,
828 childRect.right - clientRect.right, FALSE );
829 SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE );
831 if ((scroll == SB_VERT) || (scroll == SB_BOTH))
833 SetScrollRange( hwnd, SB_VERT, childRect.top,
834 childRect.bottom - clientRect.bottom, FALSE );
835 SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE );