#include "stdafx.h" #include "ItemMeasure.h" #include "Util.h" #include "SigmaDoc.h" namespace NItem { CItemMeasure::CItemMeasure(CSigmaDoc* ppDoc) : CItem(ppDoc) { SetType(ITEM_MEASURE); m_pSpatialIndex = std::make_unique(*GetDoc()->GetDraw()); } CItemMeasure::~CItemMeasure() { } void CItemMeasure::OnLButtonDblClk(UINT nFlags, CPoint point) { } void CItemMeasure::OnLButtonDown(CDC* pDC, UINT nFlags, CPoint point, int vk) { if (m_state == MeasureState::Idle) { m_state = MeasureState::SelectingStart; std::optional adsPoint = GetSnapPoint(point); CPoint2D realPoint = adsPoint ? adsPoint.value() : GetDC()->GetReal(point); m_startPoint = realPoint; m_prevPoint = m_startPoint; } } void CItemMeasure::OnLButtonUp(CDC* pDC, UINT nFlags, CPoint point, int vk) { if (m_state == MeasureState::SelectingStart) { m_endPoint = point; DrawAssistant(pDC, point.x, point.y); m_state = MeasureState::Idle; } } int CItemMeasure::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point) { if (m_state == MeasureState::SelectingStart) { CPen pen(PS_SOLID, m_penWidth, m_penColor); // 保存当前状态 CPen* pOldPen = pDC->SelectObject(&pen); int oldROP2 = pDC->SetROP2(R2_NOTXORPEN); std::optional adsPoint = GetSnapPoint(point); CPoint2D realPoint = adsPoint ? adsPoint.value() : GetReal(point); m_endPoint = realPoint; CPoint cPoint = GetScreenPoint(realPoint); CPoint startPoint = GetScreenPoint(m_startPoint); CPoint prevPoint = GetScreenPoint(m_prevPoint); // 擦除前一次的线 pDC->MoveTo(startPoint); pDC->LineTo(prevPoint); // 绘制新线 pDC->MoveTo(startPoint); pDC->LineTo(cPoint); // 恢复状态 pDC->SelectObject(pOldPen); pDC->SetROP2(oldROP2); m_prevPoint = GetReal(cPoint); } return 0; } void CItemMeasure::OnMouseMoveStatus(CDC* pDC, UINT nFlags, CPoint point, BYTE*& destBuffer, int& destLen) { if (m_state == MeasureState::SelectingStart) { } } BOOL CItemMeasure::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { return 0; } BOOL CItemMeasure::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { if (nChar == VK_ESCAPE) { return TRUE; } return FALSE; } BOOL CItemMeasure::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { return 0; } void CItemMeasure::OnDraw(CXyDC* pDC) { } void CItemMeasure::OnDraw(CXyDC* pXyDC, CDC* pDC) { } void CItemMeasure::DrawAssistant(CDC* pDC, int mouseX, int mouseY) { if (m_state == MeasureState::SelectingStart) { CPoint startPoint = GetScreenPoint(m_startPoint); DrawLineScreen(startPoint.x, startPoint.y, mouseX, mouseY); } } void CItemMeasure::OnOK(void) { m_state = MeasureState::SelectingEnd; } void CItemMeasure::OnCancel(void) { m_state = MeasureState::Idle; } CString CItemMeasure::GetCurrentInfo() const { if (m_state == MeasureState::SelectingStart) { double distance = CalcDistance(m_startPoint.x0, m_startPoint.y0, m_endPoint.x0, m_endPoint.y0); double angle = AfxGetPublicFunction()->GetAngle(m_startPoint.x0, m_startPoint.y0, m_endPoint.x0, m_endPoint.y0); double width = fabs(m_endPoint.x0 - m_startPoint.x0); double height = fabs(m_endPoint.y0 - m_startPoint.y0); CString str; str.Format("距离: %lf, 角度: %.2lf, (%.6lf x %.6lf)\n", distance, angle, width, height); return str; } return CString(); } void CItemMeasure::EnableSnap() { m_isSnapEnabled = true; } void CItemMeasure::DisableSnap() { m_isSnapEnabled = false; } bool CItemMeasure::IsSnapEnabled() const { return m_isSnapEnabled; } void CItemMeasure::DrawCross(Gdiplus::Graphics& graphics, Gdiplus::PointF center, int length, const Gdiplus::Pen& pen) const { Gdiplus::PointF horizontalStart(center.X - length, center.Y); Gdiplus::PointF horizontalEnd(center.X + length, center.Y); Gdiplus::PointF verticalStart(center.X, center.Y - length); Gdiplus::PointF verticalEnd(center.X, center.Y + length); graphics.DrawLine(&pen, horizontalStart, horizontalEnd); graphics.DrawLine(&pen, verticalStart, verticalEnd); } CPoint CItemMeasure::GetScreenPoint(const CPoint2D& realPoint) const { return const_cast(this)->GetDC()->GetScreen(realPoint.x0, realPoint.y0); } std::optional CItemMeasure::GetSnapPoint(const CPoint& point) const { if (!m_isSnapEnabled) { return const_cast(this)->GetReal(point); } CItemMeasure* mutItem = const_cast(this); CPoint2D realPoint = mutItem->GetDC()->GetReal(point.x, point.y); double realRadius = mutItem->GetDC()->GetRealWidth(m_snapRange); return m_pSpatialIndex->GetSnapPoint(realPoint, realRadius); } }