#include "StdAfx.h" #include "SigmaDoc.h" #include "ItemCopyAsImage.h" #include "HSimpleTracker.h" #include "ItemExportFile.H" #include "DCHelp.h" namespace NItem { CItemCopyAsImage::CItemCopyAsImage(CSigmaDoc* ppDoc) :CItem(ppDoc) { m_pTracker = new CHSimpleTracker(); this->SetType(ITEM_COPY_AS_IMAGE); } CItemCopyAsImage::~CItemCopyAsImage() { m_pTracker->Reset(); delete m_pTracker; m_pTracker = NULL; } int CItemCopyAsImage::SetRange(CRect rect) { GetDoc()->SetCapturedScreenStatus(false); if (rect.IsRectEmpty()) { m_range.SetRectEmpty(); m_pTracker->Reset(); return -1; } m_range = rect; m_pTracker->Create(m_pDoc, m_range); CopySelectedToClipboard(); GetDoc()->SetCapturedScreenStatus(true); return 1; } CHSimpleTracker * CItemCopyAsImage::GetTracker() { return m_pTracker; } void CItemCopyAsImage::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (m_range.IsRectEmpty()) return; m_pTracker->LButtonDown(point.x, point.y); } void CItemCopyAsImage::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (m_range.IsRectEmpty()) return; m_pTracker->LButtonUp(point.x, point.y, pDC); if (m_range.IsRectEmpty() == false) CopySelectedToClipboard(); } int CItemCopyAsImage::OnMouseMove(CDC *pDC, UINT nFlags, CPoint point) { if (m_range.IsRectEmpty()) return 1; CDC * pScreenDC = pDC; DCHelp::ClearDC(pScreenDC, m_BackColor); pScreenDC->BitBlt(0, 0, m_client.Width(), m_client.Height(), m_pBackGroundDC, 0, 0, SRCCOPY); m_pTracker->MouseMove(pDC, point.x, point.y); return 1; } void CItemCopyAsImage::OnDraw(CXyDC* pDC) { if (m_range.IsRectEmpty()) return; m_pTracker->Draw(pDC->GetDC()); CopySelectedToClipboard(); GetDoc()->SetCapturedScreenStatus(true); } void CItemCopyAsImage::DrawAssistant(CDC * pDC, int mouseX, int mouseY) { m_pTracker->Draw(pDC); } bool CItemCopyAsImage::CopySelectedToClipboard() { CRect rect = m_pTracker->GetBoundRect(); if (rect.IsRectEmpty()) return false; CRect8 realRect = GetDC()->GetReal(rect); CopyToClipboard(realRect); return true; } void CItemCopyAsImage::CopyToClipboard(CRect8 & rect, int nScale) { // 获取 1:1 情况下的屏幕矩形 CRect rtFull = GetDC()->GetScreen(rect); if (rtFull.IsRectEmpty()) return; // 计算缩放后的目标尺寸 CSize szTarget(rtFull.Width() / nScale, rtFull.Height() / nScale); if (szTarget.cx <= 0 || szTarget.cy <= 0) return; // 记录原始偏移并平移 DC 坐标系到绘图起始点 double dx = rect.left - GetDC()->left; double dy = rect.top - GetDC()->top; GetDC()->OffsetRect(dx, dy); // 临时调整 DC 的缩放比例 double oldScaleX = 0; double oldScaleY = 0; GetDC()->GetScale(oldScaleX, oldScaleY); // 备份原比例 GetDC()->SetScale(oldScaleX / nScale, oldScaleY/ nScale); // 应用新比例 // ------------------------------------- CItemExportFile ef(GetDoc()); // 现在 ExportImage 内部调用 Draw 时,会因为 DC 比例变小而绘制全图到 szTarget 尺寸的画布上 CMemoryDC* pmdc = ef.ExportImage(szTarget, 24); if (pmdc) { pmdc->CopyToClipboard(); delete pmdc; } // 恢复原比例 GetDC()->SetScale(oldScaleX, oldScaleY); GetDC()->OffsetRect(-dx, -dy); } //截取整个绘图窗口 void NItem::CItemCopyAsImage::CopyWindowToClipboard(CRect windowRect) { CRect8 rect = GetDC()->GetReal(windowRect); CopyToClipboard(rect); } //截取全图.相当于先全图缩放.在截取整个绘图窗口 void NItem::CItemCopyAsImage::CopyAllToClipboard(int nScale) { if (nScale <= 0) nScale = 1; //获得导出图件的大小 CRect8 rect(1e100, -1e100, -1e100, 1e100); GetDoc()->GetDrawRange(rect); double dx = rect.Width(); double dy = rect.Height(); CSize sz(GetDC()->GetScreenWidth(dx), abs(GetDC()->GetScreenHeight(dy))); if (dx < -1e20 || dy < -1e20) { AfxMessageBox("Map Range Error"); return; } CopyToClipboard(rect, nScale); } void CItemCopyAsImage::GetAllImageSize(int& width, int& height) { CRect8 rect(1e100, -1e100, -1e100, 1e100); GetDoc()->GetDrawRange(rect); CRect rt = GetDC()->GetScreen(rect); width = rt.Width(); height = rt.Height(); } } //end namespace