blob: ae04cd46816b735bca3eaf21338c13feaae76bef [file] [log] [blame]
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001/* MDI.C
2 *
3 * Copyright 1994, Bob Amstadt
4 *
5 * This file contains routines to support MDI features.
6 */
7#include <stdlib.h>
8#include <stdio.h>
9#include "windows.h"
10#include "win.h"
11#include "mdi.h"
12#include "user.h"
Alexandre Julliard58199531994-04-21 01:20:00 +000013#include "sysmetrics.h"
14#include "menu.h"
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000015
16/* #define DEBUG_MDI /* */
17
18/**********************************************************************
19 * MDIRecreateMenuList
20 */
21void
22MDIRecreateMenuList(MDICLIENTINFO *ci)
23{
24 MDICHILDINFO *chi;
25 char buffer[128];
26 int id, n, index;
27
28#ifdef DEBUG_MDI
29 fprintf(stderr, "MDIRecreateMenuList: hWindowMenu %04.4x\n",
30 ci->hWindowMenu);
31#endif
32
33 id = ci->idFirstChild;
34 while (DeleteMenu(ci->hWindowMenu, id, MF_BYCOMMAND))
35 id++;
36
37#ifdef DEBUG_MDI
38 fprintf(stderr, "MDIRecreateMenuList: id %04.4x, idFirstChild %04.4x\n",
39 id, ci->idFirstChild);
40#endif
41
42 if (!ci->flagMenuAltered)
43 {
44 ci->flagMenuAltered = TRUE;
45 AppendMenu(ci->hWindowMenu, MF_SEPARATOR, 0, NULL);
46 }
47
48 id = ci->idFirstChild;
49 index = 1;
50 for (chi = ci->infoActiveChildren; chi != NULL; chi = chi->next)
51 {
52 n = sprintf(buffer, "%d ", index++);
53 GetWindowText(chi->hwnd, buffer + n, sizeof(buffer) - n - 1);
54
55#ifdef DEBUG_MDI
56 fprintf(stderr, "MDIRecreateMenuList: id %04.4x, '%s'\n",
57 id, buffer);
58#endif
59
60 AppendMenu(ci->hWindowMenu, MF_STRING, id++, buffer);
61 }
62}
63
64/**********************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +000065 * MDICreateChild
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000066 */
67HWND
Alexandre Julliard58199531994-04-21 01:20:00 +000068MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPMDICREATESTRUCT cs)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000069{
70 HWND hwnd;
71
72 /*
73 * Create child window
74 */
75 cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
76
77 hwnd = CreateWindowEx(0, cs->szClass, cs->szTitle,
78 WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
79 WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
80 WS_THICKFRAME | WS_VISIBLE | cs->style,
81 cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0,
Alexandre Julliard58199531994-04-21 01:20:00 +000082 w->hInstance, (LPSTR) cs->lParam);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000083
84 if (hwnd)
85 {
86 HANDLE h = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MDICHILDINFO));
87 MDICHILDINFO *child_info = USER_HEAP_ADDR(h);
88 if (!h)
89 {
90 DestroyWindow(hwnd);
91 return 0;
92 }
93
94 ci->nActiveChildren++;
95
96 child_info->next = ci->infoActiveChildren;
97 child_info->prev = NULL;
98 child_info->hwnd = hwnd;
99
100 if (ci->infoActiveChildren)
101 ci->infoActiveChildren->prev = child_info;
102
103 ci->infoActiveChildren = child_info;
104
105 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
106 }
107
108 return hwnd;
109}
110
111/**********************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +0000112 * MDIDestroyChild
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000113 */
114HWND
Alexandre Julliard58199531994-04-21 01:20:00 +0000115MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, HWND child,
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000116 BOOL flagDestroy)
117{
118 MDICHILDINFO *chi;
119
120 chi = ci->infoActiveChildren;
121 while (chi && chi->hwnd != child)
122 chi = chi->next;
123
124 if (chi)
125 {
126 if (chi->prev)
127 chi->prev->next = chi->next;
128 if (chi->next)
129 chi->next->prev = chi->prev;
130 if (ci->infoActiveChildren == chi)
131 ci->infoActiveChildren = chi->next;
132
133 ci->nActiveChildren--;
134
135 if (chi->hwnd == ci->hwndActiveChild)
136 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
137
Alexandre Julliard58199531994-04-21 01:20:00 +0000138 USER_HEAP_FREE((HANDLE) (LONG) chi);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000139
140 if (flagDestroy)
141 DestroyWindow(child);
142 }
143
144 return 0;
145}
146
147/**********************************************************************
148 * MDIBringChildToTop
149 */
Alexandre Julliard58199531994-04-21 01:20:00 +0000150void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000151{
152 MDICHILDINFO *chi;
153 MDICLIENTINFO *ci;
154 WND *w;
155 int i;
156
157 w = WIN_FindWndPtr(parent);
158 ci = (MDICLIENTINFO *) w->wExtra;
159
160#ifdef DEBUG_MDI
161 fprintf(stderr, "MDIBringToTop: id %04.4x, by_id %d\n", id, by_id);
162#endif
163
164 if (by_id)
165 id -= ci->idFirstChild;
166 if (!by_id || id < ci->nActiveChildren)
167 {
168 chi = ci->infoActiveChildren;
169
170 if (by_id)
171 {
172 for (i = 0; i < id; i++)
173 chi = chi->next;
174 }
175 else
176 {
177 while (chi && chi->hwnd != id)
178 chi = chi->next;
179 }
180
181 if (!chi)
182 return;
183
184#ifdef DEBUG_MDI
185 fprintf(stderr, "MDIBringToTop: child %04.4x\n", chi->hwnd);
186#endif
187 if (chi != ci->infoActiveChildren)
188 {
Alexandre Julliard58199531994-04-21 01:20:00 +0000189 if (ci->flagChildMaximized)
190 {
191 RECT rectOldRestore, rect;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000192
Alexandre Julliard58199531994-04-21 01:20:00 +0000193 w = WIN_FindWndPtr(chi->hwnd);
194
195 rectOldRestore = ci->rectRestore;
196 GetWindowRect(chi->hwnd, &ci->rectRestore);
197
198 rect.top = (ci->rectMaximize.top -
199 (w->rectClient.top - w->rectWindow.top));
200 rect.bottom = (ci->rectMaximize.bottom +
201 (w->rectWindow.bottom - w->rectClient.bottom));
202 rect.left = (ci->rectMaximize.left -
203 (w->rectClient.left - w->rectWindow.left));
204 rect.right = (ci->rectMaximize.right +
205 (w->rectWindow.right - w->rectClient.right));
206 w->dwStyle |= WS_MAXIMIZE;
207 SetWindowPos(chi->hwnd, HWND_TOP, rect.left, rect.top,
208 rect.right - rect.left + 1,
209 rect.bottom - rect.top + 1, 0);
210 SendMessage(chi->hwnd, WM_SIZE, SIZE_MAXIMIZED,
211 MAKELONG(w->rectClient.right-w->rectClient.left,
212 w->rectClient.bottom-w->rectClient.top));
213
214 w = WIN_FindWndPtr(ci->hwndActiveChild);
215 w->dwStyle &= ~WS_MAXIMIZE;
216 SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM,
217 rectOldRestore.left, rectOldRestore.top,
218 rectOldRestore.right - rectOldRestore.left + 1,
219 rectOldRestore.bottom - rectOldRestore.top + 1,
220 SWP_NOACTIVATE |
221 (send_to_bottom ? 0 : SWP_NOZORDER));
222 }
223 else
224 {
225 SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0,
226 SWP_NOMOVE | SWP_NOSIZE );
227 if (send_to_bottom)
228 {
229 SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 0, 0, 0, 0,
230 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
231 }
232 }
233
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000234 if (chi->next)
235 chi->next->prev = chi->prev;
236
237 if (chi->prev)
238 chi->prev->next = chi->next;
239
240 chi->prev = NULL;
241 chi->next = ci->infoActiveChildren;
242 chi->next->prev = chi;
243 ci->infoActiveChildren = chi;
244
245 SendMessage(parent, WM_CHILDACTIVATE, 0, 0);
246 }
247
248#ifdef DEBUG_MDI
249 fprintf(stderr, "MDIBringToTop: pos %04.4x, hwnd %04.4x\n",
250 id, chi->hwnd);
251#endif
252 }
253}
254
255/**********************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +0000256 * MDIMaximizeChild
257 */
258LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
259{
260 WND *w = WIN_FindWndPtr(child);
261 RECT rect;
262
263 MDIBringChildToTop(parent, child, FALSE, FALSE);
264 ci->rectRestore = w->rectWindow;
265
266 rect.top = (ci->rectMaximize.top -
267 (w->rectClient.top - w->rectWindow.top));
268 rect.bottom = (ci->rectMaximize.bottom +
269 (w->rectWindow.bottom - w->rectClient.bottom));
270 rect.left = (ci->rectMaximize.left -
271 (w->rectClient.left - w->rectWindow.left));
272 rect.right = (ci->rectMaximize.right +
273 (w->rectWindow.right - w->rectClient.right));
274 w->dwStyle |= WS_MAXIMIZE;
275 SetWindowPos(child, 0, rect.left, rect.top,
276 rect.right - rect.left + 1, rect.bottom - rect.top + 1,
277 SWP_NOACTIVATE | SWP_NOZORDER);
278
279 ci->flagChildMaximized = TRUE;
280
281 SendMessage(child, WM_SIZE, SIZE_MAXIMIZED,
282 MAKELONG(w->rectClient.right-w->rectClient.left,
283 w->rectClient.bottom-w->rectClient.top));
284 SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
285
286 return 0;
287}
288
289/**********************************************************************
290 * MDIRestoreChild
291 */
292LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
293{
294 HWND child;
295 WND *w = WIN_FindWndPtr(child);
296 LPRECT lprect = &ci->rectRestore;
297
298 child = ci->hwndActiveChild;
299
300 w->dwStyle &= ~WS_MAXIMIZE;
301 SetWindowPos(child, 0, lprect->left, lprect->top,
302 lprect->right - lprect->left + 1,
303 lprect->bottom - lprect->top + 1,
304 SWP_NOACTIVATE | SWP_NOZORDER);
305
306 ci->flagChildMaximized = FALSE;
307
308 SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
309 MDIBringChildToTop(parent, child, FALSE, FALSE);
310
311 return 0;
312}
313
314/**********************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000315 * MDIChildActivated
316 */
317LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent)
318{
319 MDICHILDINFO *chi;
320 HWND deact_hwnd;
321 HWND act_hwnd;
322 LONG lParam;
323
324#ifdef DEBUG_MDI
325 fprintf(stderr, "MDIChildActivate: top %04.4x\n", w->hwndChild);
326#endif
327
328 chi = ci->infoActiveChildren;
329 if (chi)
330 {
331 deact_hwnd = ci->hwndActiveChild;
332 act_hwnd = chi->hwnd;
333 lParam = ((LONG) deact_hwnd << 16) | act_hwnd;
334
335#ifdef DEBUG_MDI
336 fprintf(stderr, "MDIChildActivate: deact %04.4x, act %04.4x\n",
337 deact_hwnd, act_hwnd);
338#endif
339
340 ci->hwndActiveChild = act_hwnd;
341
342 if (deact_hwnd != act_hwnd)
343 {
344 MDIRecreateMenuList(ci);
345 SendMessage(deact_hwnd, WM_NCACTIVATE, FALSE, 0);
346 SendMessage(deact_hwnd, WM_MDIACTIVATE, FALSE, lParam);
347 }
348
349 SendMessage(act_hwnd, WM_NCACTIVATE, TRUE, 0);
350 SendMessage(act_hwnd, WM_MDIACTIVATE, TRUE, lParam);
351 }
352
353 if (chi || ci->nActiveChildren == 0)
354 {
355 MDIRecreateMenuList(ci);
Alexandre Julliard58199531994-04-21 01:20:00 +0000356 SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000357 }
358
359 return 0;
360}
361
362/**********************************************************************
363 * MDICascade
364 */
365LONG MDICascade(HWND parent, MDICLIENTINFO *ci)
366{
367 MDICHILDINFO *chi;
368 RECT rect;
369 int spacing, xsize, ysize;
370 int x, y;
371
Alexandre Julliard58199531994-04-21 01:20:00 +0000372 if (ci->flagChildMaximized)
373 MDIRestoreChild(parent, ci);
374
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000375 GetClientRect(parent, &rect);
376 spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
Alexandre Julliard58199531994-04-21 01:20:00 +0000377 ysize = rect.bottom - 8 * spacing;
378 xsize = rect.right - 8 * spacing;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000379
380#ifdef DEBUG_MDI
381 fprintf(stderr,
382 "MDICascade: Client wnd at (%d,%d) - (%d,%d), spacing %d\n",
383 rect.left, rect.top, rect.right, rect.bottom, spacing);
384 fprintf(stderr, "MDICascade: searching for last child\n");
385#endif
386 for (chi = ci->infoActiveChildren; chi->next != NULL; chi = chi->next)
387 ;
388
389#ifdef DEBUG_MDI
390 fprintf(stderr, "MDICascade: last child is %04.4x\n", chi->hwnd);
391#endif
392 x = 0;
393 y = 0;
394 for ( ; chi != NULL; chi = chi->prev)
395 {
396#ifdef DEBUG_MDI
397 fprintf(stderr, "MDICascade: move %04.4x to (%d,%d) size [%d,%d]\n",
398 chi->hwnd, x, y, xsize, ysize);
399#endif
400 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
401 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
402
403 x += spacing;
404 y += spacing;
405 }
406
407 return 0;
408}
409
410/**********************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +0000411 * MDITile
412 */
413LONG MDITile(HWND parent, MDICLIENTINFO *ci)
414{
415 MDICHILDINFO *chi;
416 RECT rect;
417 int xsize, ysize;
418 int x, y;
419 int rows, columns;
420 int r, c;
421 int i;
422
423 if (ci->flagChildMaximized)
424 MDIRestoreChild(parent, ci);
425
426 GetClientRect(parent, &rect);
427 rows = (int) sqrt((double) ci->nActiveChildren);
428 columns = ci->nActiveChildren / rows;
429 ysize = rect.bottom / rows;
430 xsize = rect.right / columns;
431
432 chi = ci->infoActiveChildren;
433 x = 0;
434 i = 0;
435 for (c = 1; c <= columns; c++)
436 {
437 if (c == columns)
438 {
439 rows = ci->nActiveChildren - i;
440 ysize = rect.bottom / rows;
441 }
442
443 y = 0;
444 for (r = 1; r <= rows; r++, i++, chi = chi->next)
445 {
446 SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize,
447 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
448
449 y += ysize;
450 }
451
452 x += xsize;
453 }
454
455
456 return 0;
457}
458
459/**********************************************************************
460 * MDIHandleLButton
461 */
462BOOL MDIHandleLButton(HWND hwndFrame, HWND hwndClient,
463 WORD wParam, LONG lParam)
464{
465 MDICLIENTINFO *ci;
466 WND *w;
467 RECT rect;
468 WORD x;
469
470 w = WIN_FindWndPtr(hwndClient);
471 ci = (MDICLIENTINFO *) w->wExtra;
472
473 if (wParam == HTMENU && ci->flagChildMaximized)
474 {
475 x = LOWORD(lParam);
476
477 NC_GetInsideRect(hwndFrame, &rect);
478 if (x < rect.left + SYSMETRICS_CXSIZE)
479 {
480 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
481 SC_CLOSE, lParam);
482 return TRUE;
483 }
484 else if (x >= rect.right - SYSMETRICS_CXSIZE)
485 {
486 SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND,
487 SC_RESTORE, lParam);
488 return TRUE;
489 }
490 }
491
492 return FALSE;
493}
494
495/**********************************************************************
496 * MDIPaintMaximized
497 */
498LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
499 WORD wParam, LONG lParam)
500{
501 static HBITMAP hbitmapClose = 0;
502 static HBITMAP hbitmapMaximized = 0;
503
504 MDICLIENTINFO *ci;
505 WND *w;
506 LONG rv;
507 HDC hdc, hdcMem;
508 RECT rect;
509 WND *wndPtr = WIN_FindWndPtr(hwndFrame);
510
511 w = WIN_FindWndPtr(hwndClient);
512 ci = (MDICLIENTINFO *) w->wExtra;
513
514#ifdef DEBUG_MDI
515 fprintf(stderr,
516 "MDIPaintMaximized: frame %04x, client %04x"
517 ", max flag %d, menu %04x\n",
518 hwndFrame, hwndClient,
519 ci->flagChildMaximized, wndPtr ? wndPtr->wIDmenu : 0);
520#endif
521
522 if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0)
523 {
524 rv = NC_DoNCPaint( hwndFrame, (HRGN) 1, wParam, TRUE);
525
526 hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW);
527 if (!hdc)
528 return rv;
529
530 hdcMem = CreateCompatibleDC(hdc);
531
532 if (hbitmapClose == 0)
533 {
534 hbitmapClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE));
535 hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
536 }
537
538#ifdef DEBUG_MDI
539 fprintf(stderr,
540 "MDIPaintMaximized: hdcMem %04x, close bitmap %04x, "
541 "maximized bitmap %04x\n",
542 hdcMem, hbitmapClose, hbitmapMaximized);
543#endif
544
545 NC_GetInsideRect(hwndFrame, &rect);
546 rect.top += ((wndPtr->dwStyle & WS_CAPTION) ?
547 SYSMETRICS_CYSIZE + 1 : 0);
548 SelectObject(hdcMem, hbitmapClose);
549 BitBlt(hdc, rect.left, rect.top + 1,
550 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
551 hdcMem, 1, 1, SRCCOPY);
552
553 NC_GetInsideRect(hwndFrame, &rect);
554 rect.top += ((wndPtr->dwStyle & WS_CAPTION) ?
555 SYSMETRICS_CYSIZE + 1 : 0);
556 rect.left = rect.right - SYSMETRICS_CXSIZE;
557 SelectObject(hdcMem, hbitmapMaximized);
558 BitBlt(hdc, rect.left, rect.top + 1,
559 SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
560 hdcMem, 1, 1, SRCCOPY);
561
562 NC_GetInsideRect(hwndFrame, &rect);
563 rect.top += ((wndPtr->dwStyle & WS_CAPTION) ?
564 SYSMETRICS_CYSIZE + 1 : 0);
565 rect.left += SYSMETRICS_CXSIZE;
566 rect.right -= SYSMETRICS_CXSIZE;
567 rect.bottom = rect.top + SYSMETRICS_CYMENU;
568
569 StdDrawMenuBar(hdc, &rect, (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu),
570 FALSE);
571 GlobalUnlock(wndPtr->wIDmenu);
572
573 DeleteDC(hdcMem);
574 ReleaseDC(hwndFrame, hdc);
575 }
576 else
577 DefWindowProc(hwndFrame, message, wParam, lParam);
578
579 return rv;
580}
581
582/**********************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000583 * MDIClientWndProc
584 *
585 * This function is the handler for all MDI requests.
586 */
587LONG
588MDIClientWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
589{
590 LPCREATESTRUCT cs;
591 LPCLIENTCREATESTRUCT ccs;
592 MDICLIENTINFO *ci;
593 WND *w;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000594
595 w = WIN_FindWndPtr(hwnd);
596 ci = (MDICLIENTINFO *) w->wExtra;
597
598 switch (message)
599 {
600 case WM_CHILDACTIVATE:
601 return MDIChildActivated(w, ci, hwnd);
602
603 case WM_CREATE:
604 cs = (LPCREATESTRUCT) lParam;
605 ccs = (LPCLIENTCREATESTRUCT) cs->lpCreateParams;
606 ci->hWindowMenu = ccs->hWindowMenu;
607 ci->idFirstChild = ccs->idFirstChild;
608 ci->infoActiveChildren = NULL;
609 ci->flagMenuAltered = FALSE;
610 ci->flagChildMaximized = FALSE;
611 w->dwStyle |= WS_CLIPCHILDREN;
612
Alexandre Julliard58199531994-04-21 01:20:00 +0000613 GetClientRect(w->hwndParent, &ci->rectMaximize);
614 MoveWindow(hwnd, 0, 0,
615 ci->rectMaximize.right, ci->rectMaximize.bottom, 1);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000616
617 return 0;
618
619 case WM_MDIACTIVATE:
Alexandre Julliard58199531994-04-21 01:20:00 +0000620 MDIBringChildToTop(hwnd, wParam, FALSE, FALSE);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000621 return 0;
622
623 case WM_MDICASCADE:
624 return MDICascade(hwnd, ci);
625
626 case WM_MDICREATE:
Alexandre Julliard58199531994-04-21 01:20:00 +0000627 return MDICreateChild(w, ci, hwnd, (LPMDICREATESTRUCT) lParam);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000628
629 case WM_MDIDESTROY:
Alexandre Julliard58199531994-04-21 01:20:00 +0000630 return MDIDestroyChild(w, ci, hwnd, wParam, TRUE);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000631
632 case WM_MDIGETACTIVE:
633 return ((LONG) ci->hwndActiveChild |
634 ((LONG) ci->flagChildMaximized << 16));
635
636 case WM_MDIICONARRANGE:
637 /* return MDIIconArrange(...) */
638 break;
639
640 case WM_MDIMAXIMIZE:
Alexandre Julliard58199531994-04-21 01:20:00 +0000641 return MDIMaximizeChild(hwnd, wParam, ci);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000642
Alexandre Julliard58199531994-04-21 01:20:00 +0000643 case WM_MDINEXT:
644 MDIBringChildToTop(hwnd, wParam, FALSE, TRUE);
645 break;
646
647 case WM_MDIRESTORE:
648 return MDIRestoreChild(hwnd, ci);
649
650 case WM_MDISETMENU:
651 /* return MDISetMenu(...) */
652 break;
653
654 case WM_MDITILE:
655 return MDITile(hwnd, ci);
656
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000657 case WM_NCACTIVATE:
658 SendMessage(ci->hwndActiveChild, message, wParam, lParam);
659 break;
660
661 case WM_PARENTNOTIFY:
662 if (wParam == WM_DESTROY)
Alexandre Julliard58199531994-04-21 01:20:00 +0000663 return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000664 else if (wParam == WM_LBUTTONDOWN)
Alexandre Julliard58199531994-04-21 01:20:00 +0000665 MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE);
666 break;
667
668 case WM_SIZE:
669 GetClientRect(w->hwndParent, &ci->rectMaximize);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000670 break;
671
672 }
673
674 return DefWindowProc(hwnd, message, wParam, lParam);
675}
676
677/**********************************************************************
678 * DefFrameProc (USER.445)
679 *
680 */
681LONG
682DefFrameProc(HWND hwnd, HWND hwndMDIClient, WORD message,
683 WORD wParam, LONG lParam)
684{
685 switch (message)
686 {
687 case WM_COMMAND:
Alexandre Julliard58199531994-04-21 01:20:00 +0000688 MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE);
689 break;
690
691 case WM_NCLBUTTONDOWN:
692 if (MDIHandleLButton(hwnd, hwndMDIClient, wParam, lParam))
693 return 0;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000694 break;
695
696 case WM_NCACTIVATE:
697 SendMessage(hwndMDIClient, message, wParam, lParam);
Alexandre Julliard58199531994-04-21 01:20:00 +0000698 return MDIPaintMaximized(hwnd, hwndMDIClient, message, wParam, lParam);
699
700 case WM_NCPAINT:
701 return MDIPaintMaximized(hwnd, hwndMDIClient, message, wParam, lParam);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000702
703 case WM_SETFOCUS:
704 SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam);
705 break;
706
707 case WM_SIZE:
708 MoveWindow(hwndMDIClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
709 break;
710
711 }
712
713 return DefWindowProc(hwnd, message, wParam, lParam);
714}
715
716/**********************************************************************
717 * DefMDIChildProc (USER.447)
718 *
719 */
720LONG
721DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
722{
723 MDICLIENTINFO *ci;
724 WND *w;
725
726 w = WIN_FindWndPtr(GetParent(hwnd));
727 ci = (MDICLIENTINFO *) w->wExtra;
728
729 switch (message)
730 {
731 case WM_NCHITTEST:
732 ci->hwndHitTest = hwnd;
733 break;
734
735 case WM_NCPAINT:
736 return NC_DoNCPaint(hwnd, (HRGN)1,
737 hwnd == ci->hwndActiveChild);
Alexandre Julliard58199531994-04-21 01:20:00 +0000738
739 case WM_SYSCOMMAND:
740 switch (wParam)
741 {
742 case SC_MAXIMIZE:
743 return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, hwnd, 0);
744
745 case SC_RESTORE:
746 return SendMessage(GetParent(hwnd), WM_MDIRESTORE, hwnd, 0);
747 }
748 break;
749
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000750 }
751
752 return DefWindowProc(hwnd, message, wParam, lParam);
753}
754
755/**********************************************************************
756 * TranslateMDISysAccel (USER.451)
757 *
758 */
759BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
760{
761 return 0;
762}