AutoSizer.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #ifndef __AutoSizer_h__
  2. #define __AutoSizer_h__
  3. /////////////////////////////////////////////////////////////////////////////
  4. // AutoSizer.h | Declaration of the CAutoSizer class.
  5. #include <vector>
  6. /////////////////////////////////////////////////////////////////////////////
  7. // Enumerations
  8. enum AutoSizer_Follower
  9. {
  10. AutoSizer_Follow_Left,
  11. AutoSizer_Follow_Right,
  12. AutoSizer_Follow_LeftRight,
  13. AutoSizer_Follow_HCenter,
  14. AutoSizer_Follow_Top,
  15. AutoSizer_Follow_Bottom,
  16. AutoSizer_Follow_TopBottom,
  17. AutoSizer_Follow_VCenter,
  18. };
  19. enum AutoSizer_Leader
  20. {
  21. AutoSizer_Lead_Left,
  22. AutoSizer_Lead_Right,
  23. AutoSizer_Lead_HCenter,
  24. AutoSizer_Lead_Top,
  25. AutoSizer_Lead_Bottom,
  26. AutoSizer_Lead_VCenter,
  27. };
  28. enum AutoSizer_Refresh
  29. {
  30. AutoSizer_Refresh_NoRefresh,
  31. AutoSizer_Refresh_Refresh,
  32. AutoSizer_Refresh_BkRefresh,
  33. };
  34. /////////////////////////////////////////////////////////////////////////////
  35. // AutoSizerRule
  36. struct AutoSizerRule
  37. {
  38. // Data Members
  39. public:
  40. #pragma pack(push, 4)
  41. UINT m_idFollower;
  42. UINT m_idLeader;
  43. AutoSizer_Follower m_eFollower :12;
  44. AutoSizer_Leader m_eLeader :12;
  45. AutoSizer_Refresh m_eRefresh : 8;
  46. #pragma pack(pop)
  47. // Attributes
  48. public:
  49. bool IsEnd() const
  50. {
  51. return !m_idFollower;
  52. }
  53. };
  54. /////////////////////////////////////////////////////////////////////////////
  55. // Rule Map Macros
  56. #define BEGIN_AUTO_SIZER_MAP(name) \
  57. static AutoSizerRule name [] = \
  58. {
  59. #define AUTO_SIZER_ENTRY(idFollow, edgeFollow, idLead, edgeLead, refresh) \
  60. { \
  61. (UINT)idFollow, \
  62. (UINT)idLead, \
  63. AutoSizer_Follow_##edgeFollow, \
  64. AutoSizer_Lead_##edgeLead, \
  65. AutoSizer_Refresh_##refresh \
  66. },
  67. #define END_AUTO_SIZER_MAP() \
  68. AUTO_SIZER_ENTRY(0, Left, 0, Left, NoRefresh) \
  69. };
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CAutoSizer
  72. class CAutoSizer
  73. {
  74. // Construction / Destruction
  75. public:
  76. CAutoSizer();
  77. // Attributes
  78. public:
  79. bool SetWindowAndRules(HWND hwnd, const AutoSizerRule* pRules);
  80. bool SetMinSize(int cx, int cy, bool bDlgUnits = true);
  81. bool SetMinSize(SIZE size, bool bDlgUnits = true);
  82. SIZE GetMinSize() const;
  83. HWND GetWindow() const;
  84. const RECT* GetClientRect() const;
  85. const RECT* GetOriginalClientRect() const;
  86. // Operations
  87. public:
  88. bool ProcessMessage(MSG* pMsg);
  89. bool ProcessMessage(UINT uMsg, WPARAM wp, LPARAM lp, LRESULT* plr);
  90. bool AddRule(HWND hwndFollower, AutoSizer_Follower edgeFollower,
  91. HWND hwndLeader, AutoSizer_Leader edgeLeader, AutoSizer_Refresh refresh);
  92. bool RemoveRules(HWND hwndFollower);
  93. // Implementation
  94. protected:
  95. void ComputeMinRects();
  96. void UpdatePositions();
  97. // Message Handlers
  98. protected:
  99. void OnDestroy();
  100. void OnGetMinMaxInfo(MINMAXINFO* pMMI);
  101. void OnSize(UINT nType, int cx, int cy);
  102. void OnStyleChanged();
  103. // Types
  104. protected:
  105. struct XRule
  106. {
  107. XRule();
  108. XRule(const AutoSizerRule* pRule);
  109. XRule(const XRule& that);
  110. operator=(const AutoSizerRule* pRule);
  111. operator=(const XRule& that);
  112. bool operator==(const AutoSizerRule* pRule);
  113. HWND GetFollower() const;
  114. HWND GetLeader() const;
  115. void ResolveIDs(CAutoSizer* pSizer);
  116. bool SaveInitialOffsets(CAutoSizer* pSizer);
  117. bool UpdateRectangle(CAutoSizer* pSizer, RECT& rcNew) const;
  118. private:
  119. AutoSizerRule m_Rule;
  120. int m_Offsets[2];
  121. };
  122. typedef std::vector<XRule> XRules;
  123. typedef XRules::iterator XRuleIt;
  124. // Data Members
  125. protected:
  126. XRules m_Rules;
  127. HWND m_hwnd;
  128. RECT m_rcMinClient;
  129. RECT m_rcMinWindow;
  130. RECT m_rcClient;
  131. RECT m_rcClientOriginal;
  132. bool m_bRecomputeMinWindow : 1;
  133. };
  134. /////////////////////////////////////////////////////////////////////////////
  135. // Inline Attributes
  136. inline bool CAutoSizer::SetMinSize(SIZE size, bool bDlgUnits)
  137. {
  138. return SetMinSize(size.cx, size.cy, bDlgUnits);
  139. }
  140. inline SIZE CAutoSizer::GetMinSize() const
  141. {
  142. SIZE size = {m_rcMinClient.right, m_rcMinClient.bottom};
  143. return size;
  144. }
  145. inline HWND CAutoSizer::GetWindow() const
  146. {
  147. return m_hwnd;
  148. }
  149. inline const RECT* CAutoSizer::GetClientRect() const
  150. {
  151. return &m_rcClient;
  152. }
  153. inline const RECT* CAutoSizer::GetOriginalClientRect() const
  154. {
  155. return &m_rcClientOriginal;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. inline CAutoSizer::XRule::XRule()
  159. {
  160. ZeroMemory(&m_Rule, sizeof(m_Rule));
  161. ZeroMemory(m_Offsets, sizeof(m_Offsets));
  162. }
  163. inline CAutoSizer::XRule::XRule(const AutoSizerRule* pRule)
  164. {
  165. CopyMemory(&m_Rule, pRule, sizeof(m_Rule));
  166. }
  167. inline CAutoSizer::XRule::XRule(const XRule& that)
  168. {
  169. CopyMemory(&m_Rule, &that.m_Rule, sizeof(m_Rule));
  170. CopyMemory(m_Offsets, that.m_Offsets, sizeof(m_Offsets));
  171. }
  172. inline CAutoSizer::XRule::operator=(const AutoSizerRule* pRule)
  173. {
  174. CopyMemory(&m_Rule, pRule, sizeof(m_Rule));
  175. ZeroMemory(m_Offsets, sizeof(m_Offsets));
  176. }
  177. inline CAutoSizer::XRule::operator=(const XRule& that)
  178. {
  179. CopyMemory(&m_Rule, &that.m_Rule, sizeof(m_Rule));
  180. CopyMemory(m_Offsets, that.m_Offsets, sizeof(m_Offsets));
  181. }
  182. inline bool CAutoSizer::XRule::operator==(const AutoSizerRule* pRule)
  183. {
  184. return 0 == memcmp(pRule, &m_Rule, sizeof(m_Rule));
  185. }
  186. inline HWND CAutoSizer::XRule::GetFollower() const
  187. {
  188. HWND hwnd = reinterpret_cast<HWND>(m_Rule.m_idFollower);
  189. _ASSERTE(::IsWindow(hwnd));
  190. return hwnd;
  191. }
  192. inline HWND CAutoSizer::XRule::GetLeader() const
  193. {
  194. HWND hwnd = reinterpret_cast<HWND>(m_Rule.m_idLeader);
  195. _ASSERTE(::IsWindow(hwnd));
  196. return hwnd;
  197. }
  198. inline void CAutoSizer::XRule::ResolveIDs(CAutoSizer* pSizer)
  199. {
  200. HWND hwndParent = pSizer->GetWindow();
  201. _ASSERTE(::IsWindow(hwndParent));
  202. HWND hwndFollower = m_Rule.m_idFollower ?
  203. ::GetDlgItem(hwndParent, m_Rule.m_idFollower) : hwndParent;
  204. _ASSERTE(::IsWindow(hwndFollower));
  205. m_Rule.m_idFollower = reinterpret_cast<UINT>(hwndFollower);
  206. HWND hwndLeader = m_Rule.m_idLeader ?
  207. ::GetDlgItem(hwndParent, m_Rule.m_idLeader) : hwndParent;
  208. _ASSERTE(::IsWindow(hwndLeader));
  209. m_Rule.m_idLeader = reinterpret_cast<UINT>(hwndLeader);
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. // Message Macros for ATL usage
  213. #ifdef _ATL
  214. #define AUTO_SIZER_MESSAGE_HANDLER(autoSizer) \
  215. if (autoSizer.ProcessMessage(uMsg, wParam, lParam, &lResult)) \
  216. return TRUE;
  217. #endif // _ATL
  218. /////////////////////////////////////////////////////////////////////////////
  219. #endif // !__AutoSizer_h__