2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 #include <afs/param.h>
17 #include <WINNT/al_resource.h> // To see if you have IDC_HSPLIT etc
18 #include <WINNT/resize.h>
19 #include <WINNT/subclass.h>
20 #include <WINNT/TaLocale.h>
24 * DEFINITIONS ________________________________________________________________
29 #define limit(_a,_x,_b) (min( max( (_a),(_x) ), (_b) ))
32 #define inlimit(_a,_x,_b) ( (_x >= _a) && (_x <= _b) )
36 #define THIS_HINST (GetModuleHandle (NULL))
44 #define cxRECT(_r) ((_r).right - (_r).left)
47 #define cyRECT(_r) ((_r).bottom - (_r).top)
50 typedef struct // SplitterData
52 LONG
*pcDelta
; // pointer to LONG to hold cx/yDelta
53 int idWnd1
; // first window to split between
54 int idWnd2
; // second window to split between
55 rwWindowData
*awd
; // data list for using splitter
56 BOOL fX
; // TRUE if moves in X, FALSE if in Y
57 BOOL fDragging
; // TRUE if dragging with the mouse
58 POINT ptStart
; // point at which started dragging
59 BOOL fMovedBeforeCreate
; // TRUE if windows moved before create
64 * VARIABLES __________________________________________________________________
74 rwWindowData
*awdLast
;
77 static WindowList
*awl
;
78 static size_t cwl
= 0;
82 * PROTOTYPES _________________________________________________________________
86 int rwFindOrAddWnd (HWND
, rwWindowData
* = 0);
87 void rwFindAndRemoveWnd (HWND
);
88 DWORD
rwFindAction (rwWindowData
*, int);
90 BOOL
WhereShouldSplitterGo (HWND
, int, int, RECT
*, BOOL
*);
91 void EnsureSplitterRegistered (void);
92 LONG APIENTRY
SplitterWndProc (HWND
, UINT
, WPARAM
, LPARAM
);
93 void ResizeSplitter (HWND
, SplitterData
*, LONG
, LONG
*);
94 void FindSplitterMinMax (HWND
, SplitterData
*, LONG
,
97 void FindResizeLimits (HWND hWnd
, LONG
*pcxMin
, LONG
*pcxMax
, LONG
*pcyMin
, LONG
*pcyMax
, rwWindowData
* = 0);
99 HRESULT CALLBACK
Resize_DialogProc (HWND hWnd
, UINT msg
, WPARAM wp
, LPARAM lp
);
103 * ROUTINES ___________________________________________________________________
108 #define REALLOC(_a,_c,_r,_i) ResizeReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
109 BOOL
ResizeReallocFunction (LPVOID
*ppTarget
, size_t cbElement
, size_t *pcTarget
, size_t cReq
, size_t cInc
)
114 if (cReq
<= *pcTarget
)
117 if ((cNew
= cInc
* ((cReq
+ cInc
-1) / cInc
)) <= 0)
120 if ((pNew
= (LPVOID
)Allocate (cbElement
* cNew
)) == NULL
)
122 memset (pNew
, 0x00, cbElement
* cNew
);
126 memcpy (pNew
, *ppTarget
, cbElement
* (*pcTarget
));
137 void ResizeWindow (HWND hWnd
, rwWindowData
*awd
, rwAction rwa
, RECT
*pr
)
139 static BOOL fInHere
= FALSE
; // prevent reentrancy during SetWindowPos().
146 // We maintain list of where-was-this-window-last-time; find
147 // This window in that list, or add it.
149 if ((ii
= rwFindOrAddWnd (hWnd
, awd
)) == -1)
152 rOld
= awl
[ii
].rWnd
; // previous position
154 // If the window disappears, then remove its entry from the
157 if (!IsWindow (hWnd
))
163 // If told to, move and/or resize this parent window.
165 if (rwa
== rwaMoveToHere
)
172 SetWindowPos (hWnd
, NULL
,
175 pr
->right
- pr
->left
,
176 pr
->bottom
- pr
->top
,
177 SWP_NOZORDER
| SWP_NOACTIVATE
);
185 GetWindowRect (hWnd
, &rNew
);
188 // Window has moved from {rOld} to {rNew},
190 // Window's client area has been changed by {*pr}
192 if (rwa
== rwaMoveToHere
|| rwa
== rwaFixupGuts
|| rwa
== rwaNewClientArea
)
197 if (rwa
== rwaNewClientArea
)
199 dx
= pr
->right
- pr
->left
;
200 dy
= pr
->bottom
- pr
->top
;
204 dx
= (rNew
.right
-rNew
.left
) - (rOld
.right
-rOld
.left
);
205 dy
= (rNew
.bottom
-rNew
.top
) - (rOld
.bottom
-rOld
.top
);
209 awl
[ii
].cxDeltaCenter
+= (dx
> 0) ? 1 : -1;
211 awl
[ii
].cyDeltaCenter
+= (dy
> 0) ? 1 : -1;
213 dxc
= dx
+ awl
[ii
].cxDeltaCenter
/2;
214 dyc
= dy
+ awl
[ii
].cyDeltaCenter
/2;
216 awl
[ii
].cxDeltaCenter
%= 2;
217 awl
[ii
].cyDeltaCenter
%= 2;
219 if (dx
!= 0 || dy
!= 0)
224 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
226 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
234 HDWP dwp
= BeginDeferWindowPos (nItems
);
235 BOOL fRepaint
= FALSE
;
237 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
239 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
243 GetRectInParent (hItem
, &rItem
);
245 ra
= rwFindAction (awd
, (GetWindowLong (hItem
, GWL_ID
)));
247 DeferWindowPos (dwp
, hItem
, NULL
,
248 rItem
.left
+ ((ra
& raMoveX
) ? dx
:
249 (ra
& raMoveXB
) ? (0-dx
) :
250 (ra
& raMoveXC
) ? (dxc
/2) : 0),
251 rItem
.top
+ ((ra
& raMoveY
) ? dy
:
252 (ra
& raMoveYB
) ? (0-dy
) :
253 (ra
& raMoveYC
) ? (dyc
/2) : 0),
254 rItem
.right
-rItem
.left
255 + ((ra
& raSizeX
) ? dx
:
256 (ra
& raSizeXB
) ? (0-dx
) :
257 (ra
& raSizeXC
) ? (dxc
/2) : 0),
258 rItem
.bottom
-rItem
.top
259 + ((ra
& raSizeY
) ? dy
:
260 (ra
& raSizeYB
) ? (0-dy
) :
261 (ra
& raSizeYC
) ? (dyc
/2) : 0),
262 SWP_NOACTIVATE
| SWP_NOZORDER
);
265 EndDeferWindowPos (dwp
);
267 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
269 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
271 ra
= rwFindAction (awd
, (GetWindowLong (hItem
, GWL_ID
)));
276 GetRectInParent (hItem
, &rItem
);
277 InvalidateRect (hWnd
, &rItem
, TRUE
);
284 GetClientRect (hItem
, &rClient
);
285 SendMessage (hItem
, WM_SIZE
, SIZE_RESTORED
, MAKELPARAM( rClient
.right
-rClient
.left
, rClient
.bottom
-rClient
.top
));
297 // Record this window's current position
306 int rwFindOrAddWnd (HWND hWnd
, rwWindowData
*awd
)
308 // Is the window handle listed in awl[] already?
311 for (ii
= 0; ii
< (int)cwl
; ii
++)
313 if (awl
[ii
].hWnd
== hWnd
)
316 awl
[ii
].awdLast
= awd
;
323 for (ii
= 0; ii
< (int)cwl
; ii
++)
325 if (awl
[ii
].hWnd
== NULL
)
330 if (!REALLOC (awl
, cwl
, ii
+1, 1))
335 awl
[ii
].awdLast
= awd
;
339 GetWindowRect (hWnd
, &awl
[ii
].rWnd
);
340 Subclass_AddHook (hWnd
, Resize_DialogProc
);
344 awl
[ii
].rWnd
.left
= 0;
345 awl
[ii
].rWnd
.right
= 0;
346 awl
[ii
].rWnd
.top
= 0;
347 awl
[ii
].rWnd
.bottom
= 0;
349 awl
[ii
].cxDeltaCenter
= 0;
350 awl
[ii
].cyDeltaCenter
= 0;
356 void rwFindAndRemoveWnd (HWND hWnd
)
358 for (size_t ii
= 0; ii
< (int)cwl
; ii
++)
360 if (awl
[ii
].hWnd
== hWnd
)
362 Subclass_RemoveHook (awl
[ii
].hWnd
, hWnd
);
370 DWORD
rwFindAction (rwWindowData
*awd
, int id
)
372 DWORD raDefault
= raLeaveAlone
;
376 for (int ii
= 0; awd
[ii
].id
!= idENDLIST
; ++ii
)
378 if (awd
[ii
].id
== id
)
380 if (awd
[ii
].id
== idDEFAULT
)
381 raDefault
= awd
[ii
].ra
;
389 void GetRectInParent (HWND hWnd
, RECT
*pr
)
393 GetWindowRect (hWnd
, pr
);
395 pr
->right
-= pr
->left
;
396 pr
->bottom
-= pr
->top
; // right/bottom == width/height for now
401 ScreenToClient (GetParent (hWnd
), &pt
);
405 pr
->right
+= pr
->left
;
406 pr
->bottom
+= pr
->top
;
411 * SPLITTERS __________________________________________________________________
415 static BOOL fRegistered
= FALSE
; // TRUE If registered class
417 static TCHAR cszSplitterClassX
[] = TEXT("SplitterWindowClassX");
418 static TCHAR cszSplitterClassY
[] = TEXT("SplitterWindowClassY");
421 HWND
CreateSplitter (HWND hWnd
, int id1
, int id2
, int id
,
422 LONG
*pcd
, rwWindowData
*awd
, BOOL fMovedAlready
)
428 if (!WhereShouldSplitterGo (hWnd
, id1
, id2
, &rWnd
, &fX
))
431 EnsureSplitterRegistered ();
433 psd
= (SplitterData
*)Allocate (sizeof(SplitterData
));
442 psd
->fMovedBeforeCreate
= fMovedAlready
;
445 (fX
) ? cszSplitterClassX
: cszSplitterClassY
,
447 WS_CHILD
| WS_VISIBLE
, // Window style
448 rWnd
.left
, // Default horizontal position
449 rWnd
.top
, // Default vertical position
450 rWnd
.right
-rWnd
.left
, // Default width
451 rWnd
.bottom
-rWnd
.top
, // Default height
452 hWnd
, // Parent window
453 (HMENU
)id
, // Use ID given us by caller
454 THIS_HINST
, // This instance owns this window
455 (void *)psd
// Pointer not needed
459 void DeleteSplitter (HWND hWnd
, int id1
)
463 if (hSplit
= GetDlgItem (hWnd
, id1
))
465 DestroyWindow (hSplit
);
469 void EnsureSplitterRegistered (void)
477 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
478 wc
.lpfnWndProc
= (WNDPROC
)SplitterWndProc
;
480 wc
.cbWndExtra
= sizeof(SplitterData
*);
481 wc
.hInstance
= THIS_HINST
;
483 wc
.hbrBackground
= CreateSolidBrush( GetSysColor( COLOR_BTNFACE
));
484 wc
.lpszMenuName
= NULL
;
486 // Register the X-moving class:
489 wc
.hCursor
= LoadCursor (THIS_HINST
, MAKEINTRESOURCE( IDC_HSPLIT
));
491 wc
.hCursor
= LoadCursor (NULL
, IDC_SIZEWE
);
494 wc
.lpszClassName
= cszSplitterClassX
;
496 (void)RegisterClass (&wc
);
498 // Register the Y-moving class:
501 wc
.hCursor
= LoadCursor (THIS_HINST
, MAKEINTRESOURCE( IDC_VSPLIT
));
503 wc
.hCursor
= LoadCursor (NULL
, IDC_SIZENS
);
506 wc
.lpszClassName
= cszSplitterClassY
;
508 (void)RegisterClass (&wc
);
513 BOOL
WhereShouldSplitterGo (HWND hWnd
, int id1
, int id2
, RECT
*prWnd
, BOOL
*pfX
)
518 GetRectInParent (GetDlgItem (hWnd
, id1
), &r1
);
519 GetRectInParent (GetDlgItem (hWnd
, id2
), &r2
);
521 if (r2
.left
> r1
.right
) // R1 on left, R2 on right?
524 prWnd
->top
= min (r1
.top
, r2
.top
);
525 prWnd
->bottom
= max (r1
.bottom
, r2
.bottom
);
526 prWnd
->left
= r1
.right
;
527 prWnd
->right
= r2
.left
;
529 else if (r2
.right
< r1
.left
) // R2 on left, R1 on right?
532 prWnd
->top
= min (r1
.top
, r2
.top
);
533 prWnd
->bottom
= max (r1
.bottom
, r2
.bottom
);
534 prWnd
->left
= r2
.right
;
535 prWnd
->right
= r1
.left
;
537 else if (r2
.top
> r1
.bottom
) // R1 on top, R2 on bottom?
540 prWnd
->left
= min (r1
.left
, r2
.left
);
541 prWnd
->right
= max (r1
.right
, r2
.right
);
542 prWnd
->top
= r1
.bottom
;
543 prWnd
->bottom
= r2
.top
;
545 else if (r2
.bottom
< r1
.top
) // R2 on top, R1 on bottom?
548 prWnd
->left
= min (r1
.left
, r2
.left
);
549 prWnd
->right
= max (r1
.right
, r2
.right
);
550 prWnd
->top
= r2
.bottom
;
551 prWnd
->bottom
= r1
.top
;
553 else // Rectangles intersect!
554 { // Don't know where it should go.
562 LONG APIENTRY
SplitterWndProc (HWND hWnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
565 static LONG cdAtStart
;
567 if (msg
== WM_CREATE
)
569 SetWindowLong (hWnd
,GWL_USER
,(LONG
)((LPCREATESTRUCT
)lp
)->lpCreateParams
);
572 if ((psd
= (SplitterData
*)GetWindowLong (hWnd
, GWL_USER
)) != NULL
)
577 if (!psd
->fMovedBeforeCreate
)
578 ResizeSplitter (GetParent (hWnd
), psd
, 0, psd
->pcDelta
);
579 psd
->fDragging
= FALSE
;
586 psd
->fDragging
= TRUE
;
587 cdAtStart
= *psd
->pcDelta
;
589 GetCursorPos (&psd
->ptStart
);
590 ScreenToClient (GetParent (hWnd
), &psd
->ptStart
);
602 ScreenToClient (GetParent (hWnd
), &pt
);
604 cx
= (LONG
)pt
.x
- (LONG
)psd
->ptStart
.x
;
605 cy
= (LONG
)pt
.y
- (LONG
)psd
->ptStart
.y
;
612 if (cd
!= *(psd
->pcDelta
))
614 ResizeSplitter (GetParent(hWnd
), psd
, *psd
->pcDelta
, &cd
);
624 psd
->fDragging
= FALSE
;
632 psd
->fDragging
= FALSE
;
635 psd
= NULL
; // fault blatantly if you use {psd} now
636 SetWindowLong (hWnd
, GWL_USER
, 0);
640 #if 0 // Enable me to make the splitters draw in black
644 HDC hdc
= BeginPaint (hWnd
, &ps
);
645 FillRect (hdc
, &ps
.rcPaint
, GetStockObject(BLACK_BRUSH
));
646 EndPaint (hWnd
, &ps
);
654 return DefWindowProc (hWnd
, msg
, wp
, lp
);
658 void ResizeSplitter (HWND hWnd
, SplitterData
*psd
, LONG cOld
, LONG
*pcNew
)
665 if (psd
== NULL
|| pcNew
== NULL
|| hWnd
== NULL
)
668 FindSplitterMinMax (hWnd
, psd
, cOld
, &cdMin
, &cdMax
);
669 *pcNew
= limit (cdMin
, *pcNew
, cdMax
);
674 dx
= (psd
->fX
) ? (*pcNew
- cOld
) : 0;
675 dy
= (psd
->fX
) ? 0 : (*pcNew
- cOld
);
677 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
679 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
686 BOOL fRepaint
= FALSE
;
687 HDWP dwp
= BeginDeferWindowPos (nItems
);
689 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
691 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
696 GetRectInParent (hItem
, &rItem
);
698 ra
= rwFindAction (psd
->awd
, (GetWindowLong (hItem
, GWL_ID
)));
700 DeferWindowPos (dwp
, hItem
, NULL
,
701 rItem
.left
+ ((ra
& raMoveX
) ? dx
:
702 (ra
& raMoveXB
) ? (0-dx
) : 0),
703 rItem
.top
+ ((ra
& raMoveY
) ? dy
:
704 (ra
& raMoveYB
) ? (0-dy
) : 0),
705 rItem
.right
-rItem
.left
706 + ((ra
& raSizeX
) ? dx
:
707 (ra
& raSizeXB
) ? (0-dx
) : 0),
708 rItem
.bottom
-rItem
.top
709 + ((ra
& raSizeY
) ? dy
:
710 (ra
& raSizeYB
) ? (0-dy
) : 0),
711 SWP_NOACTIVATE
| SWP_NOZORDER
);
714 EndDeferWindowPos (dwp
);
716 for (hItem
= GetWindow (hWnd
, GW_CHILD
);
718 hItem
= GetWindow (hItem
, GW_HWNDNEXT
))
720 DWORD ra
= rwFindAction (psd
->awd
, (GetWindowLong (hItem
, GWL_ID
)));
726 GetRectInParent (hItem
, &rItem
);
728 InvalidateRect (hWnd
, &rItem
, TRUE
);
741 void FindSplitterMinMax (HWND hWnd
, SplitterData
*psd
, LONG cOld
, LONG
*pcdMin
, LONG
*pcdMax
)
746 for (int ii
= 0; psd
->awd
[ ii
].id
!= idENDLIST
; ++ii
)
749 if ((hControl
= GetDlgItem (hWnd
, psd
->awd
[ ii
].id
)) != NULL
)
752 GetRectInParent (hControl
, &rControl
);
759 if (LOWORD(psd
->awd
[ ii
].cMinimum
)) // X minimum?
761 if (psd
->awd
[ ii
].ra
& raSizeX
)
762 cxMin
= cOld
- cxRECT(rControl
) + LOWORD(psd
->awd
[ ii
].cMinimum
);
763 else if (psd
->awd
[ ii
].ra
& raSizeXB
)
764 cxMax
= cOld
+ cxRECT(rControl
) - LOWORD(psd
->awd
[ ii
].cMinimum
);
765 else if (psd
->awd
[ ii
].ra
& raSizeXC
)
766 cxMin
= cOld
- (cxRECT(rControl
) - LOWORD(psd
->awd
[ ii
].cMinimum
))*2;
769 if (LOWORD(psd
->awd
[ ii
].cMaximum
)) // X maximum?
771 if (psd
->awd
[ ii
].ra
& raSizeX
)
772 cxMax
= cOld
- cxRECT(rControl
) + LOWORD(psd
->awd
[ ii
].cMaximum
);
773 else if (psd
->awd
[ ii
].ra
& raSizeXB
)
774 cxMin
= cOld
+ cxRECT(rControl
) - LOWORD(psd
->awd
[ ii
].cMaximum
);
775 else if (psd
->awd
[ ii
].ra
& raSizeXC
)
776 cxMin
= cOld
- (cxRECT(rControl
) - LOWORD(psd
->awd
[ ii
].cMaximum
))*2;
779 if (cxMin
) *pcdMin
= (*pcdMin
) ? max( *pcdMin
, cxMin
) : cxMin
;
780 if (cxMax
) *pcdMax
= (*pcdMax
) ? min( *pcdMax
, cxMax
) : cxMax
;
787 if (HIWORD(psd
->awd
[ ii
].cMinimum
)) // Y minimum?
789 if (psd
->awd
[ ii
].ra
& raSizeY
)
790 cyMin
= cOld
- cyRECT(rControl
) + HIWORD(psd
->awd
[ ii
].cMinimum
);
791 else if (psd
->awd
[ ii
].ra
& raSizeYB
)
792 cyMax
= cOld
+ cyRECT(rControl
) - HIWORD(psd
->awd
[ ii
].cMinimum
);
793 else if (psd
->awd
[ ii
].ra
& raSizeYC
)
794 cyMin
= cOld
- (cyRECT(rControl
) - HIWORD(psd
->awd
[ ii
].cMinimum
))*2;
797 if (HIWORD(psd
->awd
[ ii
].cMaximum
)) // Y maximum?
799 if (psd
->awd
[ ii
].ra
& raSizeY
)
800 cyMax
= cOld
- cyRECT(rControl
) + HIWORD(psd
->awd
[ ii
].cMaximum
);
801 else if (psd
->awd
[ ii
].ra
& raSizeYB
)
802 cyMin
= cOld
+ cyRECT(rControl
) - HIWORD(psd
->awd
[ ii
].cMaximum
);
803 else if (psd
->awd
[ ii
].ra
& raSizeYC
)
804 cyMin
= cOld
- (cyRECT(rControl
) - HIWORD(psd
->awd
[ ii
].cMaximum
))*2;
807 if (cyMin
) *pcdMin
= (*pcdMin
) ? max( *pcdMin
, cyMin
) : cyMin
;
808 if (cyMax
) *pcdMax
= (*pcdMax
) ? min( *pcdMax
, cyMax
) : cyMax
;
815 void FindResizeLimits (HWND hWnd
, LONG
*pcxMin
, LONG
*pcxMax
, LONG
*pcyMin
, LONG
*pcyMax
, rwWindowData
*awd
)
825 if ((iwl
= rwFindOrAddWnd (hWnd
)) == -1)
828 if ((awd
= awl
[ iwl
].awdLast
) == NULL
)
833 GetWindowRect (hWnd
, &rNow
);
835 for (DWORD ii
= 0; awd
[ ii
].id
!= idENDLIST
; ++ii
)
838 if ((hControl
= GetDlgItem (hWnd
, awd
[ ii
].id
)) != NULL
)
841 GetRectInParent (hControl
, &rControl
);
848 if (LOWORD(awd
[ ii
].cMinimum
)) // X minimum?
850 if (awd
[ ii
].ra
& raSizeX
)
851 cxMin
= cxRECT(rNow
) - cxRECT(rControl
) + LOWORD(awd
[ ii
].cMinimum
);
852 else if (awd
[ ii
].ra
& raSizeXB
)
853 cxMax
= cxRECT(rNow
) + cxRECT(rControl
) - LOWORD(awd
[ ii
].cMinimum
);
854 else if (awd
[ ii
].ra
& raSizeXC
)
855 cxMin
= cxRECT(rNow
) - (cxRECT(rControl
) - LOWORD(awd
[ ii
].cMinimum
))*2;
858 if (LOWORD(awd
[ ii
].cMaximum
)) // X maximum?
860 if (awd
[ ii
].ra
& raSizeX
)
861 cxMax
= cxRECT(rNow
) - cxRECT(rControl
) + LOWORD(awd
[ ii
].cMaximum
);
862 else if (awd
[ ii
].ra
& raSizeXB
)
863 cxMin
= cxRECT(rNow
) + cxRECT(rControl
) - LOWORD(awd
[ ii
].cMaximum
);
864 else if (awd
[ ii
].ra
& raSizeXC
)
865 cxMax
= cxRECT(rNow
) - (cxRECT(rControl
) - LOWORD(awd
[ ii
].cMaximum
))*2;
868 if (HIWORD(awd
[ ii
].cMinimum
)) // Y minimum?
870 if (awd
[ ii
].ra
& raSizeY
)
871 cyMin
= cyRECT(rNow
) - cyRECT(rControl
) + HIWORD(awd
[ ii
].cMinimum
);
872 else if (awd
[ ii
].ra
& raSizeYB
)
873 cyMax
= cyRECT(rNow
) + cyRECT(rControl
) - HIWORD(awd
[ ii
].cMinimum
);
874 else if (awd
[ ii
].ra
& raSizeYC
)
875 cyMin
= cyRECT(rNow
) - (cyRECT(rControl
) - HIWORD(awd
[ ii
].cMinimum
))*2;
878 if (HIWORD(awd
[ ii
].cMaximum
)) // Y maximum?
880 if (awd
[ ii
].ra
& raSizeY
)
881 cyMax
= cyRECT(rNow
) - cyRECT(rControl
) + HIWORD(awd
[ ii
].cMaximum
);
882 else if (awd
[ ii
].ra
& raSizeYB
)
883 cyMin
= cyRECT(rNow
) + cyRECT(rControl
) - HIWORD(awd
[ ii
].cMaximum
);
884 else if (awd
[ ii
].ra
& raSizeYC
)
885 cyMax
= cyRECT(rNow
) - (cyRECT(rControl
) - HIWORD(awd
[ ii
].cMaximum
))*2;
888 if (cxMin
) *pcxMin
= (*pcxMin
) ? max( *pcxMin
, cxMin
) : cxMin
;
889 if (cyMin
) *pcyMin
= (*pcyMin
) ? max( *pcyMin
, cyMin
) : cyMin
;
890 if (cxMax
) *pcxMax
= (*pcxMax
) ? min( *pcxMax
, cxMax
) : cxMax
;
891 if (cyMax
) *pcyMax
= (*pcyMax
) ? min( *pcyMax
, cyMax
) : cyMax
;
897 HRESULT CALLBACK
Resize_DialogProc (HWND hWnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
899 PVOID fnNext
= Subclass_FindNextHook (hWnd
, Resize_DialogProc
);
903 case WM_GETMINMAXINFO
:
908 FindResizeLimits (hWnd
, &cxMin
, &cxMax
, &cyMin
, &cyMax
);
911 lpmmi
= (LPMINMAXINFO
)lp
;
914 lpmmi
->ptMinTrackSize
.x
= cxMin
;
916 lpmmi
->ptMinTrackSize
.y
= cyMin
;
918 lpmmi
->ptMaxTrackSize
.x
= cxMax
;
920 lpmmi
->ptMaxTrackSize
.y
= cyMax
;
924 rwFindAndRemoveWnd (hWnd
);
928 return (fnNext
) ? CallWindowProc ((WNDPROC
)fnNext
, hWnd
, msg
, wp
, lp
) : FALSE
;