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

Last change on this file since 1223 was 1223, checked in by achimha, 26 years ago

mdi client fixes from Yurio Dario

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