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

Last change on this file since 1036 was 1019, checked in by phaller, 26 years ago

Fix: WIN32WMDIClient:childActivate, prevActivate == NULL fixed

File size: 24.4 KB
Line 
1/* $Id: win32wmdiclient.cpp,v 1.2 1999-09-23 14:39:53 phaller 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
391 /* @@@PH prevActive may be NULL actually ?! */
392 child->SendMessageA( WM_MDIACTIVATE,
393 prevActive ? (WPARAM)prevActive->getWindowHandle() : 0,
394 child->getWindowHandle());
395 return TRUE;
396}
397/**********************************************************************
398 * MDI_SwitchActiveChild
399 *
400 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
401 * being activated
402 */
403void Win32MDIClientWindow::switchActiveChild(Win32MDIChildWindow *nextActiveChild, BOOL bNextWindow )
404{
405 Win32MDIChildWindow *prevActiveChild = 0;
406
407 if ( !nextActiveChild) return; /* no window to switch to */
408
409 prevActiveChild = getActiveChild();
410
411 if ( prevActiveChild != nextActiveChild)
412 {
413 BOOL bOptimize = 0;
414
415 if( getMaximizedChild() )
416 {
417 bOptimize = 1;
418 nextActiveChild->setStyle(nextActiveChild->getStyle()& ~WS_VISIBLE);
419 }
420
421 nextActiveChild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
422
423 if( bNextWindow && prevActiveChild )
424 prevActiveChild->SetWindowPos(HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
425
426 if( bOptimize )
427 ShowWindow(SW_SHOW );
428 }
429}
430
431
432/**********************************************************************
433 * MDIDestroyChild
434 */
435LRESULT Win32MDIClientWindow::destroyChild(Win32MDIChildWindow *child, BOOL flagDestroy )
436{
437 if( child == getActiveChild())
438 {
439 switchActiveChild(child, TRUE);
440
441 if( child == getActiveChild() )
442 {
443 ShowWindow(SW_HIDE);
444 if( child == getMaximizedChild() )
445 {
446// MDI_RestoreFrameMenu(w_parent->parent, child);
447 setMaximizedChild(NULL);
448 updateFrameText(TRUE,NULL);
449 }
450 childActivate(0);
451 }
452 }
453 child->menuDeleteItem();
454
455 decNrActiveChildren();
456
457 dprintf(("child destroyed - %04x\n", child->getWindowHandle()));
458
459 if (flagDestroy)
460 {
461// MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
462 ::DestroyWindow(child->getWindowHandle());
463 }
464
465 return 0;
466}
467/**********************************************************************
468 * MDI_UpdateFrameText
469 *
470 * used when child window is maximized/restored
471 *
472 * Note: lpTitle can be NULL
473 */
474void Win32MDIClientWindow::updateFrameText(BOOL repaint, LPCSTR lpTitle )
475{
476 char lpBuffer[MDI_MAXTITLELENGTH+1];
477
478 /* store new "default" title if lpTitle is not NULL */
479 if (lpTitle)
480 {
481 if (frameTitle) HeapFree( GetProcessHeap(), 0, frameTitle );
482 frameTitle = HEAP_strdupA( GetProcessHeap(), 0, lpTitle );
483 }
484
485 if (frameTitle)
486 {
487 Win32MDIChildWindow *childWnd = getMaximizedChild();
488
489 if( childWnd && childWnd->getWindowNameA() )
490 {
491 /* combine frame title and child title if possible */
492
493 LPCSTR lpBracket = " - [";
494 int i_frame_text_length = strlen(frameTitle);
495 int i_child_text_length = strlen(childWnd->getWindowNameA());
496
497 lstrcpynA( lpBuffer, frameTitle, MDI_MAXTITLELENGTH);
498
499 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
500 {
501 strcat( lpBuffer, lpBracket );
502
503 if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
504 {
505 strcat( lpBuffer, childWnd->getWindowNameA());
506 strcat( lpBuffer, "]" );
507 }
508 else
509 {
510 lstrcpynA(lpBuffer + i_frame_text_length + 4,
511 childWnd->getWindowNameA(), MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
512 strcat( lpBuffer, "]" );
513 }
514 }
515 }
516 else
517 {
518 strncpy(lpBuffer, frameTitle, MDI_MAXTITLELENGTH );
519 lpBuffer[MDI_MAXTITLELENGTH]='\0';
520 }
521 }
522 else
523 lpBuffer[0] = '\0';
524
525 getParent()->SetWindowTextA(lpBuffer);
526 if( repaint == MDI_REPAINTFRAME)
527 getParent()->SetWindowPos(0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
528}
529#if 0
530/**********************************************************************
531 * MDICascade
532 */
533LONG Win32MDIClientWindow::cascade()
534{
535 WND** ppWnd;
536 UINT total;
537
538 if (getMaximizedChild())
539 SendMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
540
541 if (nActiveChildren == 0) return 0;
542
543 if ((ppWnd = WIN_BuildWinArray(clientWnd, BWA_SKIPHIDDEN | BWA_SKIPOWNED |
544 BWA_SKIPICONIC, &total)))
545 {
546 WND** heapPtr = ppWnd;
547 if( total )
548 {
549 INT delta = 0, n = 0;
550 POINT pos[2];
551 if( total < ci->nActiveChildren )
552 delta = GetSystemMetrics(SM_CYICONSPACING) +
553 GetSystemMetrics(SM_CYICON);
554
555 /* walk the list (backwards) and move windows */
556 while (*ppWnd) ppWnd++;
557 while (ppWnd != heapPtr)
558 {
559 ppWnd--;
560
561 MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
562 SetWindowPos( (*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y,
563 pos[1].x, pos[1].y,
564 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
565 }
566 }
567 WIN_ReleaseWinArray(heapPtr);
568 }
569
570 if( total < ci->nActiveChildren )
571 ArrangeIconicWindows( clientWnd->hwndSelf );
572
573 return 0;
574}
575
576/**********************************************************************
577 * MDITile
578 */
579void Win32MDIClientWindow::MDITile(WPARAM wParam )
580{
581 WND** ppWnd;
582 UINT total = 0;
583
584 if (getMaximizedChild())
585 SendMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
586
587 if (nActiveChildren == 0) return;
588
589 ppWnd = WIN_BuildWinArray(wndClient, BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
590 ((wParam & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
591
592 TRACE("%u windows to tile\n", total);
593
594 if( ppWnd )
595 {
596 WND** heapPtr = ppWnd;
597
598 if( total )
599 {
600 RECT rect;
601 int x, y, xsize, ysize;
602 int rows, columns, r, c, i;
603
604 GetClientRect(wndClient->hwndSelf,&rect);
605 rows = (int) sqrt((double)total);
606 columns = total / rows;
607
608 if( wParam & MDITILE_HORIZONTAL ) /* version >= 3.1 */
609 {
610 i = rows;
611 rows = columns; /* exchange r and c */
612 columns = i;
613 }
614
615 if( total != ci->nActiveChildren)
616 {
617 y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
618 rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
619 }
620
621 ysize = rect.bottom / rows;
622 xsize = rect.right / columns;
623
624 for (x = i = 0, c = 1; c <= columns && *ppWnd; c++)
625 {
626 if (c == columns)
627 {
628 rows = total - i;
629 ysize = rect.bottom / rows;
630 }
631
632 y = 0;
633 for (r = 1; r <= rows && *ppWnd; r++, i++)
634 {
635 SetWindowPos((*ppWnd)->hwndSelf, 0, x, y, xsize, ysize,
636 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
637 y += ysize;
638 ppWnd++;
639 }
640 x += xsize;
641 }
642 }
643 WIN_ReleaseWinArray(heapPtr);
644 }
645
646 if( total < ci->nActiveChildren ) ArrangeIconicWindows( wndClient->hwndSelf );
647}
648
649/* ----------------------- Frame window ---------------------------- */
650
651/**********************************************************************
652 * MDI_AugmentFrameMenu
653 */
654BOOL Win32MDIClientWindow::augmentFrameMenu(HWND hChild )
655{
656 WND* child = WIN_FindWndPtr(hChild);
657 HMENU hSysPopup = 0;
658 HBITMAP hSysMenuBitmap = 0;
659
660 if( !frame->wIDmenu || !child->hSysMenu )
661 {
662 WIN_ReleaseWndPtr(child);
663 return 0;
664 }
665 WIN_ReleaseWndPtr(child);
666
667 /* create a copy of sysmenu popup and insert it into frame menu bar */
668
669 if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
670 return 0;
671
672 TRACE("\tgot popup %04x in sysmenu %04x\n",
673 hSysPopup, child->hSysMenu);
674
675 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
676 SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
677 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
678 SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
679
680 /* In Win 95 look, the system menu is replaced by the child icon */
681
682 if(TWEAK_WineLook > WIN31_LOOK)
683 {
684 HICON hIcon = GetClassLongA(hChild, GCL_HICONSM);
685 if (!hIcon)
686 hIcon = GetClassLongA(hChild, GCL_HICON);
687 if (hIcon)
688 {
689 HDC hMemDC;
690 HBITMAP hBitmap, hOldBitmap;
691 HBRUSH hBrush;
692 HDC hdc = GetDC(hChild);
693
694 if (hdc)
695 {
696 int cx, cy;
697 cx = GetSystemMetrics(SM_CXSMICON);
698 cy = GetSystemMetrics(SM_CYSMICON);
699 hMemDC = CreateCompatibleDC(hdc);
700 hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
701 hOldBitmap = SelectObject(hMemDC, hBitmap);
702 SetMapMode(hMemDC, MM_TEXT);
703 hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
704 DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
705 SelectObject (hMemDC, hOldBitmap);
706 DeleteObject(hBrush);
707 DeleteDC(hMemDC);
708 ReleaseDC(hChild, hdc);
709 hSysMenuBitmap = hBitmap;
710 }
711 }
712 }
713 else
714 hSysMenuBitmap = hBmpClose;
715
716 if( !InsertMenuA(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
717 hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
718 {
719 TRACE("not inserted\n");
720 DestroyMenu(hSysPopup);
721 return 0;
722 }
723
724 /* The close button is only present in Win 95 look */
725 if(TWEAK_WineLook > WIN31_LOOK)
726 {
727 AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
728 SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
729 }
730
731 EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
732 EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
733 EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
734 SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
735
736 /* redraw menu */
737 DrawMenuBar(frame->hwndSelf);
738
739 return 1;
740}
741
742/**********************************************************************
743 * MDI_RestoreFrameMenu
744 */
745static BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild )
746{
747 MENUITEMINFOA menuInfo;
748 INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1;
749 UINT iId = GetMenuItemID(frameWnd->wIDmenu,nItems) ;
750
751 TRACE("frameWnd %p,child %04x\n",frameWnd,hChild);
752
753 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
754 return 0;
755
756 /*
757 * Remove the system menu, If that menu is the icon of the window
758 * as it is in win95, we have to delete the bitmap.
759 */
760 menuInfo.cbSize = sizeof(MENUITEMINFOA);
761 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
762
763 GetMenuItemInfoA(frameWnd->wIDmenu,
764 0,
765 TRUE,
766 &menuInfo);
767
768 RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
769
770 if ( (menuInfo.fType & MFT_BITMAP) &&
771 (LOWORD(menuInfo.dwTypeData)!=0) &&
772 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
773 {
774 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
775 }
776
777 if(TWEAK_WineLook > WIN31_LOOK)
778 {
779 /* close */
780 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
781 }
782 /* restore */
783 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
784 /* minimize */
785 DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
786
787 DrawMenuBar(frameWnd->hwndSelf);
788
789 return 1;
790}
791#endif
792/* -------- Miscellaneous service functions ----------
793 *
794 * MDI_GetChildByID
795 */
796Win32MDIChildWindow *Win32MDIClientWindow::getChildByID(INT id)
797{
798 Win32MDIChildWindow *child;
799
800 for (child = (Win32MDIChildWindow *)getFirstChild() ; child; child = (Win32MDIChildWindow *)child->getNextChild())
801 if (child->getWindowId() == id) return child;
802
803 return 0;
804}
805
806void Win32MDIClientWindow::postUpdate(WORD recalc)
807{
808 if( !(mdiFlags & MDIF_NEEDUPDATE) )
809 {
810 mdiFlags |= MDIF_NEEDUPDATE;
811 PostMessageA(WM_MDICALCCHILDSCROLL, 0, 0);
812 }
813 sbRecalc = recalc;
814}
815//******************************************************************************
816//******************************************************************************
817BOOL MDICLIENT_Register()
818{
819 WNDCLASSA wndClass;
820
821 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA)) return FALSE;
822
823 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
824 wndClass.style = CS_GLOBALCLASS;
825 wndClass.lpfnWndProc = (WNDPROC)MDIClientWndProc;
826 wndClass.cbClsExtra = 0;
827 wndClass.cbWndExtra = 0;
828 wndClass.hCursor = 0;
829 wndClass.hbrBackground = (HBRUSH)LTGRAY_BRUSH;
830 wndClass.lpszClassName = MDICLIENTCLASSNAMEA;
831
832 return RegisterClassA(&wndClass);
833}
834//******************************************************************************
835//******************************************************************************
836BOOL MDICLIENT_Unregister()
837{
838 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA))
839 return UnregisterClassA(MDICLIENTCLASSNAMEA,(HINSTANCE)NULL);
840 else return FALSE;
841}
842//******************************************************************************
843//******************************************************************************
Note: See TracBrowser for help on using the repository browser.