1 /////////////////////////////////////////////////////////////////////////////
3 // This file is part of ResizableLib
4 // http://sourceforge.net/projects/resizablelib
6 // Copyright (C) 2000-2004 by Paolo Messina
7 // http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com
9 // The contents of this file are subject to the Artistic License (the "License").
10 // You may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at:
12 // http://www.opensource.org/licenses/artistic-license.html
14 // If you find this code useful, credits would be nice!
16 /////////////////////////////////////////////////////////////////////////////
20 * @brief Interface for the CResizableLayout class.
23 #if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
24 #define AFX_RESIZABLELAYOUT_H__INCLUDED_
27 #include "ResizableMsgSupport.h"
31 #endif // _MSC_VER > 1000
33 /*! @addtogroup CoreComponents
37 //! @brief Special type for layout alignment
39 * Implements anchor points as a percentage of the parent window client area.
40 * Control corners are always kept at a fixed distance from their anchor points,
41 * thus allowing a control to resize proportionally as the parent window is resized.
43 typedef struct tagANCHOR
45 int cx
; //!< horizontal component, in percent
46 int cy
; //!< vertical component, in percent
50 tagANCHOR(int x
, int y
)
56 } ANCHOR
, *PANCHOR
, *LPANCHOR
;
58 /*! @defgroup ConstAnchors Alignment Constants
59 * Define common layout alignment constants for anchor points.
62 //! Anchor to the top-left corner
63 const ANCHOR
TOP_LEFT(0, 0);
64 //! Anchor to the top edge and center horizontally
65 const ANCHOR
TOP_CENTER(50, 0);
66 //! Anchor to the top-right corner
67 const ANCHOR
TOP_RIGHT(100, 0);
68 //! Anchor to the left edge and center vertically
69 const ANCHOR
MIDDLE_LEFT(0, 50);
70 //! Anchor to the center
71 const ANCHOR
MIDDLE_CENTER(50, 50);
72 //! Anchor to the right edge and center vertically
73 const ANCHOR
MIDDLE_RIGHT(100, 50);
74 //! Anchor to the bottom-left corner
75 const ANCHOR
BOTTOM_LEFT(0, 100);
76 //! Anchor to the bottom edge and center horizontally
77 const ANCHOR
BOTTOM_CENTER(50, 100);
78 //! Anchor to the bottom-right corner
79 const ANCHOR
BOTTOM_RIGHT(100, 100);
82 //! @brief Holds a control layout settings
84 * Layout settings specify how a control must be moved and resized with respect to
85 * the parent window and how it reacts to dynamic changes to its size when painting
86 * its client area, with special care for flickering.
88 typedef struct tagLAYOUTINFO
90 //! Handle of the window the layout of which is being defined
92 //! Identification number assigned to the callback slot
95 //! Window class name to identify standard controls
96 TCHAR sWndClass
[MAX_PATH
];
98 //! Anchor point for the top-left corner
100 //! Fixed distance for the top-left corner
103 //! Anchor point for the bottom-right corner
104 ANCHOR anchorBottomRight
;
105 //! Fixed distance for the bottom-right corner
106 SIZE marginBottomRight
;
108 //! Flag that enables support for custom windows
110 //! Redraw settings for anti-flickering and proper painting
111 RESIZEPROPERTIES properties
;
113 tagLAYOUTINFO() : hWnd(NULL
), nCallbackID(0), bMsgSupport(FALSE
)
118 tagLAYOUTINFO(HWND hwnd
, ANCHOR tl_type
, SIZE tl_margin
,
119 ANCHOR br_type
, SIZE br_margin
)
121 hWnd(hwnd
), nCallbackID(0), bMsgSupport(FALSE
),
122 anchorTopLeft(tl_type
), marginTopLeft(tl_margin
),
123 anchorBottomRight(br_type
), marginBottomRight(br_margin
)
128 } LAYOUTINFO
, *PLAYOUTINFO
, *LPLAYOUTINFO
;
130 //! @brief Layout manager implementation
132 * Derive from this class to implement resizable windows, adding the ability
133 * to dinamically resize and reposition child controls.
134 * Special care is taken to ensure a smooth animation during the resize
135 * operations performed by the users, without annoying flickering effects.
137 class CResizableLayout
141 //! @brief Collection of layout settings for each control
142 CMap
<HWND
, HWND
, POSITION
, POSITION
> m_mapLayout
;
143 CList
<LAYOUTINFO
, LAYOUTINFO
&> m_listLayout
;
144 CList
<LAYOUTINFO
, LAYOUTINFO
&> m_listLayoutCB
;
148 //! @brief Used for clipping implementation
154 //! @brief Used for advanced anti-flickering
155 RECT m_rectClientBefore
;
159 //! @brief Apply clipping settings for the specified control
160 void ClipChildWindow(const LAYOUTINFO
&layout
, CRgn
* pRegion
) const;
162 //! @brief Helper function to calculate new layout
163 void CalcNewChildPosition(const LAYOUTINFO
&layout
,
164 const CRect
&rectParent
, CRect
&rectChild
, UINT
& uFlags
) const;
168 BOOL
IsInAnchorList(HWND hwnd
)
171 return m_mapLayout
.Lookup(hwnd
, pos
);
173 //! @brief Override to initialize resize properties (clipping, refresh)
174 virtual void InitResizeProperties(LAYOUTINFO
& layout
) const;
176 //! @brief Override to specify clipping for unsupported windows
177 virtual BOOL
LikesClipping(const LAYOUTINFO
&layout
) const;
179 //! @brief Override to specify refresh for unsupported windows
180 virtual BOOL
NeedsRefresh(const LAYOUTINFO
&layout
,
181 const CRect
&rectOld
, const CRect
&rectNew
) const;
183 //! @brief Clip controls in the layout out of the specified device context
184 BOOL
ClipChildren(CDC
* pDC
, BOOL bUndo
);
186 //! @brief Get the layout clipping region
187 void GetClippingRegion(CRgn
* pRegion
) const;
189 //! @brief Override for scrollable or expanding parent windows
190 virtual void GetTotalClientRect(LPRECT lpRect
) const;
193 //! @brief Add anchor points for the specified control to the layout
194 void AddAnchor(HWND hWnd
, ANCHOR anchorTopLeft
, ANCHOR anchorBottomRight
);
196 void AddAnchor(HWND hWnd
, ANCHOR anchorTopLeft
)
198 AddAnchor(hWnd
, anchorTopLeft
, anchorTopLeft
);
201 void AddAnchor(UINT nID
, ANCHOR anchorTopLeft
, ANCHOR anchorBottomRight
)
203 AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID
),
204 anchorTopLeft
, anchorBottomRight
);
207 void AddAnchor(UINT nID
, ANCHOR anchorTopLeft
)
209 AddAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID
),
210 anchorTopLeft
, anchorTopLeft
);
214 //! @brief Add a callback slot to the layout for dynamic controls or anchor points
215 UINT_PTR
AddAnchorCallback();
218 //! @brief Get position and size of a control in the layout from the parent's client area
219 BOOL
GetAnchorPosition(HWND hWnd
, const CRect
&rectParent
,
220 CRect
&rectChild
, UINT
* lpFlags
= NULL
) const
223 if (!m_mapLayout
.Lookup(hWnd
, pos
))
227 CalcNewChildPosition(m_listLayout
.GetAt(pos
), rectParent
, rectChild
,
228 (lpFlags
!= NULL
) ? (*lpFlags
) : uTmpFlags
);
232 BOOL
GetAnchorPosition(UINT nID
, const CRect
&rectParent
,
233 CRect
&rectChild
, UINT
* lpFlags
= NULL
) const
235 return GetAnchorPosition(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID
),
236 rectParent
, rectChild
, lpFlags
);
241 //! @brief Get margins surrounding a control in the layout with the given size
242 BOOL
GetAnchorMargins(HWND hWnd
, const CSize
&sizeChild
, CRect
&rectMargins
) const;
244 BOOL
GetAnchorMargins(UINT nID
, const CSize
&sizeChild
, CRect
&rectMargins
) const
246 return GetAnchorMargins(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID
),
247 sizeChild
, rectMargins
);
252 //! @brief Remove a control from the layout
253 BOOL
RemoveAnchor(HWND hWnd
)
256 if (!m_mapLayout
.Lookup(hWnd
, pos
))
259 m_listLayout
.RemoveAt(pos
);
260 return m_mapLayout
.RemoveKey(hWnd
);
263 BOOL
RemoveAnchor(UINT nID
)
265 return RemoveAnchor(::GetDlgItem(GetResizableWnd()->GetSafeHwnd(), nID
));
269 //! @brief Reset the layout content
270 void RemoveAllAnchors()
272 m_mapLayout
.RemoveAll();
273 m_listLayout
.RemoveAll();
274 m_listLayoutCB
.RemoveAll();
277 //! @brief Reposition and size all the controls in the layout
278 void ArrangeLayout() const;
280 //! @brief Override to provide dynamic control's layout info
281 virtual BOOL
ArrangeLayoutCallback(LAYOUTINFO
& layout
) const;
283 //! @brief Override to provide the parent window
284 virtual CWnd
* GetResizableWnd() const = 0;
286 //! @brief Enhance anti-flickering
287 void HandleNcCalcSize(BOOL bAfterDefault
, LPNCCALCSIZE_PARAMS lpncsp
, LRESULT
& lResult
);
289 //! @brief Enable resizable style for top level parent windows
290 void MakeResizable(LPCREATESTRUCT lpCreateStruct
);
295 m_bNoRecursion
= FALSE
;
296 m_hOldClipRgn
= ::CreateRectRgn(0,0,0,0);
300 virtual ~CResizableLayout()
305 DeleteObject(m_hOldClipRgn
);
310 #endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)