#include "stdafx.h" #include "SigmaDoc.h" #include "ItemCopyAsImageEx.h" #include "ItemExportFile.H" #include "MxnFormat\AxisLayout.h" #include "gdiplus.h" using namespace Gdiplus; NItem::CItemCopyAsImageEx::CItemCopyAsImageEx(CSigmaDoc * ppDoc) : CItemRectTracker(ppDoc) , m_color(0) , m_ShowProportion(false) , m_ShowNetGrid(false) { this->SetType(ITEM_COPY_AS_IMAGE_EX); m_coorRect.Empty(); m_Proportion.m_dScaleLength = 2000; } NItem::CItemCopyAsImageEx::~CItemCopyAsImageEx() { } void NItem::CItemCopyAsImageEx::SetProportionVisible(bool visible) { m_ShowProportion = visible; } void NItem::CItemCopyAsImageEx::SetNetGridVisible(bool visible) { m_ShowNetGrid = visible; } void NItem::CItemCopyAsImageEx::SetNetGridParameter(RectangularCSGridData* pData) { // 网格颜色 m_color = RGB(pData->girdColorR, pData->girdColorG, pData->girdColorB); // 网格步长 m_Net.m_step.SetSize(pData->stepX, pData->stepY); m_Net.ScaleProperty(1000, 1000); m_Net.SetProjection(&(GetDoc()->GetDraw()->m_ExchangeXYZ)); // 基数 m_Net.m_ptBase.x0 = pData->baseX; m_Net.m_ptBase.y0 = pData->baseY; // 系数 m_Net.m_szCoefficient.cx = pData->coefficientX; m_Net.m_szCoefficient.cy = pData->coefficientY; // 文字尺寸 m_Net.m_szText.cy = pData->textHeight; m_Net.m_szText.cx = pData->textHeight*0.4; // 文字刻度方式 switch (pData->textScale) { case 0: m_Net.SetTextMode(CNet::textGeography); break;//地理 case 1: m_Net.SetTextMode(CNet::textMath); break;//数学 case 2: m_Net.SetTextMode(CNet::textGeography1); break;//地理1 default: case 3: m_Net.SetTextMode(CNet::textGeography2); break;//地理2(all) } // 坐标网显示方式 switch (pData->showMode) { default: case 0: m_Net.SetDisplayMode(CNet::showLine); break;//显示曲线 case 1: m_Net.SetDisplayMode(CNet::showCrossPoint); break;//显示交点 case 2: m_Net.SetDisplayMode(CNet::showNull); break;//显示为空1 } // 外边框 m_Net.EnableOutFrame(pData->isShowOutBorder ? true : false); // 是否显示 COLORREF colFrame = RGB(pData->borderColorR, pData->borderColorG, pData->borderColorB); m_Net.SetFrameColor(colFrame); // 边框颜色 m_Net.GetOutFrame()->EnableBlackLine(pData->blackOutterBorder); // 显示黑边框 m_Net.GetOutFrame()->thickness = GetUnitMode().toRealUnit(pData->borderThickness); // 边框厚度 } void NItem::CItemCopyAsImageEx::Clear() { //m_range.SetRectEmpty(); m_coorRect.Empty(); } int NItem::CItemCopyAsImageEx::SetRange(CRect rect) { //GetDoc()->SetCapturedScreenStatus(false); if (rect.IsRectEmpty()) { m_range.SetRectEmpty(); //m_pTracker->Reset(); return -1; } m_range = rect; m_coorRect = GetDC()->GetReal(rect); // 自动计算坐标网的尺寸 //(CRect8)m_Net = m_coorRect; m_Net.left = m_coorRect.left; m_Net.right = m_coorRect.right; m_Net.top = m_coorRect.top; m_Net.bottom = m_coorRect.bottom; CAxisLayout al(m_coorRect.left, m_coorRect.right, 1); TIntervalStep sx = al.sd; al.setDataRange(m_coorRect.bottom, m_coorRect.top, 1); double step = min(sx.step, al.sd.step); m_Net.m_step.SetSize(step, step); m_Net.SetDisplayMode(CNet::showNull); //自动根据单位设置文字大小 double scale = GetDoc()->GetCurrentUnitScale(); m_Net.ScaleProperty(scale, scale); //m_pTracker->Create(m_pDoc, m_range); //CopySelectedToClipboard(); //GetDoc()->SetCapturedScreenStatus(true); return 1; } void NItem::CItemCopyAsImageEx::GetRange(CRect8* rec) { rec->left = m_coorRect.left; rec->right = m_coorRect.right; rec->bottom = m_coorRect.bottom; rec->top = m_coorRect.top; } void NItem::CItemCopyAsImageEx::Refresh(CDC* pDC) { if (m_coorRect.IsEmpty()) return; m_tracker.m_rect = GetDC()->GetScreen(m_coorRect); CPoint2D ptCenter = m_coorRect.CenterPoint(); // 绘制坐标框 // 绘制比例尺 if (m_ShowProportion) { CRect8 rct = m_Proportion.GetRect(); double dWidth = rct.Width(); double dHeight = rct.Height(); double dX = ptCenter.x0 - dWidth * 0.5; double dY = m_coorRect.top + dHeight * 0.3; m_Proportion.x0 = dX; m_Proportion.y0 = dY; CDC* pDCOld = GetDC()->GetDC(); GetDC()->Create(pDC); GetDC()->Draw(m_Proportion, m_color); GetDC()->Create(pDCOld); } if (m_ShowNetGrid) { // 自动计算坐标网的尺寸 (CRect8)m_Net = m_coorRect; //if (!GetDoc()->GetDraw()->GetProjection().IsEmpty()) //{ // m_Net.SetProjection(&(GetDoc()->GetDraw()->m_ExchangeXYZ)); // //自动计算步长 // CRect8 rectBL = m_Net.GetRangeBL(); // double step = min(rectBL.Width() / 5, rectBL.Height() / 5); // step *= 60; //转换为分单位 // step = AfxGetPublicFunction()->GetLBStep(step); // m_Net.m_step.SetSize(step, step); //} ////自动根据单位设置文字大小 //double scale = GetDoc()->GetCurrentUnitScale(); //m_Net.ScaleProperty(scale, scale); CDC* pDCOld = GetDC()->GetDC(); GetDC()->Create(pDC); GetDC()->Draw(m_Net, m_color, m_color); GetDC()->Create(pDCOld); } } void NItem::CItemCopyAsImageEx::GetTrueRect(CRect8* lpTrueRect) { *lpTrueRect = m_coorRect; if (m_ShowNetGrid) { m_Net.GetRange(*lpTrueRect); lpTrueRect->right += 1; } if (m_ShowProportion) { CRect8 rct; rct = m_Proportion.GetRect(); lpTrueRect->top = rct.top; } } void NItem::CItemCopyAsImageEx::DrawShadow(CDC *pDC, CRect &rectScreen, CRect rectCenter) { Gdiplus::SolidBrush brushTrans(Gdiplus::Color(228, 255, 255, 255)); Gdiplus::Graphics graphics(pDC->m_hDC); graphics.FillRectangle(&brushTrans, 0, 0, rectScreen.right, rectCenter.top); graphics.FillRectangle(&brushTrans, 0, rectCenter.top, rectCenter.left, rectCenter.bottom - rectCenter.top); graphics.FillRectangle(&brushTrans, rectCenter.right, rectCenter.top , rectScreen.right - rectCenter.right, rectCenter.bottom - rectCenter.top); graphics.FillRectangle(&brushTrans, 0, rectCenter.bottom , rectScreen.right, rectScreen.bottom - rectCenter.bottom); } void NItem::CItemCopyAsImageEx::DrawNetGrid(CDC* pDC) { // 自动计算坐标网的尺寸 m_Net.left = m_coorRect.left; m_Net.right = m_coorRect.right; m_Net.top = m_coorRect.top; m_Net.bottom = m_coorRect.bottom; CDC* pDCOld = GetDC()->GetDC(); GetDC()->Create(pDC); GetDC()->Draw(m_Net, m_color, m_color); GetDC()->Create(pDCOld); } void NItem::CItemCopyAsImageEx::DrawScaleBar(CDC* pDC) { if (m_Proportion.m_size.cx <= 0 || m_Proportion.m_size.cy <= 0) { double dx = m_Proportion.m_dScaleLength * m_Proportion.m_dCoefficient; m_Proportion.m_size.cy = dx * 0.2;// 0.1 m_Proportion.m_size.cx = m_Proportion.m_size.cy * 0.4; } CPoint2D ptCenter = m_coorRect.CenterPoint(); CRect8 rct; // m_Proportion.GetRange(rct); rct = m_Proportion.GetRect(); double dWidth = rct.Width(); double dHeight = rct.Height(); double dX = ptCenter.x0 - dWidth * 0.5; double dY = m_coorRect.top + dHeight * 0.3; m_Proportion.x0 = dX; m_Proportion.y0 = dY; if (m_ShowNetGrid) { CRect8 rectFrm; m_Net.GetRange(rectFrm); m_Proportion.y0 = rectFrm.top + dHeight * 0.2; } CDC* pDCOld = GetDC()->GetDC(); GetDC()->Create(pDC); GetDC()->Draw(m_Proportion, m_Proportion.color); GetDC()->Create(pDCOld); } void NItem::CItemCopyAsImageEx::OnDraw(CXyDC * pXyDC, CDC* pDC) { if (m_coorRect.IsEmpty()) return; m_tracker.m_rect = GetDC()->GetScreen(m_coorRect); CRect rectCenter = m_tracker.m_rect; CRect rectScreen = GetDC()->GetViewRect(); DrawShadow(pDC, rectScreen, rectCenter); // 绘制坐标框 if (m_ShowNetGrid) { DrawNetGrid(pDC); } // 绘制比例尺 if (m_ShowProportion) { DrawScaleBar(pDC); } CItemRectTracker::OnDraw(pXyDC, pDC); } int GetUnitIndex(LPCTSTR name); //{ // CStringArray units; // units.Add("公里"); // units.Add("千米"); // units.Add("千米"); // units.Add("米"); // units.Add(" (公里)"); // units.Add(" (千米)"); // units.Add(" (米)"); // int nSize = units.GetSize(); // for (int i = 0; i < nSize; i++) { // if (units.GetAt(i).Compare(name) == 0) { // return i; // } // } // return -1; //} bool GetUnitString(int index, CString& str); //{ // if (index < 0) { // return ""; // } // CStringArray units; // units.Add("公里"); // units.Add("千米"); // units.Add("米"); // units.Add(" (公里)"); // units.Add(" (千米)"); // units.Add(" (米)"); // str = units.GetAt(index); // return true; //} int NItem::CItemCopyAsImageEx::GetPropotionData(ProportionData * data) { data->x = m_Proportion.x0; data->y = m_Proportion.y0; data->ScaleLength = m_Proportion.m_dScaleLength;// *100; DWORD nViewMode = m_Proportion.GetViewMode(); int nViewModeUI = 0; if (nViewMode == CProportion::styleSimple) { nViewModeUI = 0; } else if (nViewMode == CProportion::styleContemporaneity) { nViewModeUI = 1; } else if (nViewMode == CProportion::stylePopular) { nViewModeUI = 2; } data->ViewMode = nViewModeUI; data->num = m_Proportion.num; data->Unit = GetUnitIndex(m_Proportion.m_strUnit); data->ColorR = GetRValue(m_Proportion.color); data->ColorG = GetGValue(m_Proportion.color); data->ColorB = GetBValue(m_Proportion.color); data->TextScale = m_Proportion.m_dTextScale; data->TextSpace = m_Proportion.m_dSpace; DWORD nTextAlign = m_Proportion.GetAlignsH(); int nUIAlign = 1; if (CTextFlags::alignLeft == nTextAlign) { nUIAlign = 0; } else if (CTextFlags::alignCenterH == nTextAlign) { nUIAlign = 1; } else if (CTextFlags::alignRight == nTextAlign) { nUIAlign = 2; } data->TextAlign = nUIAlign; if (m_Proportion.m_size.cx <= 0 || m_Proportion.m_size.cy <= 0) { double dx = m_Proportion.m_dScaleLength*m_Proportion.m_dCoefficient; data->TextHeight = dx * 0.2;// 0.1 data->TextWidth = data->TextHeight*0.4; } else { data->TextWidth = m_Proportion.m_size.cx; data->TextHeight = m_Proportion.m_size.cy; } return 1; } void NItem::CItemCopyAsImageEx::SetPropotionData(ProportionData * data) { m_Proportion.x0 = data->x; m_Proportion.y0 = data->y; m_Proportion.m_dScaleLength = data->ScaleLength;// / 100; switch (data->ViewMode) { case 0: m_Proportion.SetViewMode(CProportion::styleSimple); break; //普通式 case 1: m_Proportion.SetViewMode(CProportion::styleContemporaneity); break; //现代式 case 2: m_Proportion.SetViewMode(CProportion::stylePopular); break; //流行式 } m_Proportion.num = data->num; GetUnitString(data->Unit, m_Proportion.m_strUnit); m_Proportion.color = RGB(data->ColorR, data->ColorG, data->ColorB); m_Proportion.m_dTextScale = data->TextScale; m_Proportion.m_dSpace = data->TextSpace; switch (data->TextAlign) { case 0: m_Proportion.SetAlignsH(CTextFlags::alignLeft); break; case 1: m_Proportion.SetAlignsH(CTextFlags::alignCenterH); break; case 2: m_Proportion.SetAlignsH(CTextFlags::alignRight); break; } m_Proportion.m_size.cx = data->TextWidth; m_Proportion.m_size.cy = data->TextHeight; } void NItem::CItemCopyAsImageEx::TraceEnd() { m_tracker.m_rect.NormalizeRect(); m_coorRect = GetDC()->GetReal(m_tracker.m_rect); } void NItem::CItemCopyAsImageEx::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { m_tracker.SetTrackStart(point); } int NItem::CItemCopyAsImageEx::OnMouseMove(CDC * pDC, UINT nFlags, CPoint point) { return 1; } void NItem::CItemCopyAsImageEx::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { TraceEnd(); } int NItem::CItemCopyAsImageEx::HitTest(CPoint point) { //m_tracker.m_rect = GetDC()->GetScreen(m_coorRect); return m_tracker.HitTest(point); } void NItem::CItemCopyAsImageEx::TrackHandle(int nHandle, CPoint point, CDC * pDCScreen) { m_tracker.Track(nHandle, point, m_bAllowInvert, pDCScreen); } bool NItem::CItemCopyAsImageEx::CopyRectToClipboard(double scaleFactor) { // 添加边界空白区 CRect8 rctTrue; GetTrueRect(&rctTrue); CPointList pts; dfPoint pt; pt.x0 = m_coorRect.left; pt.y0 = m_coorRect.bottom; pts.AddTail(pt); pt.x0 = m_coorRect.left; pt.y0 = m_coorRect.top; pts.AddTail(pt); pt.x0 = m_coorRect.right; pt.y0 = m_coorRect.top; pts.AddTail(pt); pt.x0 = m_coorRect.right; pt.y0 = m_coorRect.bottom; pts.AddTail(pt); pt.x0 = m_coorRect.left; pt.y0 = m_coorRect.bottom; pts.AddTail(pt); pt.x0 = rctTrue.left; pt.y0 = rctTrue.bottom; pts.AddTail(pt); pt.x0 = rctTrue.right; pt.y0 = rctTrue.bottom; pts.AddTail(pt); pt.x0 = rctTrue.right; pt.y0 = rctTrue.top; pts.AddTail(pt); pt.x0 = rctTrue.left; pt.y0 = rctTrue.top; pts.AddTail(pt); pt.x0 = rctTrue.left; pt.y0 = rctTrue.bottom; pts.AddTail(pt); CCurveEx* pc = new CCurveEx; pc->SetPoints(pts, 2); POSITION pos = this->AddElement(pc, DOUBLEFOX_CURVE, false, false); this->GetDoc()->GetDraw()->SetElementLayer(pos, "__AttatchedElements"); COne* pOne = this->GetDoc()->GetDraw()->GetAt(pos); //CHowToViewCurve hw; CCurveProperties* pCurveProperty = new CCurveProperties(); pCurveProperty->color = RGB(255, 255, 255); pCurveProperty->SetCurveType(PLINE_SOLID); pCurveProperty->m_size.cx = 0; //hw.Add(pCurveProperty); pOne->HowToViewCurve = new CHowToViewCurve(); pOne->HowToViewCurve->Add(pCurveProperty); if (m_ShowNetGrid) { CGridding* pGrid = new CGridding(); *pGrid = m_Net; CRect8 pRct; pGrid->GetRange(pRct); POSITION posNet = this->AddElement(pGrid, DOUBLEFOX_GRID, false, false); this->GetDoc()->GetDraw()->SetElementLayer(posNet, "__AttatchedElements"); } if (m_ShowProportion) { CProportion* pProportion = new CProportion(); *pProportion = m_Proportion; CRect8 pRct; pProportion->GetRange(pRct); POSITION posProp = this->AddElement(pProportion, DOUBLEFOX_PROPORTION, false, false); this->GetDoc()->GetDraw()->SetElementLayer(posProp, "__AttatchedElements"); } CopyToClipboard(rctTrue, scaleFactor); // 删除边界空白区 GetDoc()->GetDraw()->RemoveLayer("__AttatchedElements", 0, 1); return true; } void NItem::CItemCopyAsImageEx::CopyToClipboard(CRect8& rect, double scaleFactor) { CXyDC* pXyDc = GetDC(); CRect rt = pXyDc->GetScreen(rect); if (rt.IsRectEmpty()) return; // pXyDc->Reduce(scaleFactor); CRect rtScale = pXyDc->GetScreen(rect); double dx = rect.left - pXyDc->left; double dy = rect.top - pXyDc->top; pXyDc->OffsetRect(dx, dy); CItemExportFile ef(GetDoc()); CMemoryDC *pmdc = ef.ExportImage(rtScale.Size(), 24); if (pmdc) { pmdc->CopyToClipboard(); delete pmdc; } pXyDc->OffsetRect(-dx, -dy); pXyDc->Reduce(1.0/scaleFactor); }