ResizableMinMax.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // This file is part of ResizableLib
  4. // https://github.com/ppescher/resizablelib
  5. //
  6. // Copyright (C) 2000-2015 by Paolo Messina
  7. // mailto:ppescher@hotmail.com
  8. //
  9. // The contents of this file are subject to the Artistic License 2.0
  10. // http://opensource.org/licenses/Artistic-2.0
  11. //
  12. // If you find this code useful, credits would be nice!
  13. //
  14. /////////////////////////////////////////////////////////////////////////////
  15. /*!
  16. * @file
  17. * @brief Implementation of the CResizableMinMax class.
  18. */
  19. #include "stdafx.h"
  20. #include "ResizableMinMax.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[]=__FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26. //////////////////////////////////////////////////////////////////////
  27. // Construction/Destruction
  28. //////////////////////////////////////////////////////////////////////
  29. CResizableMinMax::CResizableMinMax()
  30. {
  31. m_bUseMinTrack = FALSE;
  32. m_bUseMaxTrack = FALSE;
  33. m_bUseMaxRect = FALSE;
  34. }
  35. CResizableMinMax::~CResizableMinMax()
  36. {
  37. }
  38. void CResizableMinMax::MinMaxInfo(LPMINMAXINFO lpMMI)
  39. {
  40. if (m_bUseMinTrack)
  41. lpMMI->ptMinTrackSize = m_ptMinTrackSize;
  42. if (m_bUseMaxTrack)
  43. lpMMI->ptMaxTrackSize = m_ptMaxTrackSize;
  44. if (m_bUseMaxRect)
  45. {
  46. lpMMI->ptMaxPosition = m_ptMaxPos;
  47. lpMMI->ptMaxSize = m_ptMaxSize;
  48. }
  49. }
  50. void CResizableMinMax::ChainMinMaxInfo(LPMINMAXINFO lpMMI, CWnd* pParentFrame, CWnd* pWnd)
  51. {
  52. // get the extra size from child to parent
  53. CRect rectClient, rectWnd;
  54. if ((pParentFrame->GetStyle() & WS_CHILD) && pParentFrame->IsZoomed())
  55. pParentFrame->GetClientRect(rectWnd);
  56. else
  57. pParentFrame->GetWindowRect(rectWnd);
  58. pParentFrame->RepositionBars(0, 0xFFFF,
  59. AFX_IDW_PANE_FIRST, CWnd::reposQuery, rectClient);
  60. CSize sizeExtra = rectWnd.Size() - rectClient.Size();
  61. ChainMinMaxInfo(lpMMI, pWnd->GetSafeHwnd(), sizeExtra);
  62. }
  63. void CResizableMinMax::ChainMinMaxInfo(LPMINMAXINFO lpMMI, HWND hWndChild, CSize sizeExtra)
  64. {
  65. // ask the child window for track size
  66. MINMAXINFO mmiChild = *lpMMI;
  67. ::SendMessage(hWndChild, WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
  68. BOOL bRetMax = (lpMMI->ptMaxTrackSize.x != mmiChild.ptMaxTrackSize.x
  69. || lpMMI->ptMaxTrackSize.y != mmiChild.ptMaxTrackSize.y);
  70. BOOL bRetMin = (lpMMI->ptMinTrackSize.x != mmiChild.ptMinTrackSize.x
  71. || lpMMI->ptMinTrackSize.y != mmiChild.ptMinTrackSize.y);
  72. // add static extra size
  73. mmiChild.ptMaxTrackSize = sizeExtra + mmiChild.ptMaxTrackSize;
  74. mmiChild.ptMinTrackSize = sizeExtra + mmiChild.ptMinTrackSize;
  75. // min size is the largest
  76. if (bRetMin)
  77. {
  78. lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x,
  79. mmiChild.ptMinTrackSize.x);
  80. lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y,
  81. mmiChild.ptMinTrackSize.y);
  82. }
  83. // max size is the shortest
  84. if (bRetMax)
  85. {
  86. lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x,
  87. mmiChild.ptMaxTrackSize.x);
  88. lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y,
  89. mmiChild.ptMaxTrackSize.y);
  90. }
  91. }
  92. BOOL CResizableMinMax::CalcSizeExtra(HWND /*hWndChild*/, CSize /*sizeChild*/, CSize& /*sizeExtra*/)
  93. {
  94. // should be overridden if you use ChainMinMaxInfoCB
  95. ASSERT(FALSE);
  96. return FALSE;
  97. }
  98. void CResizableMinMax::ChainMinMaxInfoCB(LPMINMAXINFO lpMMI, HWND hWndChild)
  99. {
  100. // ask the child window for track size
  101. MINMAXINFO mmiChild = *lpMMI;
  102. ::SendMessage(hWndChild, WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
  103. BOOL bRetMax = (lpMMI->ptMaxTrackSize.x != mmiChild.ptMaxTrackSize.x
  104. || lpMMI->ptMaxTrackSize.y != mmiChild.ptMaxTrackSize.y);
  105. BOOL bRetMin = (lpMMI->ptMinTrackSize.x != mmiChild.ptMinTrackSize.x
  106. || lpMMI->ptMinTrackSize.y != mmiChild.ptMinTrackSize.y);
  107. // use a callback to determine extra size
  108. CSize sizeExtra(0, 0);
  109. bRetMax = bRetMax && CalcSizeExtra(hWndChild, mmiChild.ptMaxTrackSize, sizeExtra);
  110. mmiChild.ptMaxTrackSize = sizeExtra + mmiChild.ptMaxTrackSize;
  111. bRetMin = bRetMin && CalcSizeExtra(hWndChild, mmiChild.ptMinTrackSize, sizeExtra);
  112. mmiChild.ptMinTrackSize = sizeExtra + mmiChild.ptMinTrackSize;
  113. // min size is the largest
  114. if (bRetMin)
  115. {
  116. lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x,
  117. mmiChild.ptMinTrackSize.x);
  118. lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y,
  119. mmiChild.ptMinTrackSize.y);
  120. }
  121. // max size is the shortest
  122. if (bRetMax)
  123. {
  124. lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x,
  125. mmiChild.ptMaxTrackSize.x);
  126. lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y,
  127. mmiChild.ptMaxTrackSize.y);
  128. }
  129. }
  130. void CResizableMinMax::ResetAllRects()
  131. {
  132. m_bUseMinTrack = FALSE;
  133. m_bUseMaxTrack = FALSE;
  134. m_bUseMaxRect = FALSE;
  135. }
  136. void CResizableMinMax::SetMaximizedRect(const CRect& rc)
  137. {
  138. m_bUseMaxRect = TRUE;
  139. m_ptMaxPos = rc.TopLeft();
  140. m_ptMaxSize.x = rc.Width();
  141. m_ptMaxSize.y = rc.Height();
  142. }
  143. void CResizableMinMax::ResetMaximizedRect()
  144. {
  145. m_bUseMaxRect = FALSE;
  146. }
  147. void CResizableMinMax::SetMinTrackSize(const CSize& size)
  148. {
  149. m_bUseMinTrack = TRUE;
  150. m_ptMinTrackSize.x = size.cx;
  151. m_ptMinTrackSize.y = size.cy;
  152. }
  153. void CResizableMinMax::ResetMinTrackSize()
  154. {
  155. m_bUseMinTrack = FALSE;
  156. }
  157. void CResizableMinMax::SetMaxTrackSize(const CSize& size)
  158. {
  159. m_bUseMaxTrack = TRUE;
  160. m_ptMaxTrackSize.x = size.cx;
  161. m_ptMaxTrackSize.y = size.cy;
  162. }
  163. void CResizableMinMax::ResetMaxTrackSize()
  164. {
  165. m_bUseMaxTrack = FALSE;
  166. }