source: trunk/src/user32/win32wmdiclient.cpp@ 1357

Last change on this file since 1357 was 1357, checked in by sandervl, 26 years ago

MDI fix + desktop as parent for main windows

File size: 24.6 KB
Line 
1/* $Id: win32wmdiclient.cpp,v 1.7 1999-10-19 12:52:30 sandervl Exp $ */
2/*
3 * Win32 MDI Client Window Class for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 * Parts based on Wine (windows\mdi.c) (990815)
9 *
10 * Copyright 1994, Bob Amstadt
11 * 1995,1996 Alex Korobka
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16#include <os2win.h>
17#include <win.h>
18#include <stdlib.h>
19#include <string.h>
20#include <stdarg.h>
21#include <assert.h>
22#include <misc.h>
23#include <heapstring.h>
24#include <win32wnd.h>
25#include <win32wmdiclient.h>
26#include <spy.h>
27#include "wndmsg.h"
28#include "hooks.h"
29#include <oslibwin.h>
30#include <oslibutil.h>
31#include <oslibgdi.h>
32#include <oslibres.h>
33#include "oslibdos.h"
34#include <winres.h>
35#include "syscolor.h"
36#include "win32wndhandle.h"
37#include "heapshared.h"
38
39
40//******************************************************************************
41//******************************************************************************
42Win32MDIClientWindow::Win32MDIClientWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
43 : maximizedChild(0), activeChild(0), nActiveChildren(0), nTotalCreated(0),
44 frameTitle(NULL), mdiFlags(0), idFirstChild(0), hWindowMenu(0),
45 sbRecalc(0),
46 Win32BaseWindow(lpCreateStructA, classAtom, isUnicode)
47{
48}
49//******************************************************************************
50//******************************************************************************
51Win32MDIClientWindow::~Win32MDIClientWindow()
52{
53 if(frameTitle)
54 HeapFree(GetProcessHeap(), 0, frameTitle);
55}
56//******************************************************************************
57//******************************************************************************
58BOOL Win32MDIClientWindow::isMDIClient()
59{
60 return TRUE;
61}
62//******************************************************************************
63//******************************************************************************
64LRESULT Win32MDIClientWindow::MDIClientWndProc(UINT message, WPARAM wParam, LPARAM lParam)
65{
66 LPCREATESTRUCTA cs;
67 LPCLIENTCREATESTRUCT ccs;
68 RECT rect;
69 INT nItems;
70 LRESULT retvalue;
71 Win32Window *frameWnd;
72 Win32MDIChildWindow *mdichild;
73
74 frameWnd = (Win32Window *)getParent();
75 if(frameWnd == NULL) {
76 return 0;
77 }
78
79 switch (message)
80 {
81 case WM_CREATE:
82 cs = (LPCREATESTRUCTA)lParam;
83 ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
84
85 hWindowMenu = ccs->hWindowMenu;
86 idFirstChild = ccs->idFirstChild;
87
88 maximizedChild = 0;
89 activeChild = 0;
90 nActiveChildren = 0;
91 nTotalCreated = 0;
92 frameTitle = NULL;
93 mdiFlags = 0;
94
95 setStyle(getStyle() | WS_CLIPCHILDREN);
96
97 updateFrameText(MDI_NOFRAMEREPAINT, getParent()->getWindowNameA());
98
99 AppendMenuA( hWindowMenu, MF_SEPARATOR, 0, NULL );
100
101 setClientRect(frameWnd->getClientRect());
102
103 dprintf(("MDIClient created - hwnd = %04x, idFirst = %u\n", getWindowHandle(), idFirstChild ));
104
105 retvalue = 0;
106 goto END;
107
108 case WM_DESTROY:
109// if( maximizedChild ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
110
111 if((nItems = GetMenuItemCount(hWindowMenu)) > 0)
112 {
113 idFirstChild = nItems - 1;
114 nActiveChildren++; /* to delete a separator */
115 while( nActiveChildren-- )
116 DeleteMenu(hWindowMenu,MF_BYPOSITION,idFirstChild--);
117 }
118 retvalue = 0;
119 goto END;
120
121 case WM_MDIACTIVATE:
122 if( activeChild && activeChild->getWindowHandle() != (HWND)wParam )
123 {
124 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
125 if(mdichild) {
126 mdichild->SetWindowPos(0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
127 }
128 }
129 retvalue = 0;
130 goto END;
131
132#if 0
133 case WM_MDICASCADE:
134 retvalue = MDICascade(w, ci);
135 goto END;
136#endif
137
138 case WM_MDICREATE:
139 if (lParam) {
140 retvalue = Win32MDIChildWindow::createChild( this, (MDICREATESTRUCTA*)lParam );
141 }
142 else retvalue = 0;
143 goto END;
144
145 case WM_MDIDESTROY:
146 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
147 if(mdichild) {
148 retvalue = destroyChild(mdichild, TRUE );
149 }
150 goto END;
151
152 case WM_MDIGETACTIVE:
153 if (lParam)
154 *(BOOL *)lParam = (maximizedChild != 0);
155
156 retvalue = (activeChild) ? activeChild->getWindowHandle() : 0;
157 goto END;
158
159#if 0
160 case WM_MDIICONARRANGE:
161 mdiFlags |= MDIF_NEEDUPDATE;
162 ArrangeIconicWindows(hwnd);
163 sbRecalc = SB_BOTH+1;
164 SendMessageA(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
165 retvalue = 0;
166 goto END;
167#endif
168
169 case WM_MDIMAXIMIZE:
170 ::ShowWindow( (HWND)wParam, SW_MAXIMIZE );
171 retvalue = 0;
172 goto END;
173
174 case WM_MDINEXT: /* lParam != 0 means previous window */
175 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
176 if(mdichild) {
177 switchActiveChild(mdichild, (lParam)? FALSE : TRUE );
178 }
179 break;
180
181
182 case WM_MDIRESTORE:
183 ::SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
184 retvalue = 0;
185 goto END;
186#if 0
187 case WM_MDISETMENU:
188 retvalue = MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
189 goto END;
190
191 case WM_MDIREFRESHMENU:
192 retvalue = MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
193 goto END;
194
195 case WM_MDITILE:
196 mdiFlags |= MDIF_NEEDUPDATE;
197 ShowScrollBar(hwnd,SB_BOTH,FALSE);
198 MDITile(w, ci, wParam);
199 mdiFlags &= ~MDIF_NEEDUPDATE;
200 retvalue = 0;
201 goto END;
202
203 case WM_VSCROLL:
204 case WM_HSCROLL:
205 mdiFlags |= MDIF_NEEDUPDATE;
206 ScrollChildren(hwnd, message, wParam, lParam);
207 mdiFlags &= ~MDIF_NEEDUPDATE;
208 retvalue = 0;
209 goto END;
210#endif
211
212 case WM_SETFOCUS:
213 if( activeChild )
214 {
215 if( !(activeChild->getStyle() & WS_MINIMIZE) )
216 ::SetFocus(activeChild->getWindowHandle());
217 }
218 retvalue = 0;
219 goto END;
220
221 case WM_NCACTIVATE:
222 if( activeChild )
223 activeChild->SendMessageA(message, wParam, lParam);
224 break;
225
226 case WM_PARENTNOTIFY:
227 if (LOWORD(wParam) == WM_LBUTTONDOWN)
228 {
229 POINTS pt = MAKEPOINTS(lParam);
230 POINT point;
231
232 point.x = pt.x;
233 point.y = pt.y;
234
235 HWND child = ChildWindowFromPoint(getWindowHandle(), point);
236
237 if( child && child != getWindowHandle() && (!activeChild || activeChild->getWindowHandle() != child) )
238 ::SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
239 }
240 retvalue = 0;
241 goto END;
242
243 case WM_SIZE:
244 if( maximizedChild && maximizedChild->IsWindow() )
245 {
246 RECT rect;
247
248 rect.left = 0;
249 rect.top = 0;
250 rect.right = LOWORD(lParam);
251 rect.bottom = HIWORD(lParam);
252
253 AdjustWindowRectEx(&rect, maximizedChild->getStyle(), 0, maximizedChild->getExStyle());
254 ::MoveWindow(maximizedChild->getWindowHandle(), rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 1);
255 }
256 else postUpdate(SB_BOTH+1);
257 break;
258
259#if 0
260 case WM_MDICALCCHILDSCROLL:
261 if( (mdiFlags & MDIF_NEEDUPDATE) && sbRecalc )
262 {
263 CalcChildScroll(hwnd, sbRecalc-1);
264 sbRecalc = 0;
265 mdiFlags &= ~MDIF_NEEDUPDATE;
266 }
267 retvalue = 0;
268 goto END;
269#endif
270 }
271 retvalue = DefWindowProcA(message, wParam, lParam );
272END:
273 return retvalue;
274}
275/**********************************************************************
276 * MDIClientWndProc
277 *
278 * This function handles all MDI requests.
279 */
280LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, WPARAM wParam,
281 LPARAM lParam )
282{
283 Win32MDIClientWindow *window;
284
285 window = (Win32MDIClientWindow *)Win32BaseWindow::GetWindowFromHandle(hwnd);
286 if(!window) {
287 dprintf(("MDIClientWndProc, window %x not found", hwnd));
288 return 0;
289 }
290 return window->MDIClientWndProc(message, wParam, lParam);
291}
292/**********************************************************************
293 * MDI_GetWindow
294 *
295 * returns "activateable" child different from the current or zero
296 */
297Win32MDIChildWindow *Win32MDIClientWindow::getWindow(Win32MDIChildWindow *actchild, BOOL bNext,
298 DWORD dwStyleMask)
299{
300 Win32MDIChildWindow *lastchild = 0, *curchild;
301
302 dwStyleMask |= WS_DISABLED | WS_VISIBLE;
303
304 if( !actchild ) actchild = getActiveChild();
305 if( !actchild) return 0;
306
307 for ( curchild = (Win32MDIChildWindow *)actchild->getNextChild(); ; curchild = (Win32MDIChildWindow *)curchild->getNextChild())
308 {
309 if (!curchild ) curchild = (Win32MDIChildWindow *)getFirstChild();
310
311 if ( curchild == actchild ) break; /* went full circle */
312
313 if (!curchild->getOwner() && (curchild->getStyle() & dwStyleMask) == WS_VISIBLE )
314 {
315 lastchild = curchild;
316 if ( bNext ) break;
317 }
318 }
319 return lastchild;
320}
321/**********************************************************************
322 * MDI_ChildActivate
323 *
324 * Note: hWndChild is NULL when last child is being destroyed
325 */
326LONG Win32MDIClientWindow::childActivate(Win32MDIChildWindow *child)
327{
328 BOOL isActiveFrameWnd = 0;
329 LONG retvalue;
330 Win32MDIChildWindow *prevActive = activeChild;
331
332 if( child && child->getStyle() & WS_DISABLED )
333 {
334 return 0;
335 }
336
337 if( GetActiveWindow() == getParent()->getWindowHandle())
338 isActiveFrameWnd = TRUE;
339
340 /* deactivate prev. active child */
341 if( prevActive )
342 {
343 prevActive->setStyle(prevActive->getStyle() | WS_SYSMENU);
344 prevActive->SendMessageA( WM_NCACTIVATE, FALSE, 0L );
345 prevActive->SendMessageA( WM_MDIACTIVATE, (WPARAM)prevActive->getWindowHandle(), (LPARAM)(child) ? child->getWindowHandle() : 0);
346
347 /* uncheck menu item */
348 if( getMDIMenu() )
349 CheckMenuItem(getMDIMenu(), prevActive->getWindowId(), 0);
350 }
351
352 /* set appearance */
353 if( maximizedChild)
354 {
355 if( maximizedChild != child) {
356 if( child ) {
357 activeChild = child;
358 child->ShowWindow(SW_SHOWMAXIMIZED);
359 }
360 else
361 if(activeChild) activeChild->ShowWindow( SW_SHOWNORMAL );
362 }
363 }
364
365 activeChild = child;
366
367 /* check if we have any children left */
368 if( !activeChild )
369 {
370 if( isActiveFrameWnd )
371 SetFocus(getWindowHandle());
372
373 return 0;
374 }
375
376 /* check menu item */
377 if( getMDIMenu() )
378 CheckMenuItem(getMDIMenu(), child->getWindowId(), MF_CHECKED);
379
380 /* bring active child to the top */
381 child->SetWindowPos( 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
382
383 if( isActiveFrameWnd )
384 {
385 child->SendMessageA( WM_NCACTIVATE, TRUE, 0L);
386 if( GetFocus() == getWindowHandle())
387 SendMessageA( WM_SETFOCUS, (WPARAM)getWindowHandle(), 0L );
388 else
389 SetFocus( getWindowHandle() );
390 }
391
392 /* @@@PH prevActive may be NULL actually ?! */
393 child->SendMessageA( WM_MDIACTIVATE,
394 prevActive ? (WPARAM)prevActive->getWindowHandle() : 0,
395 child->getWindowHandle());
396 return TRUE;
397}
398/**********************************************************************
399 * MDI_SwitchActiveChild
400 *
401 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
402 * being activated
403 */
404void Win32MDIClientWindow::switchActiveChild(Win32MDIChildWindow *nextActiveChild, BOOL bNextWindow )
405{
406 Win32MDIChildWindow *prevActiveChild = 0;
407
408 if ( !nextActiveChild) return; /* no window to switch to */
409
410 prevActiveChild = getActiveChild();
411
412 if ( prevActiveChild != nextActiveChild)
413 {
414 BOOL bOptimize = 0;
415
416 if( getMaximizedChild() )
417 {
418 bOptimize = 1;
419 nextActiveChild->setStyle(nextActiveChild->getStyle()& ~WS_VISIBLE);
420 }
421
422 nextActiveChild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
423
424 if( bNextWindow && prevActiveChild )
425 prevActiveChild->SetWindowPos(HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
426
427 if( bOptimize )
428 ShowWindow(SW_SHOW );
429 }
430}
431
432
433/**********************************************************************
434 * MDIDestroyChild
435 */
436LRESULT Win32MDIClientWindow::destroyChild(Win32MDIChildWindow *child, BOOL flagDestroy )
437{
438 if( child == getActiveChild())
439 {
440 switchActiveChild(child, TRUE);
441
442 if( child == getActiveChild() )
443 {
444 ShowWindow(SW_HIDE);
445 if( child == getMaximizedChild() )
446 {
447// MDI_RestoreFrameMenu(w_parent->parent, child);
448 setMaximizedChild(NULL);
449 updateFrameText(TRUE,NULL);
450 }
451 childActivate(0);
452 }
453 }
454 child->menuDeleteItem();
455
456 decNrActiveChildren();
457
458 dprintf(("child destroyed - %04x\n", child->getWindowHandle()));
459
460 if (flagDestroy)
461 {
462// MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
463 ::DestroyWindow(child->getWindowHandle());
464 }
465
466 return 0;
467}
468/**********************************************************************
469 * MDI_UpdateFrameText
470 *
471 * used when child window is maximized/restored
472 *
473 * Note: lpTitle can be NULL
474 */
475void Win32MDIClientWindow::updateFrameText(BOOL repaint, LPCSTR lpTitle )
476{
477 char lpBuffer[MDI_MAXTITLELENGTH+1];
478
479 /* store new "default" title if lpTitle is not NULL */
480 if (lpTitle)
481 {
482 if (frameTitle) HeapFree( GetProcessHeap(), 0, frameTitle );
483 frameTitle = HEAP_strdupA( GetProcessHeap(), 0, lpTitle );
484 }
485
486 if (frameTitle)
487 {
488 Win32MDIChildWindow *childWnd = getMaximizedChild();
489
490 if( childWnd && childWnd->getWindowNameA() )
491 {
492 /* combine frame title and child title if possible */
493
494 LPCSTR lpBracket = " - [";
495 int i_frame_text_length = strlen(frameTitle);
496 int i_child_text_length = strlen(childWnd->getWindowNameA());
497
498 lstrcpynA( lpBuffer, frameTitle, MDI_MAXTITLELENGTH);
499
500 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
501 {
502 strcat( lpBuffer, lpBracket );
503
504 if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
505 {
506 strcat( lpBuffer, childWnd->getWindowNameA());
507 strcat( lpBuffer, "]" );
508 }
509 else
510 {
511 lstrcpynA(lpBuffer + i_frame_text_length + 4,
512 childWnd->getWindowNameA(), MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
513 strcat( lpBuffer, "]" );
514 }
515 }
516 }
517 else
518 {
519 strncpy(lpBuffer, frameTitle, MDI_MAXTITLELENGTH );
520 lpBuffer[MDI_MAXTITLELENGTH]='\0';
521 }
522 }
523 else
524 lpBuffer[0] = '\0';
525
526 getParent()->SetWindowTextA(lpBuffer);
527 if( repaint == MDI_REPAINTFRAME)
528 getParent()->SetWindowPos(0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
529}
530#if 0
531/**********************************************************************
532 * MDICascade
533 */
534LONG Win32MDIClientWindow::cascade()
535{
536 WND** ppWnd;
537 UINT total;
538
539 if (getMaximizedChild())
540 SendMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
541
542 if (nActiveChildren == 0) return 0;
543
544 if ((ppWnd = WIN_BuildWinArray(clientWnd, BWA_SKIPHIDDEN | BWA_SKIPOWNED |
545 BWA_SKIPICONIC, &total)))
546 {
547 WND** heapPtr = ppWnd;
548 if( total )
549 {
550 INT delta = 0, n = 0;
551 POINT pos[2];
552 if( total < ci->nActiveChildren )
553 delta = GetSystemMetrics(SM_CYICONSPACING) +
554 GetSystemMetrics(SM_CYICON);
555
556 /* walk the list (backwards) and move windows */
557 while (*ppWnd) ppWnd++;
558 while (ppWnd != heapPtr)
559 {
560 ppWnd--;
561
562 MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
563 SetWindowPos( (*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y,
564 pos[1].x, pos[1].y,
565 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
566 }
567 }
568 WIN_ReleaseWinArray(heapPtr);
569 }
570
571 if( total < ci->nActiveChildren )
572 ArrangeIconicWindows( clientWnd->hwndSelf );
573
574 return 0;
575}
576
577/**********************************************************************
578 * MDITile
579 */
580void Win32MDIClientWindow::MDITile(WPARAM wParam )
581{
582 WND** ppWnd;
583 UINT total = 0;
584
585 if (getMaximizedChild())
586 SendMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
587
588 if (nActiveChildren == 0) return;
589
590 ppWnd = WIN_BuildWinArray(wndClient, BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
591 ((wParam & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
592
593 TRACE("%u windows to tile\n", total);
594
595 if( ppWnd )
596 {
597 WND** heapPtr = ppWnd;
598
599 if( total )
600 {
601 RECT rect;
602 int x, y, xsize, ysize;
603 int rows, columns, r, c, i;
604
605 GetClientRect(wndClient->hwndSelf,&rect);
606 rows = (int) sqrt((double)total);
607 columns = total / rows;
608
609 if( wParam & MDITILE_HORIZONTAL ) /* version >= 3.1 */
610 {
611 i = rows;
612 rows = columns; /* exchange r and c */
613 columns = i;
614 }
615
616 if( total != ci->nActiveChildren)
617 {
618 y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
619 rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
620 }
621
622 ysize = rect.bottom / rows;
623 xsize = rect.right / columns;
624
625 for (x = i = 0, c = 1; c <= columns && *ppWnd; c++)
626 {
627 if (c == columns)
628 {
629 rows = total - i;
630 ysize = rect.bottom / rows;
631 }
632
633 y = 0;
634 for (r = 1; r <= rows && *ppWnd; r++, i++)
635 {
636 SetWindowPos((*ppWnd)->hwndSelf, 0, x, y, xsize, ysize,
637 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
638 y += ysize;
639 ppWnd++;
640 }
641 x += xsize;
642 }
643 }
644 WIN_ReleaseWinArray(heapPtr);
645 }
646
647 if( total < ci->nActiveChildren ) ArrangeIconicWindows( wndClient->hwndSelf );
648}
649
650/* ----------------------- Frame window ---------------------------- */
651
652/**********************************************************************
653 * MDI_AugmentFrameMenu
654 */
655BOOL Win32MDIClientWindow::augmentFrameMenu(HWND hChild )
656{
657 WND* child = WIN_FindWndPtr(hChild);
658 HMENU hSysPopup = 0;
659 HBITMAP hSysMenuBitmap = 0;
660
661 if( !frame->wIDmenu || !child->hSysMenu )
662 {
663 WIN_ReleaseWndPtr(child);
664 return 0;
665 }
666 WIN_ReleaseWndPtr(child);
667
668 /* create a copy of sysmenu popup and insert it into frame menu bar */
669
670 if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
671 return 0;
672
673 TRACE("\tgot popup %04x in sysmenu %04x\n",
674 hSysPopup, child->hSysMenu);
675
676 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
677 SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
678 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
679 SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
680
681 /* In Win 95 look, the system menu is replaced by the child icon */
682
683 if(TWEAK_WineLook > WIN31_LOOK)
684 {
685 HICON hIcon = GetClassLongA(hChild, GCL_HICONSM);
686 if (!hIcon)
687 hIcon = GetClassLongA(hChild, GCL_HICON);
688 if (hIcon)
689 {
690 HDC hMemDC;
691 HBITMAP hBitmap, hOldBitmap;
692 HBRUSH hBrush;
693 HDC hdc = GetDC(hChild);
694
695 if (hdc)
696 {
697 int cx, cy;
698 cx = GetSystemMetrics(SM_CXSMICON);
699 cy = GetSystemMetrics(SM_CYSMICON);
700 hMemDC = CreateCompatibleDC(hdc);
701 hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
702 hOldBitmap = SelectObject(hMemDC, hBitmap);
703 SetMapMode(hMemDC, MM_TEXT);
704 hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
705 DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
706 SelectObject (hMemDC, hOldBitmap);
707 DeleteObject(hBrush);
708 DeleteDC(hMemDC);
709 ReleaseDC(hChild, hdc);
710 hSysMenuBitmap = hBitmap;
711 }
712 }
713 }
714 else
715 hSysMenuBitmap = hBmpClose;
716
717 if( !InsertMenuA(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
718 hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
719 {
720 TRACE("not inserted\n");
721 DestroyMenu(hSysPopup);
722 return 0;
723 }
724
725 /* The close button is only present in Win 95 look */
726 if(TWEAK_WineLook > WIN31_LOOK)
727 {
728 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
729 SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
730 }
731
732 EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
733 EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
734 EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
735 SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
736
737 /* redraw menu */
738 DrawMenuBar(frame->hwndSelf);
739
740 return 1;
741}
742
743/**********************************************************************
744 * MDI_RestoreFrameMenu
745 */
746static BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild )
747{
748 MENUITEMINFOA menuInfo;
749 INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1;
750 UINT iId = GetMenuItemID(frameWnd->wIDmenu,nItems) ;
751
752 TRACE("frameWnd %p,child %04x\n",frameWnd,hChild);
753
754 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
755 return 0;
756
757 /*
758 * Remove the system menu, If that menu is the icon of the window
759 * as it is in win95, we have to delete the bitmap.
760 */
761 menuInfo.cbSize = sizeof(MENUITEMINFOA);
762 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
763
764 GetMenuItemInfoA(frameWnd->wIDmenu,
765 0,
766 TRUE,
767 &menuInfo);
768
769 RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
770
771 if ( (menuInfo.fType & MFT_BITMAP) &&
772 (LOWORD(menuInfo.dwTypeData)!=0) &&
773 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
774 {
775 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
776 }
777
778 if(TWEAK_WineLook > WIN31_LOOK)
779 {
780 /* close */
781 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
782 }
783 /* restore */
784 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
785 /* minimize */
786 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
787
788 DrawMenuBar(frameWnd->hwndSelf);
789
790 return 1;
791}
792#endif
793/* -------- Miscellaneous service functions ----------
794 *
795 * MDI_GetChildByID
796 */
797Win32MDIChildWindow *Win32MDIClientWindow::getChildByID(INT id)
798{
799 Win32MDIChildWindow *child;
800
801 for (child = (Win32MDIChildWindow *)getFirstChild() ; child; child = (Win32MDIChildWindow *)child->getNextChild())
802 if (child->getWindowId() == id) return child;
803
804 return 0;
805}
806
807void Win32MDIClientWindow::postUpdate(WORD recalc)
808{
809 if( !(mdiFlags & MDIF_NEEDUPDATE) )
810 {
811 mdiFlags |= MDIF_NEEDUPDATE;
812 PostMessageA(WM_MDICALCCHILDSCROLL, 0, 0);
813 }
814 sbRecalc = recalc;
815}
816//******************************************************************************
817//******************************************************************************
818BOOL MDICLIENT_Register()
819{
820 WNDCLASSA wndClass;
821
822 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA)) return FALSE;
823
824 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
825 wndClass.style = CS_GLOBALCLASS;
826 wndClass.lpfnWndProc = (WNDPROC)MDIClientWndProc;
827 wndClass.cbClsExtra = 0;
828 wndClass.cbWndExtra = 0;
829 wndClass.hCursor = 0;
830 wndClass.hbrBackground = (HBRUSH)LTGRAY_BRUSH;
831 wndClass.lpszClassName = MDICLIENTCLASSNAMEA;
832
833 return RegisterClassA(&wndClass);
834}
835//******************************************************************************
836//******************************************************************************
837BOOL MDICLIENT_Unregister()
838{
839 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA))
840 return UnregisterClassA(MDICLIENTCLASSNAMEA,(HINSTANCE)NULL);
841 else return FALSE;
842}
843//******************************************************************************
844//******************************************************************************
Note: See TracBrowser for help on using the repository browser.