3 * Copyright 1994, Bob Amstadt
5 * This file contains routines to support MDI features.
12 #include "nonclient.h"
16 #include "sysmetrics.h"
18 /* #define DEBUG_MDI */
21 /**********************************************************************
24 void MDIRecreateMenuList(MDICLIENTINFO
*ci
)
31 dprintf_mdi(stddeb
, "MDIRecreateMenuList: hWindowMenu %0x\n",
34 id
= ci
->idFirstChild
;
35 while (DeleteMenu(ci
->hWindowMenu
, id
, MF_BYCOMMAND
))
38 dprintf_mdi(stddeb
, "MDIRecreateMenuList: id %04x, idFirstChild %04x\n",
39 id
, ci
->idFirstChild
);
41 if (!ci
->flagMenuAltered
)
43 ci
->flagMenuAltered
= TRUE
;
44 AppendMenu(ci
->hWindowMenu
, MF_SEPARATOR
, 0, NULL
);
47 id
= ci
->idFirstChild
;
49 for (hinfo
= ci
->infoActiveChildren
; hinfo
!= 0;)
51 MDICHILDINFO
*chi
= USER_HEAP_LIN_ADDR(hinfo
);
53 n
= sprintf(buffer
, "%d ", index
++);
54 GetWindowText(chi
->hwnd
, buffer
+ n
, sizeof(buffer
) - n
- 1);
56 dprintf_mdi(stddeb
, "MDIRecreateMenuList: id %04x, '%s'\n",
59 AppendMenu(ci
->hWindowMenu
, MF_STRING
, id
++, buffer
);
65 /**********************************************************************
68 WORD
MDIIconArrange(HWND parent
)
70 return ArrangeIconicWindows(parent
); /* Any reason why the */
71 /* existing icon arrange */
72 /* can't be used here? */
76 /**********************************************************************
79 HWND
MDICreateChild(WND
*w
, MDICLIENTINFO
*ci
, HWND parent
, LPARAM lParam
)
81 MDICREATESTRUCT
*cs
= (MDICREATESTRUCT
*)PTR_SEG_TO_LIN(lParam
);
88 cs
->style
&= (WS_MINIMIZE
| WS_MAXIMIZE
| WS_HSCROLL
| WS_VSCROLL
);
90 /* The child windows should probably */
91 /* stagger, shouldn't they? -DRP */
92 spacing
= GetSystemMetrics(SM_CYCAPTION
) + GetSystemMetrics(SM_CYFRAME
);
93 cs
->x
= ci
->nActiveChildren
* spacing
;
94 cs
->y
= ci
->nActiveChildren
* spacing
;
96 hwnd
= CreateWindowEx(0, PTR_SEG_TO_LIN(cs
->szClass
),
97 PTR_SEG_TO_LIN(cs
->szTitle
),
98 WS_CHILD
| WS_BORDER
| WS_CAPTION
| WS_CLIPSIBLINGS
|
99 WS_MAXIMIZEBOX
| WS_MINIMIZEBOX
| WS_SYSMENU
|
100 WS_THICKFRAME
| WS_VISIBLE
| cs
->style
,
101 cs
->x
, cs
->y
, cs
->cx
, cs
->cy
, parent
, (HMENU
) 0,
102 w
->hInstance
, lParam
);
106 HANDLE h
= USER_HEAP_ALLOC( sizeof(MDICHILDINFO
) );
107 MDICHILDINFO
*child_info
= USER_HEAP_LIN_ADDR(h
);
115 ci
->nActiveChildren
++;
117 child_info
->next
= ci
->infoActiveChildren
;
118 child_info
->prev
= 0;
119 child_info
->hwnd
= hwnd
;
121 if (ci
->infoActiveChildren
) {
122 MDICHILDINFO
*nextinfo
= USER_HEAP_LIN_ADDR(ci
->infoActiveChildren
);
126 ci
->infoActiveChildren
= h
;
128 SendMessage(parent
, WM_CHILDACTIVATE
, 0, 0);
134 /**********************************************************************
137 HWND
MDIDestroyChild(WND
*w_parent
, MDICLIENTINFO
*ci
, HWND parent
,
138 HWND child
, BOOL flagDestroy
)
143 hinfo
= ci
->infoActiveChildren
;
145 chi
= (MDICHILDINFO
*)USER_HEAP_LIN_ADDR(hinfo
);
146 if (chi
->hwnd
== child
) break;
153 ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(chi
->prev
))->next
= chi
->next
;
155 ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(chi
->next
))->prev
= chi
->prev
;
156 if (ci
->infoActiveChildren
== hinfo
)
157 ci
->infoActiveChildren
= chi
->next
;
159 ci
->nActiveChildren
--;
161 if (chi
->hwnd
== ci
->hwndActiveChild
)
162 SendMessage(parent
, WM_CHILDACTIVATE
, 0, 0);
164 USER_HEAP_FREE(hinfo
);
167 DestroyWindow(child
);
173 /**********************************************************************
176 void MDIBringChildToTop(HWND parent
, WORD id
, WORD by_id
, BOOL send_to_bottom
)
184 w
= WIN_FindWndPtr(parent
);
185 ci
= (MDICLIENTINFO
*) w
->wExtra
;
187 dprintf_mdi(stddeb
, "MDIBringToTop: id %04x, by_id %d\n", id
, by_id
);
190 id
-= ci
->idFirstChild
;
191 if (!by_id
|| id
< ci
->nActiveChildren
)
193 hinfo
= ci
->infoActiveChildren
;
197 for (i
= 0; i
< id
; i
++)
198 hinfo
= ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(hinfo
))->next
;
199 chi
= USER_HEAP_LIN_ADDR(hinfo
);
204 chi
= (MDICHILDINFO
*)USER_HEAP_LIN_ADDR(hinfo
);
205 if (chi
->hwnd
== id
) break;
213 dprintf_mdi(stddeb
, "MDIBringToTop: child %04x\n", chi
->hwnd
);
214 if (hinfo
!= ci
->infoActiveChildren
)
216 if (ci
->flagChildMaximized
)
218 RECT rectOldRestore
, rect
;
220 w
= WIN_FindWndPtr(chi
->hwnd
);
222 rectOldRestore
= ci
->rectRestore
;
223 GetWindowRect(chi
->hwnd
, &ci
->rectRestore
);
225 rect
.top
= (ci
->rectMaximize
.top
-
226 (w
->rectClient
.top
- w
->rectWindow
.top
));
227 rect
.bottom
= (ci
->rectMaximize
.bottom
+
228 (w
->rectWindow
.bottom
- w
->rectClient
.bottom
));
229 rect
.left
= (ci
->rectMaximize
.left
-
230 (w
->rectClient
.left
- w
->rectWindow
.left
));
231 rect
.right
= (ci
->rectMaximize
.right
+
232 (w
->rectWindow
.right
- w
->rectClient
.right
));
233 w
->dwStyle
|= WS_MAXIMIZE
;
234 SetWindowPos(chi
->hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
235 rect
.right
- rect
.left
+ 1,
236 rect
.bottom
- rect
.top
+ 1, 0);
237 SendMessage(chi
->hwnd
, WM_SIZE
, SIZE_MAXIMIZED
,
238 MAKELONG(w
->rectClient
.right
-w
->rectClient
.left
,
239 w
->rectClient
.bottom
-w
->rectClient
.top
));
241 w
= WIN_FindWndPtr(ci
->hwndActiveChild
);
242 w
->dwStyle
&= ~WS_MAXIMIZE
;
243 SetWindowPos(ci
->hwndActiveChild
, HWND_BOTTOM
,
244 rectOldRestore
.left
, rectOldRestore
.top
,
245 rectOldRestore
.right
- rectOldRestore
.left
+ 1,
246 rectOldRestore
.bottom
- rectOldRestore
.top
+ 1,
248 (send_to_bottom
? 0 : SWP_NOZORDER
));
252 SetWindowPos(chi
->hwnd
, HWND_TOP
, 0, 0, 0, 0,
253 SWP_NOMOVE
| SWP_NOSIZE
);
256 SetWindowPos(ci
->hwndActiveChild
, HWND_BOTTOM
, 0, 0, 0, 0,
257 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
262 ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(chi
->next
))->prev
= chi
->prev
;
265 ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(chi
->prev
))->next
= chi
->next
;
268 chi
->next
= ci
->infoActiveChildren
;
269 ((MDICHILDINFO
*)USER_HEAP_LIN_ADDR(chi
->next
))->prev
= hinfo
;
270 ci
->infoActiveChildren
= hinfo
;
272 SendMessage(parent
, WM_CHILDACTIVATE
, 0, 0);
275 dprintf_mdi(stddeb
, "MDIBringToTop: pos %04x, hwnd %04x\n",
280 /**********************************************************************
283 LONG
MDIMaximizeChild(HWND parent
, HWND child
, MDICLIENTINFO
*ci
)
285 WND
*w
= WIN_FindWndPtr(child
);
288 MDIBringChildToTop(parent
, child
, FALSE
, FALSE
);
289 ci
->rectRestore
= w
->rectWindow
;
291 rect
.top
= (ci
->rectMaximize
.top
-
292 (w
->rectClient
.top
- w
->rectWindow
.top
));
293 rect
.bottom
= (ci
->rectMaximize
.bottom
+
294 (w
->rectWindow
.bottom
- w
->rectClient
.bottom
));
295 rect
.left
= (ci
->rectMaximize
.left
-
296 (w
->rectClient
.left
- w
->rectWindow
.left
));
297 rect
.right
= (ci
->rectMaximize
.right
+
298 (w
->rectWindow
.right
- w
->rectClient
.right
));
299 w
->dwStyle
|= WS_MAXIMIZE
;
300 SetWindowPos(child
, 0, rect
.left
, rect
.top
,
301 rect
.right
- rect
.left
+ 1, rect
.bottom
- rect
.top
+ 1,
302 SWP_NOACTIVATE
| SWP_NOZORDER
);
304 ci
->flagChildMaximized
= TRUE
;
306 SendMessage(child
, WM_SIZE
, SIZE_MAXIMIZED
,
307 MAKELONG(w
->rectClient
.right
-w
->rectClient
.left
,
308 w
->rectClient
.bottom
-w
->rectClient
.top
));
309 SendMessage(GetParent(parent
), WM_NCPAINT
, 0, 0);
314 /**********************************************************************
317 LONG
MDIRestoreChild(HWND parent
, MDICLIENTINFO
*ci
)
321 dprintf_mdi(stddeb
,"restoring mdi child\n");
323 child
= ci
->hwndActiveChild
;
324 ci
->flagChildMaximized
= FALSE
;
326 ShowWindow(child
, SW_RESTORE
); /* display the window */
327 MDIBringChildToTop(parent
, child
, FALSE
, FALSE
);
328 SendMessage(GetParent(parent
), WM_NCPAINT
, 0, 0);
333 /**********************************************************************
336 LONG
MDIChildActivated(WND
*w
, MDICLIENTINFO
*ci
, HWND parent
)
344 dprintf_mdi(stddeb
, "MDIChildActivate: top %04x\n", w
->hwndChild
);
346 hinfo
= ci
->infoActiveChildren
;
349 chi
= (MDICHILDINFO
*)USER_HEAP_LIN_ADDR(hinfo
);
350 deact_hwnd
= ci
->hwndActiveChild
;
351 act_hwnd
= chi
->hwnd
;
352 lParam
= ((LONG
) deact_hwnd
<< 16) | act_hwnd
;
354 dprintf_mdi(stddeb
, "MDIChildActivate: deact %04x, act %04x\n",
355 deact_hwnd
, act_hwnd
);
357 ci
->hwndActiveChild
= act_hwnd
;
359 if (deact_hwnd
!= act_hwnd
)
361 MDIRecreateMenuList(ci
);
362 SendMessage(deact_hwnd
, WM_NCACTIVATE
, FALSE
, 0);
363 SendMessage(deact_hwnd
, WM_MDIACTIVATE
, FALSE
, lParam
);
366 SendMessage(act_hwnd
, WM_NCACTIVATE
, TRUE
, 0);
367 SendMessage(act_hwnd
, WM_MDIACTIVATE
, TRUE
, lParam
);
370 if (hinfo
|| ci
->nActiveChildren
== 0)
372 MDIRecreateMenuList(ci
);
373 SendMessage(GetParent(parent
), WM_NCPAINT
, 0, 0);
379 /**********************************************************************
382 LONG
MDICascade(HWND parent
, MDICLIENTINFO
*ci
)
387 int spacing
, xsize
, ysize
;
390 if (ci
->flagChildMaximized
)
391 MDIRestoreChild(parent
, ci
);
393 /* If there aren't any children, don't even bother.
395 if (ci
->nActiveChildren
== 0)
398 GetClientRect(parent
, &rect
);
399 spacing
= GetSystemMetrics(SM_CYCAPTION
) + GetSystemMetrics(SM_CYFRAME
);
400 ysize
= rect
.bottom
- 8 * spacing
;
401 xsize
= rect
.right
- 8 * spacing
;
404 "MDICascade: Client wnd at (%d,%d) - (%d,%d), spacing %d\n",
405 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, spacing
);
406 dprintf_mdi(stddeb
, "MDICascade: searching for last child\n");
407 hinfo
= ci
->infoActiveChildren
;
409 chi
= USER_HEAP_LIN_ADDR(hinfo
);
410 if (chi
->next
== 0) break;
414 dprintf_mdi(stddeb
, "MDICascade: last child is %04x\n", chi
->hwnd
);
419 chi
= USER_HEAP_LIN_ADDR(hinfo
);
420 dprintf_mdi(stddeb
, "MDICascade: move %04x to (%d,%d) size [%d,%d]\n",
421 chi
->hwnd
, x
, y
, xsize
, ysize
);
422 if (IsIconic(chi
->hwnd
)) continue;
423 SetWindowPos(chi
->hwnd
, 0, x
, y
, xsize
, ysize
,
424 SWP_DRAWFRAME
| SWP_NOACTIVATE
| SWP_NOZORDER
);
435 /**********************************************************************
438 LONG
MDITile(HWND parent
, MDICLIENTINFO
*ci
)
449 if (ci
->flagChildMaximized
)
450 MDIRestoreChild(parent
, ci
);
452 /* If there aren't any children, don't even bother.
454 if (ci
->nActiveChildren
== 0)
457 GetClientRect(parent
, &rect
);
458 rows
= (int) sqrt((double) ci
->nActiveChildren
);
459 columns
= ci
->nActiveChildren
/ rows
;
460 ysize
= rect
.bottom
/ rows
;
461 xsize
= rect
.right
/ columns
;
463 hinfo
= ci
->infoActiveChildren
;
466 for (c
= 1; c
<= columns
; c
++)
470 rows
= ci
->nActiveChildren
- i
;
471 ysize
= rect
.bottom
/ rows
;
475 for (r
= 1; r
<= rows
; r
++, i
++)
477 chi
= (MDICHILDINFO
*)USER_HEAP_LIN_ADDR(hinfo
);
478 SetWindowPos(chi
->hwnd
, 0, x
, y
, xsize
, ysize
,
479 SWP_DRAWFRAME
| SWP_NOACTIVATE
| SWP_NOZORDER
);
492 /**********************************************************************
495 BOOL
MDIHandleLButton(HWND hwndFrame
, HWND hwndClient
,
496 WORD wParam
, LONG lParam
)
503 w
= WIN_FindWndPtr(hwndClient
);
504 ci
= (MDICLIENTINFO
*) w
->wExtra
;
506 if (wParam
== HTMENU
&& ci
->flagChildMaximized
)
510 NC_GetInsideRect(hwndFrame
, &rect
);
511 if (x
< rect
.left
+ SYSMETRICS_CXSIZE
)
513 SendMessage(ci
->hwndActiveChild
, WM_SYSCOMMAND
,
517 else if (x
>= rect
.right
- SYSMETRICS_CXSIZE
)
519 SendMessage(ci
->hwndActiveChild
, WM_SYSCOMMAND
,
528 /**********************************************************************
531 LONG
MDIPaintMaximized(HWND hwndFrame
, HWND hwndClient
, WORD message
,
532 WORD wParam
, LONG lParam
)
534 static HBITMAP hbitmapClose
= 0;
535 static HBITMAP hbitmapMaximized
= 0;
541 WND
*wndPtr
= WIN_FindWndPtr(hwndFrame
);
543 w
= WIN_FindWndPtr(hwndClient
);
544 ci
= (MDICLIENTINFO
*) w
->wExtra
;
546 dprintf_mdi(stddeb
, "MDIPaintMaximized: frame %04x, client %04x"
547 ", max flag %d, menu %04x\n", hwndFrame
, hwndClient
,
548 ci
->flagChildMaximized
, wndPtr
? wndPtr
->wIDmenu
: 0);
550 if (ci
->flagChildMaximized
&& wndPtr
&& wndPtr
->wIDmenu
!= 0)
552 NC_DoNCPaint(hwndFrame
, wParam
, TRUE
);
554 hdc
= GetDCEx(hwndFrame
, 0, DCX_CACHE
| DCX_WINDOW
);
557 hdcMem
= CreateCompatibleDC(hdc
);
559 if (hbitmapClose
== 0)
561 hbitmapClose
= LoadBitmap(0, MAKEINTRESOURCE(OBM_OLD_CLOSE
));
562 hbitmapMaximized
= LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE
));
566 "MDIPaintMaximized: hdcMem %04x, close bitmap %04x, "
567 "maximized bitmap %04x\n",
568 hdcMem
, hbitmapClose
, hbitmapMaximized
);
570 NC_GetInsideRect(hwndFrame
, &rect
);
571 rect
.top
+= (wndPtr
->dwStyle
& WS_CAPTION
) ? SYSMETRICS_CYSIZE
+ 1 : 0;
572 SelectObject(hdcMem
, hbitmapClose
);
573 BitBlt(hdc
, rect
.left
, rect
.top
+ 1,
574 SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
575 hdcMem
, 1, 1, SRCCOPY
);
577 NC_GetInsideRect(hwndFrame
, &rect
);
578 rect
.top
+= (wndPtr
->dwStyle
& WS_CAPTION
) ? SYSMETRICS_CYSIZE
+ 1 : 0;
579 rect
.left
= rect
.right
- SYSMETRICS_CXSIZE
;
580 SelectObject(hdcMem
, hbitmapMaximized
);
581 BitBlt(hdc
, rect
.left
, rect
.top
+ 1,
582 SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
583 hdcMem
, 1, 1, SRCCOPY
);
585 NC_GetInsideRect(hwndFrame
, &rect
);
586 rect
.top
+= (wndPtr
->dwStyle
& WS_CAPTION
) ? SYSMETRICS_CYSIZE
+ 1 : 0;
587 rect
.left
+= SYSMETRICS_CXSIZE
;
588 rect
.right
-= SYSMETRICS_CXSIZE
;
589 rect
.bottom
= rect
.top
+ SYSMETRICS_CYMENU
;
591 MENU_DrawMenuBar(hdc
, &rect
, hwndFrame
, FALSE
);
594 ReleaseDC(hwndFrame
, hdc
);
597 return DefWindowProc(hwndFrame
, message
, wParam
, lParam
);
602 /**********************************************************************
605 * This function is the handler for all MDI requests.
607 LONG
MDIClientWndProc(HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
610 LPCLIENTCREATESTRUCT ccs
;
614 w
= WIN_FindWndPtr(hwnd
);
615 ci
= (MDICLIENTINFO
*) w
->wExtra
;
619 case WM_CHILDACTIVATE
:
620 return MDIChildActivated(w
, ci
, hwnd
);
623 cs
= (LPCREATESTRUCT
) PTR_SEG_TO_LIN(lParam
);
624 ccs
= (LPCLIENTCREATESTRUCT
) PTR_SEG_TO_LIN(cs
->lpCreateParams
);
625 ci
->hWindowMenu
= ccs
->hWindowMenu
;
626 ci
->idFirstChild
= ccs
->idFirstChild
;
627 ci
->infoActiveChildren
= 0;
628 ci
->flagMenuAltered
= FALSE
;
629 ci
->flagChildMaximized
= FALSE
;
630 w
->dwStyle
|= WS_CLIPCHILDREN
;
632 GetClientRect(w
->hwndParent
, &ci
->rectMaximize
);
633 MoveWindow(hwnd
, 0, 0,
634 ci
->rectMaximize
.right
, ci
->rectMaximize
.bottom
, 1);
639 MDIBringChildToTop(hwnd
, wParam
, FALSE
, FALSE
);
643 return MDICascade(hwnd
, ci
);
646 return MDICreateChild(w
, ci
, hwnd
, lParam
);
649 return MDIDestroyChild(w
, ci
, hwnd
, wParam
, TRUE
);
651 case WM_MDIGETACTIVE
:
652 return ((LONG
) ci
->hwndActiveChild
|
653 ((LONG
) ci
->flagChildMaximized
<< 16));
655 case WM_MDIICONARRANGE
:
656 return MDIIconArrange(hwnd
);
659 return MDIMaximizeChild(hwnd
, wParam
, ci
);
662 MDIBringChildToTop(hwnd
, wParam
, FALSE
, TRUE
);
666 return MDIRestoreChild(hwnd
, ci
);
669 /* return MDISetMenu(...) */
673 return MDITile(hwnd
, ci
);
676 SendMessage(ci
->hwndActiveChild
, message
, wParam
, lParam
);
679 case WM_PARENTNOTIFY
:
680 if (wParam
== WM_DESTROY
)
681 return MDIDestroyChild(w
, ci
, hwnd
, LOWORD(lParam
), FALSE
);
682 else if (wParam
== WM_LBUTTONDOWN
)
683 MDIBringChildToTop(hwnd
, ci
->hwndHitTest
, FALSE
, FALSE
);
687 GetClientRect(w
->hwndParent
, &ci
->rectMaximize
);
692 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
695 /**********************************************************************
696 * DefFrameProc (USER.445)
699 LONG
DefFrameProc(HWND hwnd
, HWND hwndMDIClient
, WORD message
,
700 WORD wParam
, LONG lParam
)
707 MDIBringChildToTop(hwndMDIClient
, wParam
, TRUE
, FALSE
);
710 case WM_NCLBUTTONDOWN
:
711 if (MDIHandleLButton(hwnd
, hwndMDIClient
, wParam
, lParam
))
716 SendMessage(hwndMDIClient
, message
, wParam
, lParam
);
717 return MDIPaintMaximized(hwnd
, hwndMDIClient
,
718 message
, wParam
, lParam
);
721 return MDIPaintMaximized(hwnd
, hwndMDIClient
,
722 message
, wParam
, lParam
);
725 SendMessage(hwndMDIClient
, WM_SETFOCUS
, wParam
, lParam
);
729 MoveWindow(hwndMDIClient
, 0, 0,
730 LOWORD(lParam
), HIWORD(lParam
), TRUE
);
735 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
738 /**********************************************************************
739 * DefMDIChildProc (USER.447)
742 LONG
DefMDIChildProc(HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
747 w
= WIN_FindWndPtr(GetParent(hwnd
));
748 ci
= (MDICLIENTINFO
*) w
->wExtra
;
753 ci
->hwndHitTest
= hwnd
;
757 NC_DoNCPaint( hwnd
, hwnd
== ci
->hwndActiveChild
, FALSE
);
764 return SendMessage(GetParent(hwnd
), WM_MDIMAXIMIZE
, hwnd
, 0);
767 return SendMessage(GetParent(hwnd
), WM_MDIRESTORE
, hwnd
, 0);
773 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
776 /**********************************************************************
777 * TranslateMDISysAccel (USER.451)
780 BOOL
TranslateMDISysAccel(HWND hwndClient
, LPMSG msg
)
786 /***********************************************************************
787 * CalcChildScroll (USER.462)
789 void CalcChildScroll( HWND hwnd
, WORD scroll
)
791 RECT childRect
, clientRect
;
794 GetClientRect( hwnd
, &clientRect
);
795 SetRectEmpty( &childRect
);
796 hwndChild
= GetWindow( hwnd
, GW_CHILD
);
799 WND
*wndPtr
= WIN_FindWndPtr( hwndChild
);
800 UnionRect( &childRect
, &wndPtr
->rectWindow
, &childRect
);
801 hwndChild
= wndPtr
->hwndNext
;
803 UnionRect( &childRect
, &clientRect
, &childRect
);
805 if ((scroll
== SB_HORZ
) || (scroll
== SB_BOTH
))
807 SetScrollRange( hwnd
, SB_HORZ
, childRect
.left
,
808 childRect
.right
- clientRect
.right
, FALSE
);
809 SetScrollPos( hwnd
, SB_HORZ
, clientRect
.left
- childRect
.left
, TRUE
);
811 if ((scroll
== SB_VERT
) || (scroll
== SB_BOTH
))
813 SetScrollRange( hwnd
, SB_VERT
, childRect
.top
,
814 childRect
.bottom
- clientRect
.bottom
, FALSE
);
815 SetScrollPos( hwnd
, SB_HORZ
, clientRect
.top
- childRect
.top
, TRUE
);