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

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

MDI activate bugfix

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