// GraphView.cpp : 实现文件 // #include "stdafx.h" #include "DrawGraph.h" // CDrawGraph IMPLEMENT_DYNAMIC(CDrawGraph, CWnd) //======================================================== CDrawGraph::CDrawGraph() { //注册控件类 RegisterCtrlClass(); m_nMarginLeft = 40; m_nMarginTop = 15; m_nMarginRight = 15; m_nMarginBottom = 30; m_dbResolutionX = 1; m_dbResolutionY = 1; m_nDivisionX = 10; m_nDivisionY = 10; m_dbStartX = m_dbStartY = 0; m_dbEndX = m_dbEndY = 100; //颜色表 m_clrCoordBkg = RGB(255, 255, 255); m_clrFrame = RGB(0, 0, 0); m_clrWave = RGB(0, 0, 255); } //======================================================== CDrawGraph::~CDrawGraph() { } //======================================================== void CDrawGraph::RegisterCtrlClass() { HINSTANCE hInstance = AfxGetInstanceHandle(); WNDCLASS wndclsCtrl; ZeroMemory(&wndclsCtrl, sizeof(WNDCLASS)); if(::GetClassInfo(hInstance, STR_CLASS_NAME, &wndclsCtrl)) return; //设置控件类信息 wndclsCtrl.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclsCtrl.lpfnWndProc = ::DefWindowProc; wndclsCtrl.cbClsExtra = 0; wndclsCtrl.cbWndExtra = 0; wndclsCtrl.hInstance = hInstance; wndclsCtrl.hIcon = NULL; wndclsCtrl.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); wndclsCtrl.hbrBackground = NULL; wndclsCtrl.lpszMenuName = NULL; wndclsCtrl.lpszClassName = STR_CLASS_NAME; //注册控件类 AfxRegisterClass(&wndclsCtrl); } //======================================================== void CDrawGraph::SetViewFont(const CString& strFont, int nPointSize, int nWeight, BOOL bIsRedraw) { int nCount; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); //设置字体样式 nCount = sizeof(lf.lfFaceName)/sizeof(TCHAR); COPYSTRING(lf.lfFaceName, nCount, strFont); lf.lfHeight = nPointSize; lf.lfWeight = nWeight; lf.lfCharSet = GB2312_CHARSET; //清楚已有样式 if(m_fontView.GetSafeHandle()) m_fontView.DeleteObject(); //设置字体 m_fontView.CreateFontIndirect(&lf); if(bIsRedraw) Invalidate(); } //======================================================== void CDrawGraph::SetMargin(int nLeft, int nTop, int nRight, int nBottom, BOOL bIsRedraw) { m_nMarginLeft = nLeft; m_nMarginTop = nTop; m_nMarginRight = nRight; m_nMarginBottom = nBottom; if(bIsRedraw) Invalidate(); } //======================================================== bool CDrawGraph::SetGraphyView(double dbStartX, double dbEndX, double dbStartY, double dbEndY, int nDivisionX, int nDivisionY, BOOL bIsRedraw) { if(nDivisionX<=1||nDivisionY<=1) return false; m_dbStartX = dbStartX; m_dbEndX = dbEndX; m_dbStartY = dbStartY; m_dbEndY = dbEndY; m_nDivisionX = nDivisionX; m_nDivisionY = nDivisionY; if(bIsRedraw) Invalidate(); return true; } //======================================================== void CDrawGraph::SetResolution(double dbResolutionX, double dbResolutionY, BOOL bIsRedraw) { m_dbResolutionX = dbResolutionX; m_dbResolutionY = dbResolutionY; if(bIsRedraw) Invalidate(); } //======================================================== void CDrawGraph::LoadGraphyData(DataBuff& dataShow) { double dbData; INT_PTR nCount = dataShow.GetCount(); if(nCount==0) return; m_dataGraph.RemoveAll(); m_dataGraph.SetSize(nCount); for(int i=0; iFillSolidRect(rectCoord, m_clrCoordBkg); nOffset = 2; for(i=0; i<=m_nDivisionX; i++) { dbTemp = dbTempStartX+dbRangX*i/m_nDivisionX; strCoord.Format(_T("%g"), dbTemp); nSection = rectCoord.Width()*i/m_nDivisionX; szText = pDC->GetTextExtent(strCoord, strCoord.GetLength()); rectTemp.SetRect(rectCoord.left+nSection-szText.cx/2, rectCoord.bottom+nOffset, rectCoord.left+nSection+szText.cx/2, rectCoord.bottom+szText.cy+nOffset); pDC->MoveTo(rectCoord.left+nSection, rectCoord.top); pDC->LineTo(rectCoord.left+nSection, rectCoord.bottom); pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER); } nOffset = 2; for(i=0; i<=m_nDivisionY; i++) { dbTemp = dbTempStartY+dbRangY*i/m_nDivisionY; strCoord.Format(_T("%g"), dbTemp); nSection = rectCoord.Height()*i/m_nDivisionY; szText = pDC->GetTextExtent(strCoord, strCoord.GetLength()); rectTemp.SetRect(rectCoord.left-szText.cx-nOffset, rectCoord.bottom-nSection-szText.cy*2/3, rectCoord.left-nOffset, rectCoord.bottom-nSection+szText.cy/3); pDC->MoveTo(rectCoord.left, rectCoord.top+nSection); pDC->LineTo(rectCoord.right+1, rectCoord.top+nSection); pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER); } LOGFONT lf; ::ZeroMemory (&lf, sizeof (lf)); //lf.lfHeight = 160; //lf.lfWeight = FW_BOLD; lf.lfEscapement = 900; lf.lfOrientation = 900; CFont font; font.CreatePointFontIndirect (&lf); CFont* pOldFont = pDC->SelectObject (&font); pDC->TextOut(rectCoord.left-40,rectCoord.top+(rectCoord.Height()/2)+30,_T("速度(mm/s)"));//旋转90°输出 pDC->SelectObject (pOldFont); pDC->TextOut(rectCoord.left-20+(rectCoord.Width()/2),rectCoord.bottom+15,_T("时间(s)")); nOffset = 4; rectTemp.SetRect(rectCoord.left+nOffset, rectCoord.top+1, rectCoord.right, rectCoord.bottom-nOffset); pDC->FillSolidRect(rectTemp, m_clrCoordBkg); } //======================================================== void CDrawGraph::DrawActualCurve(CDC *pDC, CRect rectCoord) { CRect rectView; CRgn rgnTemp, rgnView; CPen penLine, *pOldPen; INT_PTR nCount = m_dataGraph.GetCount(); if(nCount==0) return; double dbData(0.0); int nOffsetX(0), nOffsetY(0),nOriginX(0),nOriginY(0); dbData = m_dataGraph.ElementAt(0); nOriginX = rectCoord.left; nOriginY = rectCoord.bottom;; nOffsetX = static_cast(m_dbResolutionX*(rectCoord.Width())); nOffsetY = static_cast(m_dbResolutionY*(rectCoord.Height())*dbData); rgnTemp.CreateRectRgnIndirect(rectCoord); pDC->SelectObject(rgnTemp); penLine.CreatePen(PS_SOLID, 1, m_clrWave); pOldPen = pDC->SelectObject(&penLine); pDC->MoveTo(nOriginX, nOriginY-nOffsetY); for(int i=1; i(m_dbResolutionY*(rectCoord.Height())*dbData); pDC->LineTo(nOriginX+nOffsetX*i, nOriginY-nOffsetY); } pDC->SelectObject(pOldPen); GetClientRect(rectView); rgnView.CreateRectRgnIndirect(rectView); pDC->SelectObject(rgnView); } //======================================================== void CDrawGraph::DrawIdealCurve(CDC *pDC, CRect rectCoord) { CRect rectView; CRgn rgnTemp, rgnView; CPen penLine, *pOldPen; INT_PTR nCount = m_dataGraph.GetCount(); if(nCount==0) return; double dbData; int nOffsetX, nOffsetY; int nRangX = abs(int((m_dbEndX-m_dbStartX)*m_dbResolutionX)), nRangY = abs(int((m_dbEndY-m_dbStartY)*m_dbResolutionY)); int nCoordWith = rectCoord.Width(), nCoordHeight = rectCoord.Height(), nOriginX = rectCoord.left-int(m_dbStartX*nCoordWith/nRangX), nOriginY = rectCoord.bottom+int(m_dbStartY*nCoordHeight/nRangY); rgnTemp.CreateRectRgnIndirect(rectCoord); pDC->SelectObject(rgnTemp); penLine.CreatePen(PS_SOLID, 1, m_clrWave); pOldPen = pDC->SelectObject(&penLine); dbData = m_dataGraph.ElementAt(0); nOffsetY = int(nCoordHeight*dbData/nRangY); pDC->MoveTo(nOriginX, nOriginY-nOffsetY); for(int i=1; iLineTo(nOriginX+nOffsetX, nOriginY-nOffsetY); } pDC->SelectObject(pOldPen); GetClientRect(rectView); rgnView.CreateRectRgnIndirect(rectView); pDC->SelectObject(rgnView); } //======================================================== BEGIN_MESSAGE_MAP(CDrawGraph, CWnd) ON_WM_PAINT() ON_WM_ERASEBKGND() END_MESSAGE_MAP() // CDrawGraph 消息处理程序 //======================================================== void CDrawGraph::PreSubclassWindow() { CWnd::PreSubclassWindow(); SetViewFont(_T("宋体"), 12, FW_NORMAL); } //======================================================== void CDrawGraph::OnPaint() { CPaintDC dc(this); int nMode; CRect rectClient, rectCoord, rectInfo, rectTemp; CString strCaption, strOutputInfo; CBitmap bitmapTemp, *pOldBitmap; CFont* pOldFont; CDC* pMemDC = new CDC; //获取控件信息 GetClientRect(rectClient); GetWindowText(strCaption); //创建位图内存 bitmapTemp.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height()); pMemDC->CreateCompatibleDC(&dc); pOldBitmap = pMemDC->SelectObject(&bitmapTemp); pOldFont = pMemDC->SelectObject(&m_fontView); nMode = pMemDC->SetBkMode(TRANSPARENT); //填充客户区 pMemDC->FillSolidRect(&rectClient, GetSysColor(COLOR_BTNFACE)); //绘制视图标题 pMemDC->DrawText(strCaption, strCaption.GetLength(), rectClient, DT_CENTER); //绘制坐标框 rectCoord.SetRect(rectClient.left+m_nMarginLeft, rectClient.top+m_nMarginTop, rectClient.right-m_nMarginRight, rectClient.bottom-m_nMarginBottom); DrawCoordinate(pMemDC, rectCoord); //绘制波形 DrawActualCurve(pMemDC, rectCoord); dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), pMemDC, 0, 0, SRCCOPY); pMemDC->SetBkMode(nMode); pMemDC->SelectObject(pOldFont); pMemDC->SelectObject(pOldBitmap); ReleaseDC(pMemDC); delete pMemDC; } //================================================================================================ BOOL CDrawGraph::OnEraseBkgnd(CDC* pDC) { //UNREFERENCED_PARAMETER(pDC); //return TRUE; return CWnd::OnEraseBkgnd(pDC); }