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

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

mdi client fix from Yurio Dario

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