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

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

Moved new user32 here

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