ResizableSplitterWnd.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // ResizableSplitterWnd.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 "ResizableSplitterWnd.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CResizableSplitterWnd
  26. IMPLEMENT_DYNAMIC(CResizableSplitterWnd, CSplitterWnd)
  27. CResizableSplitterWnd::CResizableSplitterWnd()
  28. {
  29. }
  30. CResizableSplitterWnd::~CResizableSplitterWnd()
  31. {
  32. }
  33. BEGIN_MESSAGE_MAP(CResizableSplitterWnd, CSplitterWnd)
  34. //{{AFX_MSG_MAP(CResizableSplitterWnd)
  35. ON_WM_GETMINMAXINFO()
  36. //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CResizableSplitterWnd message handlers
  40. void CResizableSplitterWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  41. {
  42. if ((GetStyle() & SPLS_DYNAMIC_SPLIT) &&
  43. GetRowCount() == 1 && GetColumnCount() == 1)
  44. {
  45. CWnd* pPane = GetActivePane();
  46. if (pPane != NULL)
  47. {
  48. // get the extra size from child to parent
  49. CRect rectClient, rectWnd;
  50. GetWindowRect(rectWnd);
  51. pPane->GetWindowRect(rectClient);
  52. CSize sizeExtra = rectWnd.Size() - rectClient.Size();
  53. ChainMinMaxInfo(lpMMI, pPane->m_hWnd, sizeExtra);
  54. }
  55. }
  56. else if (!(GetStyle() & SPLS_DYNAMIC_SPLIT))
  57. {
  58. ASSERT(m_nCols > 0 && m_nRows > 0);
  59. CSize sizeMin(0,0), sizeMax(0,0);
  60. for (int col = 0; col < m_nCols; ++col)
  61. {
  62. // calc min and max width for each column
  63. int min = 0;
  64. int max = LONG_MAX;
  65. for (int row = 0; row < m_nRows; ++row)
  66. {
  67. CWnd* pWnd = GetPane(row, col);
  68. // ask the child window for track size
  69. MINMAXINFO mmiChild = *lpMMI;
  70. mmiChild.ptMinTrackSize.x = 0;
  71. mmiChild.ptMaxTrackSize.x = LONG_MAX;
  72. ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
  73. max = __min(max, mmiChild.ptMaxTrackSize.x);
  74. min = __max(min, mmiChild.ptMinTrackSize.x);
  75. }
  76. // sum all column widths
  77. if (sizeMax.cx == LONG_MAX || max == LONG_MAX)
  78. sizeMax.cx = LONG_MAX;
  79. else
  80. sizeMax.cx += max + m_cxSplitterGap;
  81. sizeMin.cx += min + m_cxSplitterGap;
  82. }
  83. for (int row = 0; row < m_nRows; ++row)
  84. {
  85. // calc min and max height for each row
  86. int min = 0;
  87. int max = LONG_MAX;
  88. for (int col = 0; col < m_nCols; ++col)
  89. {
  90. CWnd* pWnd = GetPane(row, col);
  91. // ask the child window for track size
  92. MINMAXINFO mmiChild = *lpMMI;
  93. mmiChild.ptMinTrackSize.y = 0;
  94. mmiChild.ptMaxTrackSize.y = LONG_MAX;
  95. ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
  96. max = __min(max, mmiChild.ptMaxTrackSize.y);
  97. min = __max(min, mmiChild.ptMinTrackSize.y);
  98. }
  99. // sum all row heights
  100. if (sizeMax.cy == LONG_MAX || max == LONG_MAX)
  101. sizeMax.cy = LONG_MAX;
  102. else
  103. sizeMax.cy += max + m_cySplitterGap;
  104. sizeMin.cy += min + m_cySplitterGap;
  105. }
  106. // adjust total size: add the client border and
  107. // we counted one splitter more than necessary
  108. if (sizeMax.cx != LONG_MAX)
  109. sizeMax.cx += 2*m_cxBorder - m_cxSplitterGap;
  110. if (sizeMax.cy != LONG_MAX)
  111. sizeMax.cy += 2*m_cyBorder - m_cySplitterGap;
  112. sizeMin.cx += 2*m_cxBorder - m_cxSplitterGap;
  113. sizeMin.cy += 2*m_cyBorder - m_cySplitterGap;
  114. // add non-client size
  115. CRect rectExtra(0,0,0,0);
  116. ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
  117. ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
  118. sizeMax += rectExtra.Size();
  119. sizeMin += rectExtra.Size();
  120. // set minmax info
  121. lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x, sizeMin.cx);
  122. lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y, sizeMin.cy);
  123. lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x, sizeMax.cx);
  124. lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y, sizeMax.cy);
  125. }
  126. }