Release 951105
[wine/multimedia.git] / windows / mdi.c
blobe1a3ddfab2a6661661b3ea545c89ae5bf8d7e9d2
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 (%ld,%ld) - (%ld,%ld), spacing %d\n",
418 (LONG)rect.left, (LONG)rect.top, (LONG)rect.right, (LONG)rect.bottom,
419 spacing);
420 dprintf_mdi(stddeb, "MDICascade: searching for last child\n");
421 hinfo = ci->infoActiveChildren;
422 while(1) {
423 chi = USER_HEAP_LIN_ADDR(hinfo);
424 if (chi->next == 0) break;
425 hinfo = chi->next;
428 dprintf_mdi(stddeb, "MDICascade: last child is "NPFMT"\n", chi->hwnd);
429 x = 0;
430 y = 0;
431 while (hinfo != 0)
433 chi = USER_HEAP_LIN_ADDR(hinfo);
434 dprintf_mdi(stddeb, "MDICascade: move "NPFMT" to (%d,%d) size [%d,%d]\n",
435 chi->hwnd, x, y, xsize, ysize);
436 if (IsIconic(chi->hwnd)) continue;
437 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
438 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
440 x += spacing;
441 y += spacing;
443 hinfo = chi->prev;
446 return 0;
449 /**********************************************************************
450 * MDITile
452 LONG MDITile(HWND parent, MDICLIENTINFO *ci)
454 HLOCAL hinfo;
455 MDICHILDINFO *chi;
456 RECT rect;
457 int xsize, ysize;
458 int x, y;
459 int rows, columns;
460 int r, c;
461 int i;
463 if (ci->flagChildMaximized)
464 MDIRestoreChild(parent, ci);
466 /* If there aren't any children, don't even bother.
468 if (ci->nActiveChildren == 0)
469 return 0;
471 GetClientRect(parent, &rect);
472 rows = (int) sqrt((double) ci->nActiveChildren);
473 columns = ci->nActiveChildren / rows;
474 ysize = rect.bottom / rows;
475 xsize = rect.right / columns;
477 hinfo = ci->infoActiveChildren;
478 x = 0;
479 i = 0;
480 for (c = 1; c <= columns; c++)
482 if (c == columns)
484 rows = ci->nActiveChildren - i;
485 ysize = rect.bottom / rows;
488 y = 0;
489 for (r = 1; r <= rows; r++, i++)
491 chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo);
492 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
493 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
495 y += ysize;
496 hinfo = chi->next;
499 x += xsize;
503 return 0;
506 /**********************************************************************
507 * MDIHandleLButton
509 BOOL MDIHandleLButton(HWND hwndFrame, HWND hwndClient,
510 WORD wParam, LONG lParam)
512 MDICLIENTINFO *ci;
513 WND *w;
514 RECT rect;
515 WORD x;
517 w = WIN_FindWndPtr(hwndClient);
518 ci = (MDICLIENTINFO *) w->wExtra;
520 if (wParam == HTMENU && ci->flagChildMaximized)
522 x = LOWORD(lParam);
524 NC_GetInsideRect(hwndFrame, &rect);
525 if (x < rect.left + SYSMETRICS_CXSIZE)
527 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
528 SC_CLOSE, lParam);
529 return TRUE;
531 else if (x >= rect.right - SYSMETRICS_CXSIZE)
533 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
534 SC_RESTORE, lParam);
535 return TRUE;
539 return FALSE;
542 /**********************************************************************
543 * MDIPaintMaximized
545 LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
546 WORD wParam, LONG lParam)
548 static HBITMAP hbitmapClose = 0;
549 static HBITMAP hbitmapMaximized = 0;
551 MDICLIENTINFO *ci;
552 WND *w;
553 HDC hdc, hdcMem;
554 RECT rect;
555 WND *wndPtr = WIN_FindWndPtr(hwndFrame);
557 w = WIN_FindWndPtr(hwndClient);
558 ci = (MDICLIENTINFO *) w->wExtra;
560 dprintf_mdi(stddeb, "MDIPaintMaximized: frame "NPFMT", client "NPFMT
561 ", max flag %d, menu %04x\n", hwndFrame, hwndClient,
562 ci->flagChildMaximized, wndPtr ? wndPtr->wIDmenu : 0);
564 if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0)
566 NC_DoNCPaint(hwndFrame, wParam, TRUE);
568 hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW);
569 if (!hdc) return 0;
571 hdcMem = CreateCompatibleDC(hdc);
573 if (hbitmapClose == 0)
575 hbitmapClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_OLD_CLOSE));
576 hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
579 dprintf_mdi(stddeb,
580 "MDIPaintMaximized: hdcMem "NPFMT", close bitmap "NPFMT", "
581 "maximized bitmap "NPFMT"\n",
582 hdcMem, hbitmapClose, hbitmapMaximized);
584 NC_GetInsideRect(hwndFrame, &rect);
585 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
586 SelectObject(hdcMem, hbitmapClose);
587 BitBlt(hdc, rect.left, rect.top + 1,
588 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
589 hdcMem, 1, 1, SRCCOPY);
591 NC_GetInsideRect(hwndFrame, &rect);
592 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
593 rect.left = rect.right - SYSMETRICS_CXSIZE;
594 SelectObject(hdcMem, hbitmapMaximized);
595 BitBlt(hdc, rect.left, rect.top + 1,
596 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
597 hdcMem, 1, 1, SRCCOPY);
599 NC_GetInsideRect(hwndFrame, &rect);
600 rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0;
601 rect.left += SYSMETRICS_CXSIZE;
602 rect.right -= SYSMETRICS_CXSIZE;
603 rect.bottom = rect.top + SYSMETRICS_CYMENU;
605 MENU_DrawMenuBar(hdc, &rect, hwndFrame, FALSE);
607 DeleteDC(hdcMem);
608 ReleaseDC(hwndFrame, hdc);
610 else
611 return DefWindowProc(hwndFrame, message, wParam, lParam);
613 return 0;
616 /**********************************************************************
617 * MDIClientWndProc
619 * This function is the handler for all MDI requests.
621 LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
623 LPCREATESTRUCT cs;
624 LPCLIENTCREATESTRUCT ccs;
625 MDICLIENTINFO *ci;
626 WND *w;
628 w = WIN_FindWndPtr(hwnd);
629 ci = (MDICLIENTINFO *) w->wExtra;
631 switch (message)
633 case WM_CHILDACTIVATE:
634 return MDIChildActivated(w, ci, hwnd);
636 case WM_CREATE:
637 cs = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam);
638 ccs = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams);
639 ci->hWindowMenu = ccs->hWindowMenu;
640 ci->idFirstChild = ccs->idFirstChild;
641 ci->infoActiveChildren = 0;
642 ci->flagMenuAltered = FALSE;
643 ci->flagChildMaximized = FALSE;
644 w->dwStyle |= WS_CLIPCHILDREN;
646 GetClientRect(w->hwndParent, &ci->rectMaximize);
647 MoveWindow(hwnd, 0, 0,
648 ci->rectMaximize.right, ci->rectMaximize.bottom, 1);
650 return 0;
652 case WM_MDIACTIVATE:
653 MDIBringChildToTop(hwnd, wParam, FALSE, FALSE);
654 return 0;
656 case WM_MDICASCADE:
657 return MDICascade(hwnd, ci);
659 case WM_MDICREATE:
660 return (LONG)MDICreateChild(w, ci, hwnd, lParam );
662 case WM_MDIDESTROY:
663 return MDIDestroyChild(w, ci, hwnd, wParam, TRUE);
665 case WM_MDIGETACTIVE:
666 return ((LONG) ci->hwndActiveChild |
667 ((LONG) ci->flagChildMaximized << 16));
669 case WM_MDIICONARRANGE:
670 return MDIIconArrange(hwnd);
672 case WM_MDIMAXIMIZE:
673 return MDIMaximizeChild(hwnd, wParam, ci);
675 case WM_MDINEXT:
676 MDIBringChildToTop(hwnd, wParam, FALSE, TRUE);
677 break;
679 case WM_MDIRESTORE:
680 return MDIRestoreChild(hwnd, ci);
682 case WM_MDISETMENU:
683 return MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
685 case WM_MDITILE:
686 return MDITile(hwnd, ci);
688 case WM_NCACTIVATE:
689 SendMessage(ci->hwndActiveChild, message, wParam, lParam);
690 break;
692 case WM_PARENTNOTIFY:
693 if (wParam == WM_DESTROY)
694 #ifdef WINELIB32
695 return MDIDestroyChild(w, ci, hwnd, lParam, FALSE);
696 #else
697 return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE);
698 #endif
699 else if (wParam == WM_LBUTTONDOWN)
700 MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE);
701 break;
703 case WM_SIZE:
704 GetClientRect(w->hwndParent, &ci->rectMaximize);
705 break;
709 return DefWindowProc(hwnd, message, wParam, lParam);
712 /**********************************************************************
713 * DefFrameProc (USER.445)
716 LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message,
717 WPARAM wParam, LPARAM lParam)
719 if (hwndMDIClient)
721 switch (message)
723 case WM_COMMAND:
724 MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE);
725 break;
727 case WM_NCLBUTTONDOWN:
728 if (MDIHandleLButton(hwnd, hwndMDIClient, wParam, lParam))
729 return 0;
730 break;
732 case WM_NCACTIVATE:
733 SendMessage(hwndMDIClient, message, wParam, lParam);
734 return MDIPaintMaximized(hwnd, hwndMDIClient,
735 message, wParam, lParam);
737 case WM_NCPAINT:
738 return MDIPaintMaximized(hwnd, hwndMDIClient,
739 message, wParam, lParam);
741 case WM_SETFOCUS:
742 SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam);
743 break;
745 case WM_SIZE:
746 MoveWindow(hwndMDIClient, 0, 0,
747 LOWORD(lParam), HIWORD(lParam), TRUE);
748 break;
752 return DefWindowProc(hwnd, message, wParam, lParam);
755 /**********************************************************************
756 * DefMDIChildProc (USER.447)
759 #ifdef WINELIB32
760 LONG DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
761 #else
762 LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
763 #endif
765 MDICLIENTINFO *ci;
766 WND *w;
768 w = WIN_FindWndPtr(GetParent(hwnd));
769 ci = (MDICLIENTINFO *) w->wExtra;
771 switch (message)
773 case WM_NCHITTEST:
774 ci->hwndHitTest = hwnd;
775 break;
777 case WM_NCPAINT:
778 NC_DoNCPaint( hwnd, hwnd == ci->hwndActiveChild, FALSE );
779 return 0;
781 case WM_SYSCOMMAND:
782 switch (wParam)
784 case SC_MAXIMIZE:
785 return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, (WPARAM)hwnd, 0);
787 case SC_RESTORE:
788 return SendMessage(GetParent(hwnd), WM_MDIRESTORE, (WPARAM)hwnd, 0);
790 break;
794 return DefWindowProc(hwnd, message, wParam, lParam);
797 /**********************************************************************
798 * TranslateMDISysAccel (USER.451)
801 BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
803 return 0;
807 /***********************************************************************
808 * CalcChildScroll (USER.462)
810 void CalcChildScroll( HWND hwnd, WORD scroll )
812 RECT childRect, clientRect;
813 HWND hwndChild;
815 GetClientRect( hwnd, &clientRect );
816 SetRectEmpty( &childRect );
817 hwndChild = GetWindow( hwnd, GW_CHILD );
818 while (hwndChild)
820 WND *wndPtr = WIN_FindWndPtr( hwndChild );
821 UnionRect( &childRect, &wndPtr->rectWindow, &childRect );
822 hwndChild = wndPtr->hwndNext;
824 UnionRect( &childRect, &clientRect, &childRect );
826 if ((scroll == SB_HORZ) || (scroll == SB_BOTH))
828 SetScrollRange( hwnd, SB_HORZ, childRect.left,
829 childRect.right - clientRect.right, FALSE );
830 SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE );
832 if ((scroll == SB_VERT) || (scroll == SB_BOTH))
834 SetScrollRange( hwnd, SB_VERT, childRect.top,
835 childRect.bottom - clientRect.bottom, FALSE );
836 SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE );