#include "stdafx.h" #include "HTrackerDrawer.h" static void _PaintArrow(CXyDC& dc, CPoint p1, CPoint p2); HTrackerDrawer::HTrackerDrawer() { m_HandleSize = 12; m_colorMark = RGB(192, 192, 192); m_colorHandles = RGB(0, 0, 0); m_colorCenter = RGB(0, 0, 0); m_rotateAndShearState = false; } void HTrackerDrawer::SetRotateAndShearState(bool status) { m_rotateAndShearState = status; } void HTrackerDrawer::Draw(CDC * pDC, const CRect & boundRect) { m_boundRect = boundRect; m_handleCalctor.Calculate(boundRect); // All drawing is done in NOT-XOR mode. int nOldRop = pDC->SetROP2(R2_NOTXORPEN); if (this->m_rotateAndShearState) { pDC->Rectangle(&m_boundRect); //画外包矩形 DrawCenterRotate(pDC, m_handleCalctor.GetCenterPoint(), FALSE); DrawMarkRotate(pDC); } else { DrawCenter(pDC, m_handleCalctor.GetCenterPoint(), FALSE); DrawMarkRect(pDC); } pDC->SetROP2(nOldRop); } void HTrackerDrawer::Reset() { m_rotateAndShearState = false; } void HTrackerDrawer::DrawMarkRect(CDC * pDC) { ASSERT_VALID(pDC); CGdiObject * pOldBrush = pDC->SelectStockObject(NULL_BRUSH); CPen * pMarkPen = new CPen(PS_SOLID, 0, m_colorMark); CGdiObject * pOldPen = NULL; if (pMarkPen) pOldPen = pDC->SelectObject(pMarkPen); //CRect rc(m_boundRect); //if (!m_bOnlyMove) pDC->Rectangle(&m_boundRect); //画外包矩形 //if (IsRotateState()) // DrawMarkRotate(pDC, rc); //else //DrawMarkRect(pDC, rc, m_bOnlyMove); DrawHandleRect(pDC, m_boundRect, FALSE); if (pOldPen) pDC->SelectObject(pOldPen); if (pOldBrush) pDC->SelectObject(pOldBrush); delete pMarkPen; } void HTrackerDrawer::DrawHandleRect(CDC* pDC, CRect rect, BOOL bNoEditMark) { if (bNoEditMark) pDC->SelectStockObject(BLACK_BRUSH); CPen penHandles(PS_SOLID, 0, m_colorHandles); CPen * op = (CPen*)pDC->SelectObject(&penHandles); //GetPoint(rect, m_PointTemp, !bNoEditMark); CRect rc; CPoint pt; for (int i = 0; i < 8; i++) { //rc = GetHandleRect(m_PointTemp, i); rc = m_handleCalctor.GetHandleRect(i); if (bNoEditMark) rc.DeflateRect(2, 2); pDC->Rectangle(rc); //画八个小矩形 } pDC->SelectObject(op); if (bNoEditMark) pDC->SelectStockObject(NULL_BRUSH); } void HTrackerDrawer::DrawCenter(CDC * pDC, POINT center, bool bTrack) { //if (IsRotateState()) //{ // DrawCenterRotate(pDC, center, bTrack); // return; //} //ASSERT_VALID(pDC); //if (!(m_Options & OptionCenter)) // return; CPen pen(PS_SOLID, 2, m_colorCenter); CGdiObject * pOldPen = pDC->SelectObject(&pen); CRect rcInside(center, center); rcInside.InflateRect(m_HandleSize, m_HandleSize); pDC->MoveTo(rcInside.TopLeft()); pDC->LineTo(rcInside.BottomRight()); pDC->MoveTo(rcInside.right, rcInside.top); pDC->LineTo(rcInside.left, rcInside.bottom); if (pOldPen) pDC->SelectObject(pOldPen); } void HTrackerDrawer::DrawMarkRotate(CDC* pDC) { CXyDC dc; dc.Create(pDC); CPen pen(PS_SOLID, 0, RGB(0, 0, 0)); CPen* pOldPen = (CPen*)pDC->SelectObject(&pen); CGdiObject * pOldBrush = pDC->SelectStockObject(BLACK_BRUSH); m_boundRect.InflateRect(2, 2); CPoint p1, p2; CSize sz(6, 6); CPoint cp = m_boundRect.CenterPoint(); //左边中间点 p1.SetPoint(m_boundRect.left, cp.y); p2.SetPoint(m_boundRect.left, cp.y - sz.cy / 2); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.left, cp.y + sz.cy / 2); _PaintArrow(dc, p2, p1); //右边中间点 p1.SetPoint(m_boundRect.right, cp.y); p2.SetPoint(m_boundRect.right, cp.y - sz.cy / 2); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.right, cp.y + sz.cy / 2); _PaintArrow(dc, p2, p1); //上边中间点 p1.SetPoint(cp.x, m_boundRect.top); p2.SetPoint(cp.x - sz.cx / 2, m_boundRect.top); _PaintArrow(dc, p2, p1); p2.SetPoint(cp.x + sz.cx / 2, m_boundRect.top); _PaintArrow(dc, p2, p1); //下边中间点 p1.SetPoint(cp.x, m_boundRect.bottom); p2.SetPoint(cp.x - sz.cx / 2, m_boundRect.bottom); _PaintArrow(dc, p2, p1); p2.SetPoint(cp.x + sz.cx / 2, m_boundRect.bottom); _PaintArrow(dc, p2, p1); CSize sd(1, 1); sz.SetSize(5, 5); m_boundRect.DeflateRect(1, 1); //左下 p1.SetPoint(m_boundRect.left, m_boundRect.bottom); p2.SetPoint(m_boundRect.left + sz.cx, m_boundRect.bottom + sd.cy); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.left - sd.cx, m_boundRect.bottom - sz.cx); _PaintArrow(dc, p2, p1); //左上 p1.SetPoint(m_boundRect.left, m_boundRect.top); p2.SetPoint(m_boundRect.left + sz.cx, m_boundRect.top - sd.cy); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.left - sd.cx, m_boundRect.top + sz.cx); _PaintArrow(dc, p2, p1); //右上 p1.SetPoint(m_boundRect.right, m_boundRect.top); p2.SetPoint(m_boundRect.right - sz.cx, m_boundRect.top - sd.cy); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.right + sd.cx, m_boundRect.top + sz.cx); _PaintArrow(dc, p2, p1); //右下 p1.SetPoint(m_boundRect.right, m_boundRect.bottom); p2.SetPoint(m_boundRect.right - sz.cx, m_boundRect.bottom + sd.cy); _PaintArrow(dc, p2, p1); p2.SetPoint(m_boundRect.right + sd.cx, m_boundRect.bottom - sz.cx); _PaintArrow(dc, p2, p1); if (pOldPen) pDC->SelectObject(pOldPen); if (pOldBrush) pDC->SelectObject(pOldBrush); } void HTrackerDrawer::DrawCenterRotate(CDC * pDC, POINT center, bool bTrack) { CPen pen(PS_SOLID, 0, m_colorCenter); CGdiObject * pOldPen = pDC->SelectObject(&pen); CRect rcInside(center, CSize(0, 0)); int d = m_HandleSize / 2; if (bTrack) d++; CGdiObject * pOldBrush = pDC->SelectStockObject(NULL_BRUSH); rcInside.InflateRect(d, d); pDC->Ellipse(&rcInside); rcInside.InflateRect(d, d); CRect rcOutside(rcInside); pDC->SelectObject(pOldBrush); rcOutside.InflateRect(m_HandleSize, m_HandleSize); pDC->MoveTo(center.x, rcInside.top); pDC->LineTo(center.x, rcOutside.top); pDC->MoveTo(rcInside.right, center.y); pDC->LineTo(rcOutside.right, center.y); pDC->MoveTo(center.x, rcInside.bottom); pDC->LineTo(center.x, rcOutside.bottom); pDC->MoveTo(rcInside.left, center.y); pDC->LineTo(rcOutside.left, center.y); if (pOldPen) pDC->SelectObject(pOldPen); } static BOOL GetArrow3Point(CPoint p1, CPoint p2, CPoint* pt) { double cosx = p1.x - p2.x; double sinx = p1.y - p2.y; sinx = sqrt(sinx*sinx + cosx * cosx); if (sinx < 1e-30) { return FALSE; } cosx = cosx / sinx; sinx = (p1.y - p2.y) / sinx; double cy = 7; pt[0].x = AfxGetPublicFunction()->FloatToLong(p1.x + 1.0*cy*cosx); pt[0].y = AfxGetPublicFunction()->FloatToLong(p1.y + 1.0*cy*sinx); pt[1].x = AfxGetPublicFunction()->FloatToLong(p1.x + 0.4*cy*sinx); pt[1].y = AfxGetPublicFunction()->FloatToLong(p1.y - 0.4*cy*cosx); pt[2].x = AfxGetPublicFunction()->FloatToLong(p1.x - 0.4*cy*sinx); pt[2].y = AfxGetPublicFunction()->FloatToLong(p1.y + 0.4*cy*cosx); return TRUE; } static void _PaintArrow(CXyDC& dc, CPoint p1, CPoint p2) { dc.GetDC()->MoveTo(p1); dc.GetDC()->LineTo(p2); static CPoint pt[3]; if (GetArrow3Point(p1, p2, pt)) dc.PaintRgn(pt, 3); }