Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.6 KiB

  1. // SplitWnd.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "SplitterWndEx.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. // HitTest return values (values and spacing between values is important)
  11. // Had to adopt this because it has module scope
  12. enum HitTestValue
  13. {
  14. noHit = 0,
  15. vSplitterBox = 1,
  16. hSplitterBox = 2,
  17. bothSplitterBox = 3, // just for keyboard
  18. vSplitterBar1 = 101,
  19. vSplitterBar15 = 115,
  20. hSplitterBar1 = 201,
  21. hSplitterBar15 = 215,
  22. splitterIntersection1 = 301,
  23. splitterIntersection225 = 525
  24. };
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CSplitterWndEx
  27. BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
  28. //{{AFX_MSG_MAP(CSplitterWndEx)
  29. // NOTE - the ClassWizard will add and remove mapping macros here.
  30. //}}AFX_MSG_MAP
  31. END_MESSAGE_MAP()
  32. CWnd* CSplitterWndEx::GetActivePane(int* pRow, int* pCol)
  33. {
  34. ASSERT_VALID(this);
  35. CWnd* pView = GetFocus();
  36. // make sure the pane is a child pane of the splitter
  37. if (pView != NULL && !IsChildPane(pView, pRow, pCol))
  38. {
  39. pView = NULL;
  40. }
  41. return pView;
  42. }
  43. void CSplitterWndEx::SetActivePane( int row, int col, CWnd* pWnd)
  44. {
  45. // set the focus to the pane
  46. CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;
  47. pPane->SetFocus();
  48. }
  49. void CSplitterWndEx::StartTracking(int ht)
  50. {
  51. ASSERT_VALID(this);
  52. if (ht == noHit)
  53. {
  54. return;
  55. }
  56. // GetHitRect will restrict 'm_rectLimit' as appropriate
  57. GetInsideRect(m_rectLimit);
  58. if (ht >= splitterIntersection1 && ht <= splitterIntersection225)
  59. {
  60. // split two directions (two tracking rectangles)
  61. int row = (ht - splitterIntersection1) / 15;
  62. int col = (ht - splitterIntersection1) % 15;
  63. GetHitRect(row + vSplitterBar1, m_rectTracker);
  64. int yTrackOffset = m_ptTrackOffset.y;
  65. m_bTracking2 = TRUE;
  66. GetHitRect(col + hSplitterBar1, m_rectTracker2);
  67. m_ptTrackOffset.y = yTrackOffset;
  68. }
  69. else if (ht == bothSplitterBox)
  70. {
  71. // hit on splitter boxes (for keyboard)
  72. GetHitRect(vSplitterBox, m_rectTracker);
  73. int yTrackOffset = m_ptTrackOffset.y;
  74. m_bTracking2 = TRUE;
  75. GetHitRect(hSplitterBox, m_rectTracker2);
  76. m_ptTrackOffset.y = yTrackOffset;
  77. // center it
  78. m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2);
  79. m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);
  80. }
  81. else
  82. {
  83. // only hit one bar
  84. GetHitRect(ht, m_rectTracker);
  85. }
  86. // steal focus and capture
  87. SetCapture();
  88. SetFocus();
  89. // make sure no updates are pending
  90. RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
  91. // set tracking state and appropriate cursor
  92. m_bTracking = TRUE;
  93. OnInvertTracker(m_rectTracker);
  94. if (m_bTracking2)
  95. {
  96. OnInvertTracker(m_rectTracker2);
  97. }
  98. m_htTrack = ht;
  99. SetSplitCursor(ht);
  100. }
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CSplitterWnd command routing
  103. BOOL CSplitterWndEx::OnCommand(WPARAM wParam, LPARAM lParam)
  104. {
  105. if (CWnd::OnCommand(wParam, lParam))
  106. {
  107. return TRUE;
  108. }
  109. // route commands to the splitter to the parent frame window
  110. return (BOOL) GetParent()->SendMessage(WM_COMMAND, wParam, lParam);
  111. }
  112. BOOL CSplitterWndEx::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
  113. {
  114. if (CWnd::OnNotify(wParam, lParam, pResult))
  115. {
  116. return TRUE;
  117. }
  118. // route commands to the splitter to the parent frame window
  119. *pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);
  120. return TRUE;
  121. }
  122. BOOL CSplitterWndEx::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  123. {
  124. // The code line below is necessary if using CSplitterWndEx in a regular dll
  125. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  126. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  127. }