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

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

mouse dragging fix + updated isMdiClient code/headers

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