QSelectTracker.cpp
上传用户:xp9161
上传日期:2009-12-21
资源大小:70k
文件大小:4k
源码类别:

Windows编程

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////
  2. // QSelectTracker
  3. //===============================
  4. // Version 1.0, August 29, 2003
  5. // (c) Sjaak Priester, Amsterdam
  6. // www.sjaakpriester.nl
  7. //
  8. // Freeware. Use at your own risk. Comments welcome.
  9. #include "StdAfx.h"
  10. #include "QSelectTracker.h"
  11. QSelectTracker::QSelectTracker(CWnd * pWnd)
  12. : QTracker(pWnd)
  13. , m_pTrackPen(0)
  14. , m_CenterSize(4)
  15. , m_colorCenter(RGB(0, 0, 0))
  16. {
  17. SetTrackPen(0);
  18. }
  19. QSelectTracker::~QSelectTracker()
  20. {
  21. delete m_pTrackPen;
  22. }
  23. int QSelectTracker::OnBeginTrack(UINT nFlags, CPoint point)
  24. {
  25. m_Rect.SetRectEmpty();
  26. m_Rect.OffsetRect(point);
  27. return QTracker::OnBeginTrack(nFlags, point);
  28. }
  29. int QSelectTracker::OnEndTrack(int trackResult)
  30. {
  31. if (trackResult <= 0) m_Rect.SetRectEmpty();
  32. return trackResult;
  33. }
  34. int QSelectTracker::OnMouseMessage(UINT msg, UINT nFlags, CPoint point)
  35. {
  36. // If spacebar is pressed, move the rectangle
  37. if (::GetAsyncKeyState(VK_SPACE) < 0)
  38. {
  39. if (nFlags & MK_SHIFT)
  40. {
  41. point = RestrictPoint(point, m_StartPoint, FALSE);
  42. m_Point = point;
  43. }
  44. CSize sz = point - m_PreviousPoint;
  45. m_Rect.OffsetRect(sz);
  46. }
  47. else
  48. {
  49. if (nFlags & MK_SHIFT)
  50. {
  51. point = RestrictPoint(point, m_Rect.CenterPoint(), TRUE);
  52. m_Point = point;
  53. }
  54. if (::GetAsyncKeyState(VK_MENU) < 0) // Alt pressed
  55. {
  56. CPoint pCenter = m_Rect.CenterPoint();
  57. CSize sz = point - pCenter;
  58. m_Rect.TopLeft() = pCenter - sz;
  59. }
  60. m_Rect.BottomRight() = point;
  61. }
  62. return QTracker::OnMouseMessage(msg, nFlags, point);
  63. }
  64. void QSelectTracker::OnUpdate(CDC * pDC, UINT nMode)
  65. {
  66. ASSERT_VALID(pDC);
  67. ASSERT_VALID(m_pTrackPen);
  68. CPen * pOldPen = (CPen *) pDC->SelectObject(m_pTrackPen);
  69. pDC->Rectangle(& m_Rect);
  70. if (pOldPen) pDC->SelectObject(pOldPen);
  71. DrawCenter(pDC);
  72. }
  73. void QSelectTracker::DrawCenter(CDC * pDC)
  74. {
  75. int d = 2 * m_CenterSize;
  76. if (m_CenterSize
  77. && abs(m_Rect.Width()) > d
  78. && abs(m_Rect.Height()) > d)
  79. {
  80. CPoint pCenter = m_Rect.CenterPoint();
  81. CPen pen(PS_SOLID, 0, m_colorCenter);
  82. CPen * pOldPen = (CPen *) pDC->SelectObject(& pen);
  83. pDC->MoveTo(pCenter.x - m_CenterSize, pCenter.y);
  84. pDC->LineTo(pCenter.x + m_CenterSize, pCenter.y);
  85. pDC->MoveTo(pCenter.x, pCenter.y - m_CenterSize);
  86. pDC->LineTo(pCenter.x, pCenter.y + m_CenterSize);
  87. if (pOldPen) pDC->SelectObject(pOldPen);
  88. }
  89. }
  90. // Set the pen of the track rectangle; if 0, use default (1 pixel dotted black).
  91. void QSelectTracker::SetTrackPen(CPen * pPen)
  92. {
  93. delete m_pTrackPen;
  94. if (pPen) m_pTrackPen = pPen;
  95. else
  96. {
  97. if (_winmajor > 4)
  98. {
  99. LOGBRUSH lb;
  100. lb.lbColor = RGB(0, 0, 0);
  101. lb.lbHatch = 0;
  102. lb.lbStyle = BS_SOLID;
  103. m_pTrackPen = new CPen(PS_COSMETIC | PS_ALTERNATE, 1, & lb);
  104. }
  105. else m_pTrackPen = new CPen(PS_SOLID, 0, RGB(192, 192, 192));
  106. // PS_ALTERNATE not supported on W98
  107. }
  108. }
  109. // Restrict point to horizontal, vertical or diagonal with respect to pntBase
  110. CPoint QSelectTracker::RestrictPoint(CPoint point, CPoint pntBase, BOOL bDiagonalOnly)
  111. {
  112. // distance
  113. CSize d = point - pntBase;
  114. int cxAbs = abs(d.cx);
  115. int cyAbs = abs(d.cy);
  116. BOOL bHandled = FALSE;
  117. if (! bDiagonalOnly)
  118. {
  119. if (cxAbs > 2 * cyAbs) // 0 degrees
  120. {
  121. point.y = pntBase.y;
  122. bHandled = TRUE;
  123. }
  124. else if (cyAbs > 2 * cxAbs) // 90 degrees
  125. {
  126. point.x = pntBase.x;
  127. bHandled = TRUE;
  128. }
  129. }
  130. if (! bHandled) // 45 degrees
  131. {
  132. if (cxAbs > cyAbs)
  133. point.x = pntBase.x + ((d.cx < 0) ? -cyAbs : cyAbs);
  134. else point.y = pntBase.y + ((d.cy < 0) ? -cxAbs : cxAbs);
  135. }
  136. return point;
  137. }