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

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

MDI changes

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