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

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

minor update

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