ResizableFormView.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // ResizableFormView.cpp : implementation file
  2. //
  3. /////////////////////////////////////////////////////////////////////////////
  4. //
  5. // This file is part of ResizableLib
  6. // https://github.com/ppescher/resizablelib
  7. //
  8. // Copyright (C) 2000-2015 by Paolo Messina
  9. // mailto:ppescher@hotmail.com
  10. //
  11. // The contents of this file are subject to the Artistic License 2.0
  12. // http://opensource.org/licenses/Artistic-2.0
  13. //
  14. // If you find this code useful, credits would be nice!
  15. //
  16. /////////////////////////////////////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "ResizableFormView.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CResizableFormView
  26. IMPLEMENT_DYNAMIC(CResizableFormView, CFormView)
  27. inline void CResizableFormView::PrivateConstruct()
  28. {
  29. m_dwGripTempState = GHR_SCROLLBAR | GHR_ALIGNMENT | GHR_MAXIMIZED;
  30. }
  31. CResizableFormView::CResizableFormView(UINT nIDTemplate)
  32. : CFormView(nIDTemplate)
  33. {
  34. PrivateConstruct();
  35. }
  36. CResizableFormView::CResizableFormView(LPCTSTR lpszTemplateName)
  37. : CFormView(lpszTemplateName)
  38. {
  39. PrivateConstruct();
  40. }
  41. CResizableFormView::~CResizableFormView()
  42. {
  43. }
  44. BEGIN_MESSAGE_MAP(CResizableFormView, CFormView)
  45. //{{AFX_MSG_MAP(CResizableFormView)
  46. ON_WM_SIZE()
  47. ON_WM_ERASEBKGND()
  48. ON_WM_GETMINMAXINFO()
  49. ON_WM_DESTROY()
  50. ON_WM_NCCREATE()
  51. //}}AFX_MSG_MAP
  52. END_MESSAGE_MAP()
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CResizableFormView diagnostics
  55. #ifdef _DEBUG
  56. void CResizableFormView::AssertValid() const
  57. {
  58. CFormView::AssertValid();
  59. }
  60. void CResizableFormView::Dump(CDumpContext& dc) const
  61. {
  62. CFormView::Dump(dc);
  63. }
  64. #endif //_DEBUG
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CResizableFormView message handlers
  67. void CResizableFormView::OnSize(UINT nType, int cx, int cy)
  68. {
  69. CFormView::OnSize(nType, cx, cy);
  70. CWnd* pParent = GetParentFrame();
  71. // hide size grip when parent is maximized
  72. if (pParent->IsZoomed())
  73. HideSizeGrip(&m_dwGripTempState, GHR_MAXIMIZED);
  74. else
  75. ShowSizeGrip(&m_dwGripTempState, GHR_MAXIMIZED);
  76. // hide size grip when there are scrollbars
  77. CSize size = GetTotalSize();
  78. if ((cx < size.cx || cy < size.cy) && (m_nMapMode >= 0))
  79. HideSizeGrip(&m_dwGripTempState, GHR_SCROLLBAR);
  80. else
  81. ShowSizeGrip(&m_dwGripTempState, GHR_SCROLLBAR);
  82. // hide size grip when the parent frame window is not resizable
  83. // or the form is not bottom-right aligned (e.g. there's a statusbar)
  84. DWORD dwStyle = pParent->GetStyle();
  85. CRect rect, rectChild;
  86. GetWindowRect(rect);
  87. BOOL bCanResize = TRUE; // whether the grip can size the frame
  88. for (HWND hWndChild = ::GetWindow(m_hWnd, GW_HWNDFIRST); hWndChild != NULL;
  89. hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  90. {
  91. ::GetWindowRect(hWndChild, rectChild);
  92. //! @todo check RTL layouts!
  93. if (rectChild.right > rect.right || rectChild.bottom > rect.bottom)
  94. {
  95. bCanResize = FALSE;
  96. break;
  97. }
  98. }
  99. if ((dwStyle & WS_THICKFRAME) && bCanResize)
  100. ShowSizeGrip(&m_dwGripTempState, GHR_ALIGNMENT);
  101. else
  102. HideSizeGrip(&m_dwGripTempState, GHR_ALIGNMENT);
  103. // update grip and layout
  104. UpdateSizeGrip();
  105. ArrangeLayout();
  106. }
  107. void CResizableFormView::GetTotalClientRect(LPRECT lpRect) const
  108. {
  109. GetClientRect(lpRect);
  110. // get dialog template's size
  111. // (this is set in CFormView::Create)
  112. CSize sizeTotal, sizePage, sizeLine;
  113. int nMapMode = 0;
  114. GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);
  115. // otherwise, give the correct size if scrollbars active
  116. if (nMapMode < 0) // scrollbars disabled
  117. return;
  118. // enlarge reported client area when needed
  119. CRect rect(lpRect);
  120. if (rect.Width() < sizeTotal.cx)
  121. rect.right = rect.left + sizeTotal.cx;
  122. if (rect.Height() < sizeTotal.cy)
  123. rect.bottom = rect.top + sizeTotal.cy;
  124. rect.OffsetRect(-GetDeviceScrollPosition());
  125. *lpRect = rect;
  126. }
  127. BOOL CResizableFormView::OnEraseBkgnd(CDC* pDC)
  128. {
  129. ClipChildren(pDC, FALSE);
  130. BOOL bRet = CFormView::OnEraseBkgnd(pDC);
  131. ClipChildren(pDC, TRUE);
  132. return bRet;
  133. }
  134. void CResizableFormView::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  135. {
  136. MinMaxInfo(lpMMI);
  137. }
  138. void CResizableFormView::OnDestroy()
  139. {
  140. // reset instance data
  141. RemoveAllAnchors();
  142. ResetAllRects();
  143. PrivateConstruct();
  144. CFormView::OnDestroy();
  145. }
  146. LRESULT CResizableFormView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  147. {
  148. if (message == WM_INITDIALOG)
  149. return (LRESULT)OnInitDialog();
  150. if (message != WM_NCCALCSIZE || wParam == 0)
  151. return CFormView::WindowProc(message, wParam, lParam);
  152. // specifying valid rects needs controls already anchored
  153. LRESULT lResult = 0;
  154. HandleNcCalcSize(FALSE, (LPNCCALCSIZE_PARAMS)lParam, lResult);
  155. lResult = CFormView::WindowProc(message, wParam, lParam);
  156. HandleNcCalcSize(TRUE, (LPNCCALCSIZE_PARAMS)lParam, lResult);
  157. return lResult;
  158. }
  159. BOOL CResizableFormView::OnInitDialog()
  160. {
  161. const MSG* pMsg = GetCurrentMessage();
  162. BOOL bRet = (BOOL)CFormView::WindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
  163. // we need to associate member variables with control IDs
  164. UpdateData(FALSE);
  165. // set default scroll size
  166. CRect rectTemplate;
  167. GetWindowRect(rectTemplate);
  168. SetScrollSizes(MM_TEXT, rectTemplate.Size());
  169. return bRet;
  170. }
  171. BOOL CResizableFormView::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
  172. {
  173. if (!CFormView::OnNcCreate(lpCreateStruct))
  174. return FALSE;
  175. // create and init the size-grip
  176. if (!CreateSizeGrip())
  177. return FALSE;
  178. return TRUE;
  179. }