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

Last change on this file since 5935 was 5935, checked in by sandervl, 24 years ago

reference count (window + class objects) rewrite

File size: 40.8 KB
Line 
1/* $Id: win32wmdiclient.cpp,v 1.35 2001-06-09 14:50:23 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()
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 != (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 RELEASE_WNDOBJ(mdichild);
133 }
134 }
135 retvalue = 0;
136 goto END;
137
138 case WM_MDICASCADE:
139 retvalue = cascade(wParam);
140 goto END;
141
142 case WM_MDICREATE:
143 if (lParam) {
144 retvalue = Win32MDIChildWindow::createChild( this, (MDICREATESTRUCTA*)lParam );
145 }
146 else retvalue = 0;
147 goto END;
148
149 case WM_MDIDESTROY:
150 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
151 if(mdichild) {
152 retvalue = destroyChild(mdichild, TRUE );
153 RELEASE_WNDOBJ(mdichild);
154 }
155 goto END;
156
157 case WM_MDIGETACTIVE:
158 dprintf(("WM_MDIGETACTIVE: %x %x", this, activeChild));
159 if (lParam)
160 *(BOOL *)lParam = (maximizedChild != 0);
161
162 retvalue = activeChild;
163 goto END;
164
165 case WM_MDIICONARRANGE:
166 mdiFlags |= MDIF_NEEDUPDATE;
167 ArrangeIconicWindows(Win32Hwnd);
168 sbRecalc = SB_BOTH+1;
169 SendMessageA(WM_MDICALCCHILDSCROLL,0,0L);
170 retvalue = 0;
171 goto END;
172
173 case WM_MDIMAXIMIZE:
174 ::ShowWindow( (HWND)wParam, SW_MAXIMIZE );
175 retvalue = 0;
176 goto END;
177
178 case WM_MDINEXT: /* lParam != 0 means previous window */
179 mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
180 if(mdichild) {
181 switchActiveChild(mdichild, (lParam)? FALSE : TRUE );
182 RELEASE_WNDOBJ(mdichild);
183 }
184 break;
185
186 case WM_MDIRESTORE:
187 ::SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
188 retvalue = 0;
189 goto END;
190 case WM_MDISETMENU:
191 retvalue = setMDIMenu((HMENU)wParam, (HMENU)lParam );
192 goto END;
193
194 case WM_MDIREFRESHMENU:
195 retvalue = refreshMDIMenu((HMENU)wParam, (HMENU)lParam );
196 goto END;
197
198 case WM_MDITILE:
199 mdiFlags |= MDIF_NEEDUPDATE;
200 ShowScrollBar(Win32Hwnd,SB_BOTH,FALSE);
201 tile(wParam);
202 mdiFlags &= ~MDIF_NEEDUPDATE;
203 retvalue = 0;
204 goto END;
205
206 case WM_VSCROLL:
207 case WM_HSCROLL:
208 mdiFlags |= MDIF_NEEDUPDATE;
209 ScrollChildren(Win32Hwnd, message, wParam, lParam);
210 mdiFlags &= ~MDIF_NEEDUPDATE;
211 retvalue = 0;
212 goto END;
213
214 case WM_SETFOCUS:
215 if( activeChild )
216 {
217 if( !(GetWindowLongA(activeChild, GWL_STYLE) & WS_MINIMIZE) )
218 ::SetFocus(activeChild);
219 }
220 retvalue = 0;
221 goto END;
222
223 case WM_NCACTIVATE:
224 if( activeChild )
225 ::SendMessageA(activeChild, message, wParam, lParam);
226 break;
227
228 case WM_PARENTNOTIFY:
229 if (LOWORD(wParam) == WM_LBUTTONDOWN)
230 {
231 POINTS pt = MAKEPOINTS(lParam);
232 POINT point;
233
234 point.x = pt.x;
235 point.y = pt.y;
236
237 HWND child = ChildWindowFromPoint(getWindowHandle(), point);
238
239 if( child && child != getWindowHandle() && (activeChild != child) )
240 ::SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
241 }
242 retvalue = 0;
243 goto END;
244
245 case WM_SIZE:
246 if( ::IsWindow(maximizedChild) )
247 {
248 RECT rect;
249
250 rect.left = 0;
251 rect.top = 0;
252 rect.right = LOWORD(lParam);
253 rect.bottom = HIWORD(lParam);
254
255 AdjustWindowRectEx(&rect, GetWindowLongA(maximizedChild, GWL_STYLE), 0, GetWindowLongA(maximizedChild, GWL_EXSTYLE));
256 ::MoveWindow(maximizedChild, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 1);
257 }
258 else postUpdate(SB_BOTH+1);
259 break;
260
261 case WM_MDICALCCHILDSCROLL:
262 if( (mdiFlags & MDIF_NEEDUPDATE) && sbRecalc )
263 {
264 CalcChildScroll(Win32Hwnd, sbRecalc-1);
265 sbRecalc = 0;
266 mdiFlags &= ~MDIF_NEEDUPDATE;
267 }
268 retvalue = 0;
269 goto END;
270 }
271 retvalue = DefWindowProcA(message, wParam, lParam );
272END:
273 return retvalue;
274}
275/**********************************************************************
276 * MDIClientWndProc
277 *
278 * This function handles all MDI requests.
279 */
280LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, WPARAM wParam,
281 LPARAM lParam )
282{
283 Win32MDIClientWindow *window;
284
285 window = (Win32MDIClientWindow *)Win32BaseWindow::GetWindowFromHandle(hwnd);
286 if(!window) {
287 dprintf(("MDIClientWndProc, window %x not found", hwnd));
288 return 0;
289 }
290 LRESULT ret = window->MDIClientWndProc(message, wParam, lParam);
291 RELEASE_WNDOBJ(window);
292 return ret;
293}
294/**********************************************************************
295 * MDI_GetWindow
296 *
297 * returns "activateable" child different from the current or zero
298 */
299Win32MDIChildWindow *Win32MDIClientWindow::getWindow(Win32MDIChildWindow *actchild, BOOL bNext,
300 DWORD dwStyleMask)
301{
302 Win32MDIChildWindow *lastchild = 0, *curchild;
303
304 dwStyleMask |= WS_DISABLED | WS_VISIBLE;
305
306 if( !actchild ) {
307 actchild = (Win32MDIChildWindow *)GetWindowFromHandle(getActiveChild());
308 }
309 else actchild->addRef();
310
311 if( !actchild) return 0;
312
313 lock();
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 unlock();
327 RELEASE_WNDOBJ(actchild);
328 return lastchild;
329}
330/**********************************************************************
331 * MDI_ChildActivate
332 *
333 * Note: hWndChild is NULL when last child is being destroyed
334 */
335LONG Win32MDIClientWindow::childActivate(Win32MDIChildWindow *child)
336{
337 BOOL isActiveFrameWnd = 0;
338 LONG retvalue;
339 Win32MDIChildWindow *prevActive = (Win32MDIChildWindow *)GetWindowFromHandle(activeChild);
340
341 if( child && child->getStyle() & WS_DISABLED )
342 {
343 if(prevActive) RELEASE_WNDOBJ(prevActive);
344 return 0;
345 }
346
347 /* Don't activate if it is already active. Might happen
348 since ShowWindow DOES activate MDI children */
349 if(activeChild == child->getWindowHandle())
350 {
351 if(prevActive) RELEASE_WNDOBJ(prevActive);
352 return 0;
353 }
354
355 if( GetActiveWindow() == getParent()->getWindowHandle())
356 isActiveFrameWnd = TRUE;
357
358 /* deactivate prev. active child */
359 if( prevActive )
360 {
361 prevActive->setStyle(prevActive->getStyle() | WS_SYSMENU);
362 prevActive->DeactivateChildWindow();
363 prevActive->SendInternalMessageA( WM_NCACTIVATE, FALSE, 0L );
364 prevActive->SendInternalMessageA( WM_MDIACTIVATE, (WPARAM)prevActive->getWindowHandle(), (LPARAM)(child) ? child->getWindowHandle() : 0);
365
366 /* uncheck menu item */
367 if( getMDIMenu() )
368 CheckMenuItem(getMDIMenu(), prevActive->getWindowId(), 0);
369 }
370
371 /* set appearance */
372 if( maximizedChild)
373 {
374 if( maximizedChild != child->getWindowHandle()) {
375 if( child ) {
376 activeChild = child->getWindowHandle();
377 child->ShowWindow(SW_SHOWMAXIMIZED);
378 }
379 else
380 if(activeChild) ::ShowWindow(activeChild, SW_SHOWNORMAL );
381 }
382 }
383
384 dprintf(("childActivate: %x %x", this, (child) ? child->getWindowHandle() : 0));
385 activeChild = child->getWindowHandle();
386
387 /* check if we have any children left */
388 if( !activeChild )
389 {
390 if( isActiveFrameWnd )
391 SetFocus(getWindowHandle());
392
393 if(prevActive) RELEASE_WNDOBJ(prevActive);
394 return 0;
395 }
396
397 /* check menu item */
398 if( getMDIMenu() )
399 CheckMenuItem(getMDIMenu(), child->getWindowId(), MF_CHECKED);
400
401 /* bring active child to the top */
402 child->SetWindowPos( 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
403
404 if( isActiveFrameWnd )
405 {
406 child->SendInternalMessageA( WM_NCACTIVATE, TRUE, 0L);
407 if( GetFocus() == getWindowHandle())
408 SendInternalMessageA( WM_SETFOCUS, (WPARAM)getWindowHandle(), 0L );
409 else
410 SetFocus( getWindowHandle() );
411 }
412
413 /* @@@PH prevActive may be NULL actually ?! */
414 child->SendInternalMessageA( WM_MDIACTIVATE,
415 prevActive ? (WPARAM)prevActive->getWindowHandle() : 0,
416 child->getWindowHandle());
417
418 if(prevActive) RELEASE_WNDOBJ(prevActive);
419 return TRUE;
420}
421/**********************************************************************
422 * MDI_SwitchActiveChild
423 *
424 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
425 * being activated
426 */
427void Win32MDIClientWindow::switchActiveChild(Win32MDIChildWindow *nextActiveChild, BOOL bNextWindow )
428{
429 HWND prevActiveChild = 0;
430
431 if ( !nextActiveChild) return; /* no window to switch to */
432
433 prevActiveChild = getActiveChild();
434
435 if ( prevActiveChild != nextActiveChild->getWindowHandle())
436 {
437 BOOL bOptimize = 0;
438
439 if( getMaximizedChild() )
440 {
441 bOptimize = 1;
442 nextActiveChild->setStyle(nextActiveChild->getStyle()& ~WS_VISIBLE);
443 }
444
445 nextActiveChild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
446
447 if( bNextWindow && prevActiveChild )
448 ::SetWindowPos(prevActiveChild, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
449
450 if( bOptimize )
451 ShowWindow(SW_SHOW );
452 }
453}
454
455
456/**********************************************************************
457 * MDIDestroyChild
458 */
459LRESULT Win32MDIClientWindow::destroyChild(Win32MDIChildWindow *child, BOOL flagDestroy )
460{
461 if( child->getWindowHandle() == getActiveChild())
462 {
463 switchActiveChild(child, TRUE);
464
465 if( child->getWindowHandle() == getActiveChild() )
466 {
467 ::ShowWindow(child->getWindowHandle(),SW_HIDE);
468 if( child->getWindowHandle() == getMaximizedChild() )
469 {
470 restoreFrameMenu(child);
471 setMaximizedChild(NULL);
472 updateFrameText(TRUE,NULL);
473 }
474 childActivate(0);
475 }
476 }
477 child->menuDeleteItem();
478
479 decNrActiveChildren();
480
481 dprintf(("child destroyed - %04x\n", child->getWindowHandle()));
482
483 if (flagDestroy)
484 {
485 postUpdate(SB_BOTH+1);
486 ::DestroyWindow(child->getWindowHandle());
487 }
488
489 return 0;
490}
491/**********************************************************************
492 * MDI_UpdateFrameText
493 *
494 * used when child window is maximized/restored
495 *
496 * Note: lpTitle can be NULL
497 */
498void Win32MDIClientWindow::updateFrameText(BOOL repaint, LPCSTR lpTitle )
499{
500 char lpBuffer[MDI_MAXTITLELENGTH+1];
501
502 /* store new "default" title if lpTitle is not NULL */
503 if (lpTitle)
504 {
505 if (frameTitle) HeapFree( GetProcessHeap(), 0, frameTitle );
506 frameTitle = HEAP_strdupA( GetProcessHeap(), 0, lpTitle );
507 }
508
509 if (frameTitle)
510 {
511 Win32MDIChildWindow *childWnd = (Win32MDIChildWindow *)GetWindowFromHandle(getMaximizedChild());
512
513 if( childWnd && childWnd->getWindowNameA() )
514 {
515 /* combine frame title and child title if possible */
516
517 LPCSTR lpBracket = " - [";
518 int i_frame_text_length = strlen(frameTitle);
519 int i_child_text_length = strlen(childWnd->getWindowNameA());
520
521 lstrcpynA( lpBuffer, frameTitle, MDI_MAXTITLELENGTH);
522
523 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
524 {
525 strcat( lpBuffer, lpBracket );
526
527 if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
528 {
529 strcat( lpBuffer, childWnd->getWindowNameA());
530 strcat( lpBuffer, "]" );
531 }
532 else
533 {
534 lstrcpynA(lpBuffer + i_frame_text_length + 4,
535 childWnd->getWindowNameA(), MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
536 strcat( lpBuffer, "]" );
537 }
538 }
539 }
540 else
541 {
542 lstrcpynA(lpBuffer, frameTitle, MDI_MAXTITLELENGTH );
543 lpBuffer[MDI_MAXTITLELENGTH]='\0';
544 }
545 if(childWnd) RELEASE_WNDOBJ(childWnd);
546 }
547 else
548 lpBuffer[0] = '\0';
549
550 getParent()->SetWindowTextA(lpBuffer);
551 if( repaint == MDI_REPAINTFRAME)
552 getParent()->SetWindowPos(0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
553}
554/**********************************************************************
555 * MDISetMenu
556 */
557LRESULT Win32MDIClientWindow::setMDIMenu(HMENU hmenuFrame, HMENU hmenuWindow)
558{
559 HWND hwndFrame = ::GetParent(getWindowHandle());
560 HMENU oldFrameMenu = ::GetMenu(hwndFrame);
561
562 if (hmenuFrame && !IsMenu(hmenuFrame))
563 {
564 dprintf(("Win32MDIClientWindow::setMDIMenu: hmenuFrame is not a menu handle\n"));
565 return 0L;
566 }
567
568 if (hmenuWindow && !IsMenu(hmenuWindow))
569 {
570 dprintf(("Win32MDIClientWindow::setMDIMenu: hmenuWindow is not a menu handle\n"));
571 return 0L;
572 }
573
574 if( maximizedChild && hmenuFrame && hmenuFrame!=oldFrameMenu )
575 restoreFrameMenu(maximizedChild);
576
577 if( hmenuWindow && hmenuWindow != hWindowMenu )
578 {
579 /* delete menu items from ci->hWindowMenu
580 * and add them to hmenuWindow */
581
582 INT i = GetMenuItemCount(hWindowMenu) - 1;
583 INT pos = GetMenuItemCount(hmenuWindow) + 1;
584
585 AppendMenuA( hmenuWindow, MF_SEPARATOR, 0, NULL);
586
587#if 1
588 if( nActiveChildren )
589 {
590 INT j = i - nActiveChildren + 1;
591 char buffer[100];
592 UINT id,state;
593
594 for( ; i >= j ; i-- )
595 {
596 id = GetMenuItemID(hWindowMenu,i );
597 state = GetMenuState(hWindowMenu,i,MF_BYPOSITION);
598
599 GetMenuStringA(hWindowMenu, i, buffer, 100, MF_BYPOSITION);
600
601 DeleteMenu(hWindowMenu, i , MF_BYPOSITION);
602 InsertMenuA(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
603 id, buffer);
604 CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
605 }
606 }
607#else
608//doesn't work:
609 if( nActiveChildren )
610 {
611 INT j;
612 LPWSTR buffer = NULL;
613 MENUITEMINFOW mii;
614 INT nbWindowsMenuItems; /* num of documents shown + "More Windows..." if present */
615
616 if (nActiveChildren <= MDI_MOREWINDOWSLIMIT)
617 nbWindowsMenuItems = nActiveChildren;
618 else
619 nbWindowsMenuItems = MDI_MOREWINDOWSLIMIT + 1;
620
621 j = i - nbWindowsMenuItems + 1;
622
623 for( ; i >= j ; i-- )
624 {
625 memset(&mii, 0, sizeof(mii));
626 mii.cbSize = sizeof(mii);
627 mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE
628 | MIIM_SUBMENU | MIIM_TYPE | MIIM_BITMAP;
629
630 GetMenuItemInfoW(hWindowMenu, i, TRUE, &mii);
631 if(mii.cch) { /* Menu is MFT_STRING */
632 mii.cch++; /* add room for '\0' */
633 buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
634 mii.cch * sizeof(WCHAR));
635 mii.dwTypeData = buffer;
636 GetMenuItemInfoW(hWindowMenu, i, TRUE, &mii);
637 }
638 DeleteMenu(hWindowMenu, i, MF_BYPOSITION);
639 InsertMenuItemW(hmenuWindow, pos, TRUE, &mii);
640 if(buffer) {
641 HeapFree(GetProcessHeap(), 0, buffer);
642 buffer = NULL;
643 }
644 }
645 }
646#endif
647 /* remove separator */
648 DeleteMenu(hWindowMenu, i, MF_BYPOSITION);
649
650 hWindowMenu = hmenuWindow;
651 }
652
653 if (hmenuFrame)
654 {
655 ::SetMenu(hwndFrame, hmenuFrame);
656
657 if( hmenuFrame!=oldFrameMenu )
658 {
659 if (maximizedChild)
660 augmentFrameMenu(maximizedChild);
661
662 return oldFrameMenu;
663 }
664 }
665 else
666 {
667 INT nItems = GetMenuItemCount(oldFrameMenu) - 1;
668 UINT iId = GetMenuItemID(oldFrameMenu,nItems) ;
669
670 if( !(iId == SC_RESTORE || iId == SC_CLOSE) )
671 {
672 /* SetMenu() may already have been called, meaning that this window
673 * already has its menu. But they may have done a SetMenu() on
674 * an MDI window, and called MDISetMenu() after the fact, meaning
675 * that the "if" to this "else" wouldn't catch the need to
676 * augment the frame menu.
677 */
678 if( maximizedChild )
679 augmentFrameMenu(maximizedChild);
680 }
681 }
682 return 0;
683}
684
685/**********************************************************************
686 * MDIRefreshMenu
687 */
688LRESULT Win32MDIClientWindow::refreshMDIMenu(HMENU hmenuFrame, HMENU hmenuWindow)
689{
690 HMENU oldFrameMenu = getParent()->GetMenu();
691
692// FIXME("partially function stub\n");
693
694 return oldFrameMenu;
695}
696/**********************************************************************
697 * MDI_RestoreFrameMenu
698 */
699BOOL Win32MDIClientWindow::restoreFrameMenu(Win32BaseWindow *child)
700{
701 MENUITEMINFOA menuInfo;
702 INT nItems = GetMenuItemCount(getParent()->GetMenu()) - 1;
703 UINT iId = GetMenuItemID(getParent()->GetMenu(),nItems) ;
704
705 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
706 return 0;
707
708 /*
709 * Remove the system menu, If that menu is the icon of the window
710 * as it is in win95, we have to delete the bitmap.
711 */
712 menuInfo.cbSize = sizeof(MENUITEMINFOA);
713 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
714
715 GetMenuItemInfoA(getParent()->GetMenu(),
716 0,
717 TRUE,
718 &menuInfo);
719
720 RemoveMenu(getParent()->GetMenu(),0,MF_BYPOSITION);
721
722//TODO: See augmentframemenu
723#if 0
724 if ((menuInfo.fType & MFT_BITMAP) &&
725 (LOWORD(menuInfo.dwTypeData)!=0) &&
726 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
727 {
728 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
729 }
730#endif
731
732 /* close */
733 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
734
735 /* restore */
736 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
737 /* minimize */
738 DeleteMenu(getParent()->GetMenu(),GetMenuItemCount(getParent()->GetMenu()) - 1,MF_BYPOSITION);
739
740 DrawMenuBar(getParent()->getWindowHandle());
741
742 return 1;
743}
744
745Win32BaseWindow** Win32MDIClientWindow::buildWindowArray(UINT bwaFlags,PUINT total)
746{
747 Win32BaseWindow **list = NULL,*win32wnd,**pos;
748 UINT skipHidden;
749 DWORD skipFlags;
750
751 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
752 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
753 if (bwaFlags & BWA_SKIPICONIC) skipFlags |= WS_MINIMIZE;
754
755 /* First count the windows */
756 *total = 0;
757 win32wnd = (Win32BaseWindow*)this->getFirstChild();
758 while (win32wnd)
759 {
760 if (!(win32wnd->getStyle() & skipFlags) && (!skipHidden || (win32wnd->getStyle() & WS_VISIBLE)))
761 (*total)++;
762 win32wnd = (Win32BaseWindow*)win32wnd->getNextChild();
763 }
764
765 if (*total)
766 {
767 /* Now build the list of all windows */
768 list = (Win32BaseWindow**)HeapAlloc(GetProcessHeap(),0,sizeof(Win32BaseWindow*)*(*total+1));
769 if (list)
770 {
771 for (win32wnd = (Win32BaseWindow*)this->getFirstChild(),pos = list;win32wnd;win32wnd = (Win32BaseWindow*)win32wnd->getNextChild())
772 {
773 if ((win32wnd->getStyle() & skipFlags));
774 else if(!skipHidden || win32wnd->getStyle() & WS_VISIBLE)
775 *pos++ = win32wnd;
776 }
777 *pos = NULL;
778 }
779 }
780
781 return list;
782}
783
784void Win32MDIClientWindow::releaseWindowArray(Win32BaseWindow **wndArray)
785{
786 HeapFree(GetProcessHeap(),0,wndArray);
787}
788
789/**********************************************************************
790 * MDI_CalcDefaultChildPos
791 *
792 * It seems that the default height is about 2/3 of the client rect
793 */
794void Win32MDIClientWindow::calcDefaultChildPos(WORD n,LPPOINT lpPos,INT delta)
795{
796 INT nstagger;
797 RECT rect;
798 INT spacing = GetSystemMetrics(SM_CYCAPTION) +
799 GetSystemMetrics(SM_CYFRAME) - 1;
800
801 getClientRect(&rect);
802 if( rect.bottom - rect.top - delta >= spacing )
803 rect.bottom -= delta;
804
805 nstagger = (rect.bottom - rect.top)/(3 * spacing);
806 lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
807 lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
808 lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
809}
810
811/**********************************************************************
812 * MDICascade
813 */
814BOOL Win32MDIClientWindow::cascade(UINT fuCascade)
815{
816 Win32BaseWindow **list;
817 UINT total = 0;
818
819 if (getMaximizedChild())
820 SendInternalMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild(), 0);
821
822 if (nActiveChildren == 0) return 0;
823
824 list = buildWindowArray(BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC,&total);
825 if (list)
826 {
827 Win32BaseWindow** heapPtr = list;
828 if (total)
829 {
830 INT delta = 0,n = 0;
831 POINT pos[2];
832
833
834 if (total < nActiveChildren)
835 delta = GetSystemMetrics(SM_CYICONSPACING)+GetSystemMetrics(SM_CYICON);
836
837 // walk the list (backwards) and move windows
838 while (*list) list++;
839 while (list != heapPtr)
840 {
841 list--;
842
843 calcDefaultChildPos(n++,pos,delta);
844 ::SetWindowPos((*list)->getWindowHandle(),0,pos[0].x,pos[0].y,pos[1].x,pos[1].y,SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
845 }
846 }
847 releaseWindowArray(heapPtr);
848 }
849
850 if (total < nActiveChildren)
851 ArrangeIconicWindows(Win32Hwnd);
852
853 return TRUE;
854}
855
856/**********************************************************************
857 * MDITile
858 */
859BOOL Win32MDIClientWindow::tile(UINT fuTile)
860{
861 Win32BaseWindow** list;
862 UINT total = 0;
863
864 if (getMaximizedChild())
865 SendInternalMessageA(WM_MDIRESTORE, (WPARAM)getMaximizedChild(), 0);
866
867 if (nActiveChildren == 0) return TRUE;
868
869 list = buildWindowArray(BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
870 ((fuTile & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
871
872 if (list)
873 {
874 Win32BaseWindow** heapPtr = list;
875
876 if (total)
877 {
878 RECT rect;
879 int x, y, xsize, ysize;
880 int rows, columns, r, c, i;
881
882 GetClientRect(Win32Hwnd,&rect);
883 rows = (int) sqrt((double)total);
884 columns = total / rows;
885
886 if( fuTile & MDITILE_HORIZONTAL ) // version >= 3.1
887 {
888 i = rows;
889 rows = columns; // exchange r and c
890 columns = i;
891 }
892
893 if( total != nActiveChildren)
894 {
895 y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
896 rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
897 }
898
899 ysize = rect.bottom / rows;
900 xsize = rect.right / columns;
901
902 for (x = i = 0, c = 1; c <= columns && *list; c++)
903 {
904 if (c == columns)
905 {
906 rows = total - i;
907 ysize = rect.bottom / rows;
908 }
909
910 y = 0;
911 for (r = 1; r <= rows && *list; r++, i++)
912 {
913 ::SetWindowPos((*list)->getWindowHandle(), 0, x, y, xsize, ysize,
914 SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
915 y += ysize;
916 list++;
917 }
918 x += xsize;
919 }
920 }
921 releaseWindowArray(heapPtr);
922 }
923
924 if( total < nActiveChildren ) ArrangeIconicWindows(Win32Hwnd);
925
926 return TRUE;
927}
928
929/* ----------------------- Frame window ---------------------------- */
930
931/**********************************************************************
932 * MDI_AugmentFrameMenu
933 */
934BOOL Win32MDIClientWindow::augmentFrameMenu(HWND hwndChild)
935{
936 Win32MDIChildWindow *child = (Win32MDIChildWindow *)GetWindowFromHandle(hwndChild);
937 HMENU hSysPopup = 0,hFrameMenu = ::GetMenu(getParent()->getWindowHandle()),hSysMenu = ::GetSystemMenu(child->getWindowHandle(),FALSE);
938 HBITMAP hSysMenuBitmap = 0;
939
940 if (!hFrameMenu || !hSysMenu) {
941 RELEASE_WNDOBJ(child);
942 return 0;
943 }
944 // create a copy of sysmenu popup and insert it into frame menu bar
945
946 if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU"))) {
947 RELEASE_WNDOBJ(child);
948 return 0;
949 }
950
951 //TRACE("\tgot popup %04x in sysmenu %04x\n",
952 // hSysPopup, child->hSysMenu);
953
954 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
955 SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
956 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
957 SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
958
959 // In Win 95 look, the system menu is replaced by the child icon
960
961 /* Find icon */
962 HICON hIcon = child->IconForWindow(ICON_SMALL);
963
964 if (hIcon)
965 {
966 HDC hMemDC;
967 HBITMAP hBitmap, hOldBitmap;
968 HBRUSH hBrush;
969 HDC hdc = GetDC(child->getWindowHandle());
970
971 if (hdc)
972 {
973 int cx, cy;
974
975 cx = GetSystemMetrics(SM_CXSMICON);
976 cy = GetSystemMetrics(SM_CYSMICON);
977 hMemDC = CreateCompatibleDC(hdc);
978 hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
979 hOldBitmap = SelectObject(hMemDC, hBitmap);
980 SetMapMode(hMemDC, MM_TEXT);
981 hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
982 DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
983 SelectObject (hMemDC, hOldBitmap);
984 DeleteObject(hBrush);
985 DeleteDC(hMemDC);
986 ReleaseDC(child->getWindowHandle(), hdc);
987 hSysMenuBitmap = hBitmap;
988 }
989 }
990 RELEASE_WNDOBJ(child);
991
992 if( !InsertMenuA(hFrameMenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
993 hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
994 {
995 //TRACE("not inserted\n");
996 DestroyMenu(hSysPopup);
997 return 0;
998 }
999
1000 // The close button is only present in Win 95 look
1001
1002 AppendMenuA(hFrameMenu,MF_HELP | MF_BITMAP,
1003 SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
1004
1005 EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
1006 EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
1007 EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
1008 SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
1009
1010 // redraw menu
1011 DrawMenuBar(getParent()->getWindowHandle());
1012
1013 return 1;
1014}
1015
1016/**********************************************************************
1017 * MDI_RestoreFrameMenu
1018 */
1019BOOL Win32MDIClientWindow::restoreFrameMenu(HWND hwndChild)
1020{
1021 MENUITEMINFOA menuInfo;
1022 HMENU hFrameMenu = ::GetMenu(getParent()->getWindowHandle());
1023 INT nItems = GetMenuItemCount(hFrameMenu) - 1;
1024 UINT iId = GetMenuItemID(hFrameMenu,nItems) ;
1025
1026 //TRACE("frameWnd %p,child %04x\n",frameWnd,hChild);
1027
1028 if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
1029 return 0;
1030
1031 /*
1032 * Remove the system menu, If that menu is the icon of the window
1033 * as it is in win95, we have to delete the bitmap.
1034 */
1035
1036 menuInfo.cbSize = sizeof(MENUITEMINFOA);
1037 menuInfo.fMask = MIIM_DATA | MIIM_TYPE;
1038
1039 GetMenuItemInfoA(hFrameMenu,
1040 0,
1041 TRUE,
1042 &menuInfo);
1043
1044 RemoveMenu(hFrameMenu,0,MF_BYPOSITION);
1045
1046#if 0 //CB: hBmpClose not (yet) defined
1047 if ( (menuInfo.fType & MFT_BITMAP) &&
1048 (LOWORD(menuInfo.dwTypeData)!=0) &&
1049 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
1050 {
1051 DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
1052 }
1053#endif
1054
1055 // close
1056 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1057
1058 // restore
1059 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1060 // minimize
1061 DeleteMenu(hFrameMenu,GetMenuItemCount(hFrameMenu) - 1,MF_BYPOSITION);
1062
1063 DrawMenuBar(getParent()->getWindowHandle());
1064
1065 return 1;
1066}
1067
1068/***********************************************************************
1069 * CalcChildScroll (USER.462)
1070 */
1071void WINAPI CalcChildScroll(HWND hwnd,WORD scroll)
1072{
1073 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1074 Win32BaseWindow *child;
1075 SCROLLINFO info;
1076 RECT childRect, clientRect;
1077 INT vmin, vmax, hmin, hmax, vpos, hpos;
1078
1079 if (!win32wnd) return;
1080
1081 GetClientRect( hwnd, &clientRect );
1082 SetRectEmpty( &childRect );
1083
1084 //TODO: Check if this goes correctly
1085 win32wnd->lock();
1086 for (child = (Win32BaseWindow*)win32wnd->getFirstChild();child;child = (Win32BaseWindow*)child->getNextChild())
1087 {
1088 if( child->getStyle() & WS_MAXIMIZE )
1089 {
1090 win32wnd->unlock();
1091 RELEASE_WNDOBJ(win32wnd);
1092 ShowScrollBar(hwnd, SB_BOTH, FALSE);
1093 return;
1094 }
1095 UnionRect(&childRect,child->getWindowRect(),&childRect);
1096 }
1097 win32wnd->unlock();
1098 RELEASE_WNDOBJ(win32wnd);
1099
1100 UnionRect( &childRect, &clientRect, &childRect );
1101
1102 hmin = childRect.left; hmax = childRect.right - clientRect.right;
1103 hpos = clientRect.left - childRect.left;
1104 vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
1105 vpos = clientRect.top - childRect.top;
1106
1107 switch( scroll )
1108 {
1109 case SB_HORZ:
1110 vpos = hpos; vmin = hmin; vmax = hmax;
1111 case SB_VERT:
1112 info.cbSize = sizeof(info);
1113 info.nMax = vmax; info.nMin = vmin; info.nPos = vpos;
1114 info.fMask = SIF_POS | SIF_RANGE;
1115 SetScrollInfo(hwnd, scroll, &info, TRUE);
1116 break;
1117 case SB_BOTH:
1118 {
1119 SCROLLINFO vInfo, hInfo;
1120
1121 vInfo.cbSize = hInfo.cbSize = sizeof(SCROLLINFO);
1122 vInfo.nMin = vmin;
1123 hInfo.nMin = hmin;
1124 vInfo.nMax = vmax;
1125 hInfo.nMax = hmax;
1126 vInfo.nPos = vpos;
1127 hInfo.nPos = hpos;
1128 vInfo.fMask = hInfo.fMask = SIF_RANGE | SIF_POS;
1129
1130 SetScrollInfo(hwnd,SB_VERT,&vInfo,TRUE);
1131 SetScrollInfo(hwnd,SB_HORZ,&hInfo,TRUE);
1132 }
1133 }
1134}
1135
1136/***********************************************************************
1137 * ScrollChildren32 (USER32.448)
1138 */
1139void WINAPI ScrollChildren(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
1140{
1141 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hWnd);
1142 INT newPos = -1;
1143 INT curPos, length, minPos, maxPos, shift;
1144
1145 if (!win32wnd) return;
1146
1147 if (uMsg == WM_HSCROLL)
1148 {
1149 GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
1150 curPos = GetScrollPos(hWnd,SB_HORZ);
1151 length = win32wnd->getClientWidth()/2;
1152 shift = GetSystemMetrics(SM_CYHSCROLL);
1153 }
1154 else if (uMsg == WM_VSCROLL)
1155 {
1156 GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
1157 curPos = GetScrollPos(hWnd,SB_VERT);
1158 length = win32wnd->getClientHeight()/2;
1159 shift = GetSystemMetrics(SM_CXVSCROLL);
1160 }
1161 else
1162 {
1163 RELEASE_WNDOBJ(win32wnd);
1164 return;
1165 }
1166 RELEASE_WNDOBJ(win32wnd);
1167
1168 switch( wParam )
1169 {
1170 case SB_LINEUP:
1171 newPos = curPos - shift;
1172 break;
1173
1174 case SB_LINEDOWN:
1175 newPos = curPos + shift;
1176 break;
1177
1178 case SB_PAGEUP:
1179 newPos = curPos - length;
1180 break;
1181
1182 case SB_PAGEDOWN:
1183 newPos = curPos + length;
1184 break;
1185
1186 case SB_THUMBPOSITION:
1187 newPos = LOWORD(lParam);
1188 break;
1189
1190 case SB_THUMBTRACK:
1191 return;
1192
1193 case SB_TOP:
1194 newPos = minPos;
1195 break;
1196
1197 case SB_BOTTOM:
1198 newPos = maxPos;
1199 break;
1200
1201 case SB_ENDSCROLL:
1202 CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
1203 return;
1204 }
1205
1206 if( newPos > maxPos )
1207 newPos = maxPos;
1208 else
1209 if( newPos < minPos )
1210 newPos = minPos;
1211
1212 SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
1213
1214 if( uMsg == WM_VSCROLL )
1215 ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL,
1216 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
1217 else
1218 ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
1219 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
1220}
1221
1222/*****************************************************************************
1223 * Name : WORD WIN32API CascadeWindows
1224 * Purpose : The CascadeWindows function cascades the specified windows or
1225 * the child windows of the specified parent window.
1226 * Parameters: HWND hwndParent handle of parent window
1227 * UINT wHow types of windows not to arrange
1228 * CONST RECT * lpRect rectangle to arrange windows in
1229 * UINT cKids number of windows to arrange
1230 * const HWND FAR * lpKids array of window handles
1231 * Variables :
1232 * Result : If the function succeeds, the return value is the number of windows arranged.
1233 * If the function fails, the return value is zero.
1234 * Remark :
1235 * Status : UNTESTED STUB
1236 *
1237 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1238 *****************************************************************************/
1239WORD WIN32API CascadeWindows(HWND hwndParent,
1240 UINT wHow,
1241 CONST LPRECT lpRect,
1242 UINT cKids,
1243 const HWND *lpKids)
1244{
1245 dprintf(("USER32:CascadeWindows(%08xh,%u,%08xh,%u,%08x) not implemented.\n",
1246 hwndParent,
1247 wHow,
1248 lpRect,
1249 cKids,
1250 lpKids));
1251
1252 return (0);
1253}
1254
1255/*****************************************************************************
1256 * Name : BOOL WIN32API CascadeChildWindows
1257 * Purpose : Unknown
1258 * Parameters: Unknown
1259 * Variables :
1260 * Result :
1261 * Remark :
1262 * Status : UNTESTED UNKNOWN STUB
1263 *
1264 * Author : Patrick Haller [Wed, 1998/06/16 11:55]
1265 *****************************************************************************/
1266BOOL WIN32API CascadeChildWindows(DWORD x1,
1267 DWORD x2)
1268{
1269 dprintf(("USER32: CascadeChildWindows(%08xh,%08xh) not implemented.\n",
1270 x1,
1271 x2));
1272
1273 return (FALSE); /* default */
1274}
1275
1276/*****************************************************************************
1277 * Name : WORD WIN32API TileWindows
1278 * Purpose : The TileWindows function tiles the specified windows, or the child
1279 * windows of the specified parent window.
1280 * Parameters: HWND hwndParent handle of parent window
1281 * WORD wFlags types of windows not to arrange
1282 * LPCRECT lpRect rectangle to arrange windows in
1283 * WORD cChildrenb number of windows to arrange
1284 * const HWND *ahwndChildren array of window handles
1285 * Variables :
1286 * Result : If the function succeeds, the return value is the number of
1287 * windows arranged.
1288 * If the function fails, the return value is zero.
1289 * Remark :
1290 * Status : UNTESTED STUB
1291 *
1292 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1293 *****************************************************************************/
1294WORD WIN32API TileWindows(HWND hwndParent,
1295 UINT wFlags,
1296 const LPRECT lpRect,
1297 UINT cChildrenb,
1298 const HWND *ahwndChildren)
1299{
1300 dprintf(("USER32:TileWindows (%08xh,%08xh,%08xh,%08xh,%08x) not implemented.\n",
1301 hwndParent,
1302 wFlags,
1303 lpRect,
1304 cChildrenb,
1305 ahwndChildren));
1306
1307 return (0);
1308}
1309
1310/*****************************************************************************
1311 * Name : BOOL WIN32API TileChildWindows
1312 * Purpose : Unknown
1313 * Parameters: Unknown
1314 * Variables :
1315 * Result :
1316 * Remark :
1317 * Status : UNTESTED UNKNOWN STUB
1318 *
1319 * Author : Patrick Haller [Wed, 1998/06/16 11:55]
1320 *****************************************************************************/
1321BOOL WIN32API TileChildWindows(DWORD x1,
1322 DWORD x2)
1323{
1324 dprintf(("USER32: TileChildWindows(%08xh,%08xh) not implemented.\n",
1325 x1,
1326 x2));
1327
1328 return (FALSE); /* default */
1329}
1330
1331/* -------- Miscellaneous service functions ---------- */
1332
1333void Win32MDIClientWindow::postUpdate(WORD recalc)
1334{
1335 if( !(mdiFlags & MDIF_NEEDUPDATE) )
1336 {
1337 mdiFlags |= MDIF_NEEDUPDATE;
1338 PostMessageA(getWindowHandle(), WM_MDICALCCHILDSCROLL, 0, 0);
1339 }
1340 sbRecalc = recalc;
1341}
1342//******************************************************************************
1343//******************************************************************************
1344BOOL MDICLIENT_Register()
1345{
1346 WNDCLASSA wndClass;
1347
1348//SvL: Don't check this now
1349// if (GlobalFindAtomA(MDICLIENTCLASSNAMEA)) return FALSE;
1350
1351 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
1352 wndClass.style = CS_GLOBALCLASS;
1353 wndClass.lpfnWndProc = (WNDPROC)MDIClientWndProc;
1354 wndClass.cbClsExtra = 0;
1355 wndClass.cbWndExtra = 0;
1356 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);;
1357 wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
1358 wndClass.lpszClassName = MDICLIENTCLASSNAMEA;
1359
1360 return RegisterClassA(&wndClass);
1361}
1362//******************************************************************************
1363//******************************************************************************
1364BOOL MDICLIENT_Unregister()
1365{
1366 if (GlobalFindAtomA(MDICLIENTCLASSNAMEA))
1367 return UnregisterClassA(MDICLIENTCLASSNAMEA,(HINSTANCE)NULL);
1368 else return FALSE;
1369}
1370//******************************************************************************
1371//******************************************************************************
Note: See TracBrowser for help on using the repository browser.