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

Last change on this file since 5258 was 5258, checked in by sandervl, 25 years ago

mdi, setcursor, min/max/restore, dlglist changes

File size: 40.1 KB
Line 
1/* $Id: win32wmdiclient.cpp,v 1.34 2001-02-23 14:52:42 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 Corel WINE (window\mdi.c: 20000317)
9 * (Parts based on Wine (windows\mdi.c) (990815))
10 *
11 * Copyright 1994, Bob Amstadt
12 * 1995,1996 Alex Korobka
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <win.h>
19#include <stdlib.h>
20#include <math.h>
21#include <string.h>
22#include <stdarg.h>
23#include <assert.h>
24#include <misc.h>
25#include <heapstring.h>
26#include <win32wnd.h>
27#include <win32wmdiclient.h>
28#include <spy.h>
29#include "wndmsg.h"
30#include <oslibwin.h>
31#include <oslibutil.h>
32#include <oslibgdi.h>
33#include <oslibres.h>
34#include "oslibdos.h"
35#include "syscolor.h"
36#include "win32wndhandle.h"
37
38#define DBG_LOCALLOG DBG_win32wmdiclient
39#include "dbglocal.h"
40
41
42//******************************************************************************
43//******************************************************************************
44Win32MDIClientWindow::Win32MDIClientWindow(CREATESTRUCTA *lpCreateStructA, ATOM classAtom, BOOL isUnicode)
45 : maximizedChild(0), activeChild(0), nActiveChildren(0), nTotalCreated(0),
46 frameTitle(NULL), mdiFlags(0), idFirstChild(0), hWindowMenu(0),
47 sbRecalc(0),
48 Win32BaseWindow(OBJTYPE_WINDOW)
49{
50 Init();
51 this->isUnicode = isUnicode;
52 CreateWindowExA(lpCreateStructA, classAtom);
53}
54//******************************************************************************
55//******************************************************************************
56Win32MDIClientWindow::~Win32MDIClientWindow()
57{
58 if(frameTitle)
59 HeapFree(GetProcessHeap(), 0, frameTitle);
60}
61//******************************************************************************
62//******************************************************************************
63BOOL Win32MDIClientWindow::isMDIClient()
64{
65 return TRUE;
66}
67//******************************************************************************
68//******************************************************************************
69LRESULT Win32MDIClientWindow::MDIClientWndProc(UINT message, WPARAM wParam, LPARAM lParam)
70{
71 LPCREATESTRUCTA cs;
72 LPCLIENTCREATESTRUCT ccs;
73 RECT rect;
74 INT nItems;
75 LRESULT retvalue;
76 Win32Window *frameWnd;
77 Win32MDIChildWindow *mdichild;
78
79 frameWnd = (Win32Window *)getParent();
80 if(frameWnd == NULL) {
81 return 0;
82 }
83
84 switch (message)
85 {
86 case WM_CREATE:
87 cs = (LPCREATESTRUCTA)lParam;
88 ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
89
90 hWindowMenu = ccs->hWindowMenu;
91 idFirstChild = ccs->idFirstChild;
92
93 maximizedChild = 0;
94 activeChild = 0;
95 nActiveChildren = 0;
96 nTotalCreated = 0;
97 frameTitle = NULL;
98 mdiFlags = 0;
99
100 setStyle(getStyle() | WS_CLIPCHILDREN);
101
102 updateFrameText(MDI_NOFRAMEREPAINT, getParent()->getWindowNameA());
103
104 AppendMenuA( hWindowMenu, MF_SEPARATOR, 0, NULL );
105
106 setClientRect(frameWnd->getClientRectPtr());
107
108 dprintf(("MDIClient created - hwnd = %04x, idFirst = %u\n", getWindowHandle(), idFirstChild ));
109
110 retvalue = 0;
111 goto END;
112
113 case WM_DESTROY:
114 if( maximizedChild ) restoreFrameMenu(getParent());
115
116 if((nItems = GetMenuItemCount(hWindowMenu)) > 0)
117 {
118 idFirstChild = nItems - 1;
119 nActiveChildren++; /* to delete a separator */
120 while( nActiveChildren-- )
121 DeleteMenu(hWindowMenu,MF_BYPOSITION,idFirstChild--);
122 }
123 retvalue = 0;
124 goto END;
125
126 case WM_MDIACTIVATE:
127 if( activeChild && activeChild->getWindowHandle() != (HWND)wParam )
128 {
129 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
130 if(mdichild) {
131 mdichild->SetWindowPos(0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
132 }
133 }
134 retvalue = 0;
135 goto END;
136
137 case WM_MDICASCADE:
138 retvalue = cascade(wParam);
139 goto END;
140
141 case WM_MDICREATE:
142 if (lParam) {
143 retvalue = Win32MDIChildWindow::createChild( this, (MDICREATESTRUCTA*)lParam );
144 }
145 else retvalue = 0;
146 goto END;
147
148 case WM_MDIDESTROY:
149 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
150 if(mdichild) {
151 retvalue = destroyChild(mdichild, TRUE );
152 }
153 goto END;
154
155 case WM_MDIGETACTIVE:
156 dprintf(("WM_MDIGETACTIVE: %x %x", this, (activeChild) ? activeChild->getWindowHandle() : 0));
157 if (lParam)
158 *(BOOL *)lParam = (maximizedChild != 0);
159
160 retvalue = (activeChild) ? activeChild->getWindowHandle() : 0;
161 goto END;
162
163 case WM_MDIICONARRANGE:
164 mdiFlags |= MDIF_NEEDUPDATE;
165 ArrangeIconicWindows(Win32Hwnd);
166 sbRecalc = SB_BOTH+1;
167 SendMessageA(WM_MDICALCCHILDSCROLL,0,0L);
168 retvalue = 0;
169 goto END;
170
171 case WM_MDIMAXIMIZE:
172 ::ShowWindow( (HWND)wParam, SW_MAXIMIZE );
173 retvalue = 0;
174 goto END;
175
176 case WM_MDINEXT: /* lParam != 0 means previous window */
177 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
178 if(mdichild) {
179 switchActiveChild(mdichild, (lParam)? FALSE : TRUE );
180 }
181 break;
182
183 case WM_MDIRESTORE:
184 ::SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
185 retvalue = 0;
186 goto END;
187 case WM_MDISETMENU:
188 retvalue = setMDIMenu((HMENU)wParam, (HMENU)lParam );
189 goto END;
190
191 case WM_MDIREFRESHMENU:
192 retvalue = refreshMDIMenu((HMENU)wParam, (HMENU)lParam );
193 goto END;
194
195 case WM_MDITILE:
196 mdiFlags |= MDIF_NEEDUPDATE;
197 ShowScrollBar(Win32Hwnd,SB_BOTH,FALSE);
198 tile(wParam);
199 mdiFlags &= ~MDIF_NEEDUPDATE;
200 retvalue = 0;
201 goto END;
202
203 case WM_VSCROLL:
204 case WM_HSCROLL:
205 mdiFlags |= MDIF_NEEDUPDATE;
206 ScrollChildren(Win32Hwnd, message, wParam, lParam);
207 mdiFlags &= ~MDIF_NEEDUPDATE;
208 retvalue = 0;
209 goto END;
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->SendInternalMessageA(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 case WM_MDICALCCHILDSCROLL:
259 if( (mdiFlags & MDIF_NEEDUPDATE) && sbRecalc )
260 {
261 CalcChildScroll(Win32Hwnd, sbRecalc-1);
262 sbRecalc = 0;
263 mdiFlags &= ~MDIF_NEEDUPDATE;
264 }
265 retvalue = 0;
266 goto END;
267 }
268 retvalue = DefWindowProcA(message, wParam, lParam );
269END:
270 return retvalue;
271}
272/**********************************************************************
273 * MDIClientWndProc
274 *
275 * This function handles all MDI requests.
276 */
277LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, WPARAM wParam,
278 LPARAM lParam )
279{
280 Win32MDIClientWindow *window;
281
282 window = (Win32MDIClientWindow *)Win32BaseWindow::GetWindowFromHandle(hwnd);
283 if(!window) {
284 dprintf(("MDIClientWndProc, window %x not found", hwnd));
285 return 0;
286 }
287 return window->MDIClientWndProc(message, wParam, lParam);
288}
289/**********************************************************************
290 * MDI_GetWindow
291 *
292 * returns "activateable" child different from the current or zero
293 */
294Win32MDIChildWindow *Win32MDIClientWindow::getWindow(Win32MDIChildWindow *actchild, BOOL bNext,
295 DWORD dwStyleMask)
296{
297 Win32MDIChildWindow *lastchild = 0, *curchild;
298
299 dwStyleMask |= WS_DISABLED | WS_VISIBLE;
300
301 if( !actchild ) actchild = getActiveChild();
302 if( !actchild) return 0;
303
304 for ( curchild = (Win32MDIChildWindow *)actchild->getNextChild(); ; curchild = (Win32MDIChildWindow *)curchild->getNextChild())
305 {
306 if (!curchild ) curchild = (Win32MDIChildWindow *)getFirstChild();
307
308 if ( curchild == actchild ) break; /* went full circle */
309
310 if (!curchild->getOwner() && (curchild->getStyle() & dwStyleMask) == WS_VISIBLE )
311 {
312 lastchild = curchild;
313 if ( bNext ) break;
314 }
315 }
316 return lastchild;
317}
318/**********************************************************************
319 * MDI_ChildActivate
320 *
321 * Note: hWndChild is NULL when last child is being destroyed
322 */
323LONG Win32MDIClientWindow::childActivate(Win32MDIChildWindow *child)
324{
325 BOOL isActiveFrameWnd = 0;
326 LONG retvalue;
327 Win32MDIChildWindow *prevActive = activeChild;
328
329 if( child && child->getStyle() & WS_DISABLED )
330 {
331 return 0;
332 }
333
334 /* Don't activate if it is already active. Might happen
335 since ShowWindow DOES activate MDI children */
336 if(activeChild == child)
337 {
338 return 0;
339 }
340
341 if( GetActiveWindow() == getParent()->getWindowHandle())
342 isActiveFrameWnd = TRUE;
343
344 /* deactivate prev. active child */
345 if( prevActive )
346 {
347 prevActive->setStyle(prevActive->getStyle() | WS_SYSMENU);
348 prevActive->DeactivateChildWindow();
349 prevActive->SendInternalMessageA( WM_NCACTIVATE, FALSE, 0L );
350 prevActive->SendInternalMessageA( 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 dprintf(("childActivate: %x %x", this, (child) ? child->getWindowHandle() : 0));
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->SendInternalMessageA( WM_NCACTIVATE, TRUE, 0L);
392 if( GetFocus() == getWindowHandle())
393 SendInternalMessageA( WM_SETFOCUS, (WPARAM)getWindowHandle(), 0L );
394 else
395 SetFocus( getWindowHandle() );
396 }
397
398 /* @@@PH prevActive may be NULL actually ?! */
399 child->SendInternalMessageA( 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(child->getWindowHandle(),SW_HIDE);
451 if( child == getMaximizedChild() )
452 {
453 restoreFrameMenu(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 postUpdate(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 lstrcpynA(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/**********************************************************************
537 * MDISetMenu
538 */
539LRESULT Win32MDIClientWindow::setMDIMenu(HMENU hmenuFrame, HMENU hmenuWindow)
540{
541 HWND hwndFrame = ::GetParent(getWindowHandle());
542 HMENU oldFrameMenu = ::GetMenu(hwndFrame);
543
544 if (hmenuFrame && !IsMenu(hmenuFrame))
545 {
546 dprintf(("Win32MDIClientWindow::setMDIMenu: hmenuFrame is not a menu handle\n"));
547 return 0L;
548 }
549
550 if (hmenuWindow && !IsMenu(hmenuWindow))
551 {
552 dprintf(("Win32MDIClientWindow::setMDIMenu: hmenuWindow is not a menu handle\n"));
553 return 0L;
554 }
555
556 if( maximizedChild && hmenuFrame && hmenuFrame!=oldFrameMenu )
557 restoreFrameMenu(maximizedChild);
558
559 if( hmenuWindow && hmenuWindow != hWindowMenu )
560 {
561 /* delete menu items from ci->hWindowMenu
562 * and add them to hmenuWindow */
563
564 INT i = GetMenuItemCount(hWindowMenu) - 1;
565 INT pos = GetMenuItemCount(hmenuWindow) + 1;
566
567 AppendMenuA( hmenuWindow, MF_SEPARATOR, 0, NULL);
568
569#if 1
570 if( nActiveChildren )
571 {
572 INT j = i - nActiveChildren + 1;
573 char buffer[100];
574 UINT id,state;
575
576 for( ; i >= j ; i-- )
577 {
578 id = GetMenuItemID(hWindowMenu,i );
579 state = GetMenuState(hWindowMenu,i,MF_BYPOSITION);
580
581 GetMenuStringA(hWindowMenu, i, buffer, 100, MF_BYPOSITION);
582
583 DeleteMenu(hWindowMenu, i , MF_BYPOSITION);
584 InsertMenuA(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
585 id, buffer);
586 CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
587 }
588 }
589#else
590//doesn't work:
591 if( nActiveChildren )
592 {
593 INT j;
594 LPWSTR buffer = NULL;
595 MENUITEMINFOW mii;
596 INT nbWindowsMenuItems; /* num of documents shown + "More Windows..." if present */
597
598 if (nActiveChildren <= MDI_MOREWINDOWSLIMIT)
599 nbWindowsMenuItems = nActiveChildren;
600 else
601 nbWindowsMenuItems = MDI_MOREWINDOWSLIMIT + 1;
602
603 j = i - nbWindowsMenuItems + 1;
604
605 for( ; i >= j ; i-- )
606 {
607 memset(&mii, 0, sizeof(mii));
608 mii.cbSize = sizeof(mii);
609 mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE
610 | MIIM_SUBMENU | MIIM_TYPE | MIIM_BITMAP;
611
612 GetMenuItemInfoW(hWindowMenu, i, TRUE, &mii);
613 if(mii.cch) { /* Menu is MFT_STRING */
614 mii.cch++; /* add room for '\0' */
615 buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
616 mii.cch * sizeof(WCHAR));
617 mii.dwTypeData = buffer;
618 GetMenuItemInfoW(hWindowMenu, i, TRUE, &mii);
619 }
620 DeleteMenu(hWindowMenu, i, MF_BYPOSITION);
621 InsertMenuItemW(hmenuWindow, pos, TRUE, &mii);
622 if(buffer) {
623 HeapFree(GetProcessHeap(), 0, buffer);
624 buffer = NULL;
625 }
626 }
627 }
628#endif
629 /* remove separator */
630 DeleteMenu(hWindowMenu, i, MF_BYPOSITION);
631
632 hWindowMenu = hmenuWindow;
633 }
634
635 if (hmenuFrame)
636 {
637 ::SetMenu(hwndFrame, hmenuFrame);
638
639 if( hmenuFrame!=oldFrameMenu )
640 {
641 if (maximizedChild)
642 augmentFrameMenu(maximizedChild);
643
644 return oldFrameMenu;
645 }
646 }
647 else
648 {
649 INT nItems = GetMenuItemCount(oldFrameMenu) - 1;
650 UINT iId = GetMenuItemID(oldFrameMenu,nItems) ;
651
652 if( !(iId == SC_RESTORE || iId == SC_CLOSE) )
653 {
654 /* SetMenu() may already have been called, meaning that this window
655 * already has its menu. But they may have done a SetMenu() on
656 * an MDI window, and called MDISetMenu() after the fact, meaning
657 * that the "if" to this "else" wouldn't catch the need to
658 * augment the frame menu.
659 */
660 if( maximizedChild )
661 augmentFrameMenu(maximizedChild);
662 }
663 }
664 return 0;
665}
666
667/**********************************************************************
668 * MDIRefreshMenu
669 */
670LRESULT Win32MDIClientWindow::refreshMDIMenu(HMENU hmenuFrame, HMENU hmenuWindow)
671{
672 HMENU oldFrameMenu = getParent()->GetMenu();
673
674// FIXME("partially function stub\n");
675
676 return oldFrameMenu;
677}
678/**********************************************************************
679 * MDI_RestoreFrameMenu
680 */
681BOOL Win32MDIClientWindow::restoreFrameMenu(Win32BaseWindow *child)
682{
683 MENUITEMINFOA menuInfo;
684 INT nItems = GetMenuItemCount(getParent()->GetMenu()) - 1;
685 UINT iId = GetMenuItemID(getParent()->GetMenu(),nItems) ;
686
687 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
688 return 0;
689
690 /*
691 * Remove the system menu, If that menu is the icon of the window
692 * as it is in win95, we have to delete the bitmap.
693 */
694 menuInfo.cbSize = sizeof(MENUITEMINFOA);
695 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
696
697 GetMenuItemInfoA(getParent()->GetMenu(),
698 0,
699 TRUE,
700 &menuInfo);
701
702 RemoveMenu(getParent()->GetMenu(),0,MF_BYPOSITION);
703
704//TODO: See augmentframemenu
705#if 0
706 if ((menuInfo.fType & MFT_BITMAP) &&
707 (LOWORD(menuInfo.dwTypeData)!=0) &&
708 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
709 {
710 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
711 }
712#endif
713
714 /* close */
715 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
716
717 /* restore */
718 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
719 /* minimize */
720 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
721
722 DrawMenuBar(getParent()->getWindowHandle());
723
724 return 1;
725}
726
727Win32BaseWindow** Win32MDIClientWindow::buildWindowArray(UINT bwaFlags,PUINT total)
728{
729 Win32BaseWindow **list = NULL,*win32wnd,**pos;
730 UINT skipHidden;
731 DWORD skipFlags;
732
733 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
734 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
735 if (bwaFlags & BWA_SKIPICONIC) skipFlags |= WS_MINIMIZE;
736
737 /* First count the windows */
738 *total = 0;
739 win32wnd = (Win32BaseWindow*)this->getFirstChild();
740 while (win32wnd)
741 {
742 if (!(win32wnd->getStyle() & skipFlags) && (!skipHidden || (win32wnd->getStyle() & WS_VISIBLE)))
743 (*total)++;
744 win32wnd = (Win32BaseWindow*)win32wnd->getNextChild();
745 }
746
747 if (*total)
748 {
749 /* Now build the list of all windows */
750 list = (Win32BaseWindow**)HeapAlloc(GetProcessHeap(),0,sizeof(Win32BaseWindow*)*(*total+1));
751 if (list)
752 {
753 for (win32wnd = (Win32BaseWindow*)this->getFirstChild(),pos = list;win32wnd;win32wnd = (Win32BaseWindow*)win32wnd->getNextChild())
754 {
755 if ((win32wnd->getStyle() & skipFlags));
756 else if(!skipHidden || win32wnd->getStyle() & WS_VISIBLE)
757 *pos++ = win32wnd;
758 }
759 *pos = NULL;
760 }
761 }
762
763 return list;
764}
765
766void Win32MDIClientWindow::releaseWindowArray(Win32BaseWindow **wndArray)
767{
768 HeapFree(GetProcessHeap(),0,wndArray);
769}
770
771/**********************************************************************
772 * MDI_CalcDefaultChildPos
773 *
774 * It seems that the default height is about 2/3 of the client rect
775 */
776void Win32MDIClientWindow::calcDefaultChildPos(WORD n,LPPOINT lpPos,INT delta)
777{
778 INT nstagger;
779 RECT rect;
780 INT spacing = GetSystemMetrics(SM_CYCAPTION) +
781 GetSystemMetrics(SM_CYFRAME) - 1;
782
783 getClientRect(&rect);
784 if( rect.bottom - rect.top - delta >= spacing )
785 rect.bottom -= delta;
786
787 nstagger = (rect.bottom - rect.top)/(3 * spacing);
788 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
789 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
790 lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
791}
792
793/**********************************************************************
794 * MDICascade
795 */
796BOOL Win32MDIClientWindow::cascade(UINT fuCascade)
797{
798 Win32BaseWindow **list;
799 UINT total = 0;
800
801 if (getMaximizedChild())
802 SendInternalMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
803
804 if (nActiveChildren == 0) return 0;
805
806 list = buildWindowArray(BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC,&total);
807 if (list)
808 {
809 Win32BaseWindow** heapPtr = list;
810 if (total)
811 {
812 INT delta = 0,n = 0;
813 POINT pos[2];
814
815
816 if (total < nActiveChildren)
817 delta = GetSystemMetrics(SM_CYICONSPACING)+GetSystemMetrics(SM_CYICON);
818
819 // walk the list (backwards) and move windows
820 while (*list) list++;
821 while (list != heapPtr)
822 {
823 list--;
824
825 calcDefaultChildPos(n++,pos,delta);
826 ::SetWindowPos((*list)->getWindowHandle(),0,pos[0].x,pos[0].y,pos[1].x,pos[1].y,SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
827 }
828 }
829 releaseWindowArray(heapPtr);
830 }
831
832 if (total < nActiveChildren)
833 ArrangeIconicWindows(Win32Hwnd);
834
835 return TRUE;
836}
837
838/**********************************************************************
839 * MDITile
840 */
841BOOL Win32MDIClientWindow::tile(UINT fuTile)
842{
843 Win32BaseWindow** list;
844 UINT total = 0;
845
846 if (getMaximizedChild())
847 SendInternalMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild()->getWindowHandle(), 0);
848
849 if (nActiveChildren == 0) return TRUE;
850
851 list = buildWindowArray(BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
852 ((fuTile & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
853
854 if (list)
855 {
856 Win32BaseWindow** heapPtr = list;
857
858 if (total)
859 {
860 RECT rect;
861 int x, y, xsize, ysize;
862 int rows, columns, r, c, i;
863
864 GetClientRect(Win32Hwnd,&rect);
865 rows = (int) sqrt((double)total);
866 columns = total / rows;
867
868 if( fuTile & MDITILE_HORIZONTAL ) // version >= 3.1
869 {
870 i = rows;
871 rows = columns; // exchange r and c
872 columns = i;
873 }
874
875 if( total != nActiveChildren)
876 {
877 y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
878 rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
879 }
880
881 ysize = rect.bottom / rows;
882 xsize = rect.right / columns;
883
884 for (x = i = 0, c = 1; c <= columns && *list; c++)
885 {
886 if (c == columns)
887 {
888 rows = total - i;
889 ysize = rect.bottom / rows;
890 }
891
892 y = 0;
893 for (r = 1; r <= rows && *list; r++, i++)
894 {
895 ::SetWindowPos((*list)->getWindowHandle(), 0, x, y, xsize, ysize,
896 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
897 y += ysize;
898 list++;
899 }
900 x += xsize;
901 }
902 }
903 releaseWindowArray(heapPtr);
904 }
905
906 if( total < nActiveChildren ) ArrangeIconicWindows(Win32Hwnd);
907
908 return TRUE;
909}
910
911/* ----------------------- Frame window ---------------------------- */
912
913/**********************************************************************
914 * MDI_AugmentFrameMenu
915 */
916BOOL Win32MDIClientWindow::augmentFrameMenu(Win32MDIChildWindow *child)
917{
918 HMENU hSysPopup = 0,hFrameMenu = ::GetMenu(getParent()->getWindowHandle()),hSysMenu = ::GetSystemMenu(child->getWindowHandle(),FALSE);
919 HBITMAP hSysMenuBitmap = 0;
920
921 if (!hFrameMenu || !hSysMenu)
922 return 0;
923
924 // create a copy of sysmenu popup and insert it into frame menu bar
925
926 if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
927 return 0;
928
929 //TRACE("\tgot popup %04x in sysmenu %04x\n",
930 // hSysPopup, child->hSysMenu);
931
932 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
933 SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
934 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
935 SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
936
937 // In Win 95 look, the system menu is replaced by the child icon
938
939 /* Find icon */
940 HICON hIcon = child->IconForWindow(ICON_SMALL);
941
942 if (hIcon)
943 {
944 HDC hMemDC;
945 HBITMAP hBitmap, hOldBitmap;
946 HBRUSH hBrush;
947 HDC hdc = GetDC(child->getWindowHandle());
948
949 if (hdc)
950 {
951 int cx, cy;
952
953 cx = GetSystemMetrics(SM_CXSMICON);
954 cy = GetSystemMetrics(SM_CYSMICON);
955 hMemDC = CreateCompatibleDC(hdc);
956 hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
957 hOldBitmap = SelectObject(hMemDC, hBitmap);
958 SetMapMode(hMemDC, MM_TEXT);
959 hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
960 DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
961 SelectObject (hMemDC, hOldBitmap);
962 DeleteObject(hBrush);
963 DeleteDC(hMemDC);
964 ReleaseDC(child->getWindowHandle(), hdc);
965 hSysMenuBitmap = hBitmap;
966 }
967 }
968
969 if( !InsertMenuA(hFrameMenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
970 hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
971 {
972 //TRACE("not inserted\n");
973 DestroyMenu(hSysPopup);
974 return 0;
975 }
976
977 // The close button is only present in Win 95 look
978
979 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
980 SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
981
982 EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
983 EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
984 EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
985 SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
986
987 // redraw menu
988 DrawMenuBar(getParent()->getWindowHandle());
989
990 return 1;
991}
992
993/**********************************************************************
994 * MDI_RestoreFrameMenu
995 */
996BOOL Win32MDIClientWindow::restoreFrameMenu(Win32MDIChildWindow *child)
997{
998 MENUITEMINFOA menuInfo;
999 HMENU hFrameMenu = ::GetMenu(getParent()->getWindowHandle());
1000 INT nItems = GetMenuItemCount(hFrameMenu) - 1;
1001 UINT iId = GetMenuItemID(hFrameMenu,nItems) ;
1002
1003 //TRACE("frameWnd %p,child %04x\n",frameWnd,hChild);
1004
1005 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
1006 return 0;
1007
1008 /*
1009 * Remove the system menu, If that menu is the icon of the window
1010 * as it is in win95, we have to delete the bitmap.
1011 */
1012
1013 menuInfo.cbSize = sizeof(MENUITEMINFOA);
1014 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
1015
1016 GetMenuItemInfoA(hFrameMenu,
1017 0,
1018 TRUE,
1019 &menuInfo);
1020
1021 RemoveMenu(hFrameMenu,0,MF_BYPOSITION);
1022
1023#if 0 //CB: hBmpClose not (yet) defined
1024 if ( (menuInfo.fType & MFT_BITMAP) &&
1025 (LOWORD(menuInfo.dwTypeData)!=0) &&
1026 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
1027 {
1028 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
1029 }
1030#endif
1031
1032 // close
1033 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1034
1035 // restore
1036 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1037 // minimize
1038 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1039
1040 DrawMenuBar(getParent()->getWindowHandle());
1041
1042 return 1;
1043}
1044
1045/***********************************************************************
1046 * CalcChildScroll (USER.462)
1047 */
1048void WINAPI CalcChildScroll(HWND hwnd,WORD scroll)
1049{
1050 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1051 SCROLLINFO info;
1052 RECT childRect, clientRect;
1053 INT vmin, vmax, hmin, hmax, vpos, hpos;
1054
1055 if (!win32wnd) return;
1056
1057 GetClientRect( hwnd, &clientRect );
1058 SetRectEmpty( &childRect );
1059
1060 //TODO: Check if this goes correctly
1061 for (win32wnd = (Win32BaseWindow*)win32wnd->getFirstChild();win32wnd;win32wnd = (Win32BaseWindow*)win32wnd->getNextChild())
1062 {
1063 if( win32wnd->getStyle() & WS_MAXIMIZE )
1064 {
1065 ShowScrollBar(hwnd, SB_BOTH, FALSE);
1066 return;
1067 }
1068 UnionRect(&childRect,win32wnd->getWindowRect(),&childRect);
1069 }
1070 UnionRect( &childRect, &clientRect, &childRect );
1071
1072 hmin = childRect.left; hmax = childRect.right - clientRect.right;
1073 hpos = clientRect.left - childRect.left;
1074 vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
1075 vpos = clientRect.top - childRect.top;
1076
1077 switch( scroll )
1078 {
1079 case SB_HORZ:
1080 vpos = hpos; vmin = hmin; vmax = hmax;
1081 case SB_VERT:
1082 info.cbSize = sizeof(info);
1083 info.nMax = vmax; info.nMin = vmin; info.nPos = vpos;
1084 info.fMask = SIF_POS | SIF_RANGE;
1085 SetScrollInfo(hwnd, scroll, &info, TRUE);
1086 break;
1087 case SB_BOTH:
1088 {
1089 SCROLLINFO vInfo, hInfo;
1090
1091 vInfo.cbSize = hInfo.cbSize = sizeof(SCROLLINFO);
1092 vInfo.nMin = vmin;
1093 hInfo.nMin = hmin;
1094 vInfo.nMax = vmax;
1095 hInfo.nMax = hmax;
1096 vInfo.nPos = vpos;
1097 hInfo.nPos = hpos;
1098 vInfo.fMask = hInfo.fMask = SIF_RANGE | SIF_POS;
1099
1100 SetScrollInfo(hwnd,SB_VERT,&vInfo,TRUE);
1101 SetScrollInfo(hwnd,SB_HORZ,&hInfo,TRUE);
1102 }
1103 }
1104}
1105
1106/***********************************************************************
1107 * ScrollChildren32 (USER32.448)
1108 */
1109void WINAPI ScrollChildren(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
1110{
1111 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hWnd);
1112 INT newPos = -1;
1113 INT curPos, length, minPos, maxPos, shift;
1114
1115 if (!win32wnd) return;
1116
1117 if (uMsg == WM_HSCROLL)
1118 {
1119 GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
1120 curPos = GetScrollPos(hWnd,SB_HORZ);
1121 length = win32wnd->getClientWidth()/2;
1122 shift = GetSystemMetrics(SM_CYHSCROLL);
1123 } else if (uMsg == WM_VSCROLL)
1124 {
1125 GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
1126 curPos = GetScrollPos(hWnd,SB_VERT);
1127 length = win32wnd->getClientHeight()/2;
1128 shift = GetSystemMetrics(SM_CXVSCROLL);
1129 } else return;
1130
1131 switch( wParam )
1132 {
1133 case SB_LINEUP:
1134 newPos = curPos - shift;
1135 break;
1136
1137 case SB_LINEDOWN:
1138 newPos = curPos + shift;
1139 break;
1140
1141 case SB_PAGEUP:
1142 newPos = curPos - length;
1143 break;
1144
1145 case SB_PAGEDOWN:
1146 newPos = curPos + length;
1147 break;
1148
1149 case SB_THUMBPOSITION:
1150 newPos = LOWORD(lParam);
1151 break;
1152
1153 case SB_THUMBTRACK:
1154 return;
1155
1156 case SB_TOP:
1157 newPos = minPos;
1158 break;
1159
1160 case SB_BOTTOM:
1161 newPos = maxPos;
1162 break;
1163
1164 case SB_ENDSCROLL:
1165 CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
1166 return;
1167 }
1168
1169 if( newPos > maxPos )
1170 newPos = maxPos;
1171 else
1172 if( newPos < minPos )
1173 newPos = minPos;
1174
1175 SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
1176
1177 if( uMsg == WM_VSCROLL )
1178 ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
1179 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
1180 else
1181 ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
1182 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
1183}
1184
1185/*****************************************************************************
1186 * Name : WORD WIN32API CascadeWindows
1187 * Purpose : The CascadeWindows function cascades the specified windows or
1188 * the child windows of the specified parent window.
1189 * Parameters: HWND hwndParent handle of parent window
1190 * UINT wHow types of windows not to arrange
1191 * CONST RECT * lpRect rectangle to arrange windows in
1192 * UINT cKids number of windows to arrange
1193 * const HWND FAR * lpKids array of window handles
1194 * Variables :
1195 * Result : If the function succeeds, the return value is the number of windows arranged.
1196 * If the function fails, the return value is zero.
1197 * Remark :
1198 * Status : UNTESTED STUB
1199 *
1200 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1201 *****************************************************************************/
1202WORD WIN32API CascadeWindows(HWND hwndParent,
1203 UINT wHow,
1204 CONST LPRECT lpRect,
1205 UINT cKids,
1206 const HWND *lpKids)
1207{
1208 dprintf(("USER32:CascadeWindows(%08xh,%u,%08xh,%u,%08x) not implemented.\n",
1209 hwndParent,
1210 wHow,
1211 lpRect,
1212 cKids,
1213 lpKids));
1214
1215 return (0);
1216}
1217
1218/*****************************************************************************
1219 * Name : BOOL WIN32API CascadeChildWindows
1220 * Purpose : Unknown
1221 * Parameters: Unknown
1222 * Variables :
1223 * Result :
1224 * Remark :
1225 * Status : UNTESTED UNKNOWN STUB
1226 *
1227 * Author : Patrick Haller [Wed, 1998/06/16 11:55]
1228 *****************************************************************************/
1229BOOL WIN32API CascadeChildWindows(DWORD x1,
1230 DWORD x2)
1231{
1232 dprintf(("USER32: CascadeChildWindows(%08xh,%08xh) not implemented.\n",
1233 x1,
1234 x2));
1235
1236 return (FALSE); /* default */
1237}
1238
1239/*****************************************************************************
1240 * Name : WORD WIN32API TileWindows
1241 * Purpose : The TileWindows function tiles the specified windows, or the child
1242 * windows of the specified parent window.
1243 * Parameters: HWND hwndParent handle of parent window
1244 * WORD wFlags types of windows not to arrange
1245 * LPCRECT lpRect rectangle to arrange windows in
1246 * WORD cChildrenb number of windows to arrange
1247 * const HWND *ahwndChildren array of window handles
1248 * Variables :
1249 * Result : If the function succeeds, the return value is the number of
1250 * windows arranged.
1251 * If the function fails, the return value is zero.
1252 * Remark :
1253 * Status : UNTESTED STUB
1254 *
1255 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1256 *****************************************************************************/
1257WORD WIN32API TileWindows(HWND hwndParent,
1258 UINT wFlags,
1259 const LPRECT lpRect,
1260 UINT cChildrenb,
1261 const HWND *ahwndChildren)
1262{
1263 dprintf(("USER32:TileWindows (%08xh,%08xh,%08xh,%08xh,%08x) not implemented.\n",
1264 hwndParent,
1265 wFlags,
1266 lpRect,
1267 cChildrenb,
1268 ahwndChildren));
1269
1270 return (0);
1271}
1272
1273/*****************************************************************************
1274 * Name : BOOL WIN32API TileChildWindows
1275 * Purpose : Unknown
1276 * Parameters: Unknown
1277 * Variables :
1278 * Result :
1279 * Remark :
1280 * Status : UNTESTED UNKNOWN STUB
1281 *
1282 * Author : Patrick Haller [Wed, 1998/06/16 11:55]
1283 *****************************************************************************/
1284BOOL WIN32API TileChildWindows(DWORD x1,
1285 DWORD x2)
1286{
1287 dprintf(("USER32: TileChildWindows(%08xh,%08xh) not implemented.\n",
1288 x1,
1289 x2));
1290
1291 return (FALSE); /* default */
1292}
1293
1294/* -------- Miscellaneous service functions ----------
1295 *
1296 * MDI_GetChildByID
1297 */
1298Win32MDIChildWindow *Win32MDIClientWindow::getChildByID(INT id)
1299{
1300 Win32MDIChildWindow *child;
1301
1302 for (child = (Win32MDIChildWindow *)getFirstChild() ; child; child = (Win32MDIChildWindow *)child->getNextChild())
1303 if (child->getWindowId() == id) return child;
1304
1305 return 0;
1306}
1307
1308void Win32MDIClientWindow::postUpdate(WORD recalc)
1309{
1310 if( !(mdiFlags & MDIF_NEEDUPDATE) )
1311 {
1312 mdiFlags |= MDIF_NEEDUPDATE;
1313 PostMessageA(getWindowHandle(), WM_MDICALCCHILDSCROLL, 0, 0);
1314 }
1315 sbRecalc = recalc;
1316}
1317//******************************************************************************
1318//******************************************************************************
1319BOOL MDICLIENT_Register()
1320{
1321 WNDCLASSA wndClass;
1322
1323//SvL: Don't check this now
1324// if (GlobalFindAtomA(MDICLIENTCLASSNAMEA)) return FALSE;
1325
1326 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
1327 wndClass.style = CS_GLOBALCLASS;
1328 wndClass.lpfnWndProc = (WNDPROC)MDIClientWndProc;
1329 wndClass.cbClsExtra = 0;
1330 wndClass.cbWndExtra = 0;
1331 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);;
1332 wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
1333 wndClass.lpszClassName = MDICLIENTCLASSNAMEA;
1334
1335 return RegisterClassA(&wndClass);
1336}
1337//******************************************************************************
1338//******************************************************************************
1339BOOL MDICLIENT_Unregister()
1340{
1341 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA))
1342 return UnregisterClassA(MDICLIENTCLASSNAMEA,(HINSTANCE)NULL);
1343 else return FALSE;
1344}
1345//******************************************************************************
1346//******************************************************************************
Note: See TracBrowser for help on using the repository browser.