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