DividerCtrl.cpp
上传用户:hawkcdm
上传日期:2013-02-10
资源大小:411k
文件大小:5k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. // DividerCtrl.cpp : implementation file
  2. //
  3. // Markup Release 6.1 Lite
  4. // Copyright (C) 1999-2001 First Objective Software, Inc. All rights reserved
  5. // This entire notice must be retained in this source code
  6. // Redistributing this source code requires written permission
  7. // This software is provided "as is", with no warranty.
  8. // Latest fixes enhancements and documentation at www.firstobject.com
  9. #include "stdafx.h"
  10. #include "DividerCtrl.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CDividerCtrl
  18. CDividerCtrl::CDividerCtrl()
  19. {
  20. m_bHasCapture = FALSE;
  21. m_enumOrientation = NoOrientation;
  22. m_nOffset = 0;
  23. m_nFractionOf1000 = 0;
  24. m_nMinFraction = 0;
  25. m_nMaxFraction = 1000;
  26. m_bDisappearingBar = FALSE;
  27. m_nWidth = 8;
  28. m_nMinWidthFromEdge = 30;
  29. m_hCursor = NULL;
  30. }
  31. CDividerCtrl::~CDividerCtrl()
  32. {
  33. }
  34. BEGIN_MESSAGE_MAP(CDividerCtrl, CStatic)
  35. //{{AFX_MSG_MAP(CDividerCtrl)
  36. ON_WM_LBUTTONDOWN()
  37. ON_WM_LBUTTONUP()
  38. ON_WM_MOUSEMOVE()
  39. ON_WM_CAPTURECHANGED()
  40. //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42. void CDividerCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  43. {
  44. UNREFERENCED_PARAMETER( nFlags );
  45. // Capture mouse move messages
  46. SetSplitterCursor();
  47. SetCapture();
  48. m_bHasCapture = TRUE;
  49. // Figure out original x coordinate
  50. m_pointOrig = point;
  51. // CStatic::OnLButtonDown(nFlags, point);
  52. }
  53. void CDividerCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
  54. {
  55. SetSplitterCursor();
  56. if ( m_bHasCapture )
  57. ::ReleaseCapture();
  58. else
  59. CStatic::OnLButtonUp(nFlags, point);
  60. }
  61. void CDividerCtrl::SetSplitterCursor() 
  62. {
  63. // AFX Cursors
  64. if ( ! m_hCursor )
  65. {
  66. if ( m_enumOrientation == MoveHorizontal )
  67. m_hCursor = AfxGetApp()->LoadCursor(AFX_IDC_HSPLITBAR);
  68. else if ( m_enumOrientation == MoveVertical )
  69. m_hCursor = AfxGetApp()->LoadCursor(AFX_IDC_VSPLITBAR);
  70. }
  71. // If AFX Cursors not available, use standard windows cursors
  72. if ( ! m_hCursor )
  73. {
  74. if ( m_enumOrientation == MoveHorizontal )
  75. m_hCursor = LoadCursor( NULL, IDC_SIZEWE );
  76. else if ( m_enumOrientation == MoveVertical )
  77. m_hCursor = LoadCursor( NULL, IDC_SIZENS );
  78. }
  79. // Set cursor
  80. if ( m_hCursor )
  81. ::SetCursor(m_hCursor);
  82. }
  83. void CDividerCtrl::OnMouseMove(UINT nFlags, CPoint point) 
  84. {
  85. SetSplitterCursor();
  86. if ( m_bHasCapture )
  87. {
  88. m_pointNew = point;
  89. if ( m_enumOrientation == NoOrientation  && m_pointNew != m_pointOrig ||
  90.  m_enumOrientation == MoveHorizontal && m_pointNew.x != m_pointOrig.x ||
  91.  m_enumOrientation == MoveVertical && m_pointNew.y != m_pointOrig.y
  92.  )
  93. {
  94. CRect rect;
  95. GetParent()->GetClientRect( &rect );
  96. GetParent()->SendMessage(
  97. WM_SIZE,
  98. SIZE_RESTORED,
  99. MAKELPARAM(rect.Width(),rect.Height())
  100. );
  101. }
  102. }
  103. else
  104. CStatic::OnMouseMove(nFlags, point);
  105. }
  106. void CDividerCtrl::OnCaptureChanged(CWnd *pWnd) 
  107. {
  108. m_bHasCapture = FALSE;
  109. CStatic::OnCaptureChanged(pWnd);
  110. }
  111. int CDividerCtrl::GetWidth()
  112. {
  113. if ( m_bDisappearingBar && ( m_bAtHighEnd || m_bAtLowEnd ) )
  114. return 0;
  115. else
  116. return m_nWidth;
  117. }
  118. int CDividerCtrl::CalculateOffset( int nSizeOfRange )
  119. {
  120. // During resize, the divider offset is adjusted here
  121. // If not in mouse capture mode, maintain per cent in given range
  122. // If in mouse capture mode, adjust by mouse movement
  123. if ( m_bHasCapture )
  124. {
  125. int nAdjust = 0;
  126. if ( m_enumOrientation == MoveHorizontal )
  127. nAdjust = m_pointNew.x - m_pointOrig.x;
  128. else if ( m_enumOrientation == MoveVertical )
  129. nAdjust = m_pointNew.y - m_pointOrig.y;
  130. m_nOffset += nAdjust;
  131. m_nFractionOf1000 = m_nOffset * 1000 / nSizeOfRange;
  132. }
  133. else
  134. {
  135. m_nOffset = m_nFractionOf1000 * nSizeOfRange / 1000;
  136. }
  137. // Max and min only affect within snap-to
  138. if ( m_nMinFraction > 0 )
  139. {
  140. int nMinOffset = m_nMinFraction * nSizeOfRange / 1000;
  141. if ( m_nOffset < nMinOffset )
  142. m_nOffset = nMinOffset;
  143. }
  144. if ( m_nMaxFraction < 1000 )
  145. {
  146. int nMaxOffset = m_nMaxFraction * nSizeOfRange / 1000;
  147. if ( m_nOffset > nMaxOffset )
  148. m_nOffset = nMaxOffset;
  149. }
  150. // Keep divider within edges
  151. // Slap to edge if under min width from edge
  152. // Keep at zero if nSizeOfRange too small
  153. m_bAtLowEnd = FALSE;
  154. m_bAtHighEnd = FALSE;
  155. if ( m_nOffset > nSizeOfRange - m_nMinWidthFromEdge - m_nWidth )
  156. {
  157. if ( m_bDisappearingBar )
  158. m_nOffset = nSizeOfRange;
  159. else
  160. m_nOffset = nSizeOfRange - m_nWidth;
  161. m_bAtHighEnd = TRUE;
  162. }
  163. if ( m_nOffset < m_nMinWidthFromEdge )
  164. {
  165. m_nOffset = 0;
  166. m_bAtLowEnd = TRUE;
  167. }
  168. return m_nOffset;
  169. }