?? graphctrl.cpp
字號(hào):
#include "stdafx.h"
#include "resource.h"
#include "GraphCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
MECGraphCtrl::MECGraphCtrl()
{
m_nLastIndexPoint = 0;
m_nYDecimals = 0 ;
m_nXDecimals = 0 ;
m_dLowerLimit = 0 ;
m_dUpperLimit = 100 ;
m_dRange = m_dUpperLimit - m_dLowerLimit ;
m_dXLower = 0 ;
m_dXUpper = 100 ;
m_XRange = m_dXUpper - m_dXLower;
m_crBackColor = RGB( 0, 0, 0) ;
m_crGridColor = RGB( 0, 255, 255) ;
m_crPlotColor = RGB(255, 255, 255) ;
m_penPlot.CreatePen(PS_SOLID, 0, m_crPlotColor) ;
m_brushBack.CreateSolidBrush(m_crBackColor) ;
m_strXUnitsString.Format(_T("Time in seconds")) ;
m_pbitmapOldGrid = NULL ;
m_pbitmapOldPlot = NULL ;
}
MECGraphCtrl::~MECGraphCtrl()
{
}
BEGIN_MESSAGE_MAP(MECGraphCtrl, CWnd)
//{{AFX_MSG_MAP(MECGraphCtrl)
ON_WM_SIZE()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void MECGraphCtrl::AppendPoint(double dPointX, double dPointY)
{
m_oNewPoint.x = dPointX;
m_oNewPoint.y = dPointY;
m_oPoints[m_nLastIndexPoint].x = m_oNewPoint.x;
m_oPoints[m_nLastIndexPoint].y = m_oNewPoint.y;
DrawPoints();
m_nLastIndexPoint++;
Invalidate();
}
void MECGraphCtrl::DrawPoints()
{
CPen *oldPen ;
CRect rectCleanUp ;
if (m_dcPlot.GetSafeHdc() != NULL)
{
m_dcPlot.BitBlt(m_rectPlot.left, m_rectPlot.top+1,
m_nPlotWidth, m_nPlotHeight, &m_dcPlot,
m_rectPlot.left, m_rectPlot.top+1,
SRCCOPY) ;
m_dcPlot.FillRect(rectCleanUp, &m_brushBack) ;
oldPen = m_dcPlot.SelectObject(&m_penPlot) ;
if(m_nLastIndexPoint == 0)
{
int nXOrigin = m_rectPlot.left ;
int nYOrigin = m_rectPlot.bottom ;
m_dcPlot.MoveTo (nXOrigin, nYOrigin) ;
m_dPoints[m_nLastIndexPoint].x = m_rectPlot.left+(long)((m_oPoints[m_nLastIndexPoint].x - m_dXLower) * m_dHorizontalFactor) ;
m_dPoints[m_nLastIndexPoint].y = m_rectPlot.bottom -
(long)((m_oPoints[m_nLastIndexPoint].y - m_dLowerLimit) * m_dVerticalFactor) ;
m_dcPlot.LineTo ((int)m_dPoints[m_nLastIndexPoint].x, (int)m_dPoints[m_nLastIndexPoint].y) ;
}
else
{
if (m_dPoints[m_nLastIndexPoint].x >= m_rectPlot.left)
m_dcPlot.MoveTo ((int)m_dPoints[m_nLastIndexPoint-1].x, (int)m_dPoints[m_nLastIndexPoint-1].y) ;
m_dPoints[m_nLastIndexPoint].x = m_rectPlot.left+(long)((m_oPoints[m_nLastIndexPoint-1].x - m_dXLower) * m_dHorizontalFactor) ;
m_dPoints[m_nLastIndexPoint].y = m_rectPlot.bottom -
(long)((m_oPoints[m_nLastIndexPoint-1].y - m_dLowerLimit) * m_dVerticalFactor) ;
if (m_dPoints[m_nLastIndexPoint].x >= m_rectPlot.left)
m_dcPlot.LineTo ((int)m_dPoints[m_nLastIndexPoint].x, (int)m_dPoints[m_nLastIndexPoint].y) ;
}
if ((m_dPoints[m_nLastIndexPoint-1].y <= m_rectPlot.top) || (m_dPoints[m_nLastIndexPoint].y <= m_rectPlot.top))
m_dcPlot.FillRect(CRect((int)m_dPoints[m_nLastIndexPoint].x, m_rectClient.top, (int)m_dPoints[m_nLastIndexPoint].x+1, m_rectPlot.top+1), &m_brushBack) ;
if ((m_dPoints[m_nLastIndexPoint-1].y >= m_rectPlot.bottom) || (m_dPoints[m_nLastIndexPoint].y >= m_rectPlot.bottom))
m_dcPlot.FillRect(CRect((int)m_dPoints[m_nLastIndexPoint].x, m_rectPlot.bottom+1, (int)m_dPoints[m_nLastIndexPoint].x+1, m_rectClient.bottom+1), &m_brushBack) ;
m_dcPlot.SelectObject(oldPen) ;
}
}
void MECGraphCtrl::InvalidateCtrl()
{
int nCharacters ;
CPen *oldPen ;
CPen solidPen(PS_SOLID, 0, m_crGridColor) ;
CFont axisFont, yUnitFont, *oldFont ;
CString strTemp ;
CClientDC dc(this) ;
if (m_dcGrid.GetSafeHdc() == NULL)
{
m_dcGrid.CreateCompatibleDC(&dc) ;
m_bitmapGrid.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;
m_pbitmapOldGrid = m_dcGrid.SelectObject(&m_bitmapGrid) ;
}
m_dcGrid.SetBkColor (m_crBackColor) ;
m_dcGrid.FillRect(m_rectClient, &m_brushBack) ;
nCharacters = abs((int)log10(fabs(m_dUpperLimit))) ;
nCharacters = max(nCharacters, abs((int)log10(fabs(m_dLowerLimit)))) ;
nCharacters = nCharacters + 4 + m_nYDecimals ;
m_rectPlot.left = m_rectClient.left + 6*(nCharacters) ;
m_nPlotWidth = m_rectPlot.Width() ;
oldPen = m_dcGrid.SelectObject (&solidPen) ;
m_dcGrid.MoveTo (m_rectPlot.left, m_rectPlot.top) ;
m_dcGrid.LineTo (m_rectPlot.right+1, m_rectPlot.top) ;
m_dcGrid.LineTo (m_rectPlot.right+1, m_rectPlot.bottom+1) ;
m_dcGrid.LineTo (m_rectPlot.left, m_rectPlot.bottom+1) ;
m_dcGrid.LineTo (m_rectPlot.left, m_rectPlot.top) ;
m_dcGrid.SelectObject (oldPen) ;
yUnitFont.CreateFont (14, 0, 900, 0, 300,
FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS, _T("Arial")) ;
axisFont.CreateFont (14, 0, 0, 0, 300,
FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS, _T("Arial")) ;
oldFont = m_dcGrid.SelectObject(&axisFont) ;
// y max
m_dcGrid.SetTextColor (m_crGridColor) ;
strTemp.Format (_T("%.*lf"), m_nYDecimals, m_dUpperLimit) ;
int nYMaxLength = strTemp.GetLength();
if(m_nYDecimals == 2)
m_dcGrid.ExtTextOut(m_rectPlot.left-30,m_rectPlot.top,ETO_CLIPPED|ETO_OPAQUE,NULL,strTemp,nYMaxLength,NULL);
// y min
strTemp.Format (_T("%.*lf"), m_nYDecimals, m_dLowerLimit) ;
nYMaxLength = strTemp.GetLength();
if(m_nYDecimals == 2)
m_dcGrid.ExtTextOut(m_rectPlot.left-30, m_rectPlot.bottom -10,ETO_CLIPPED|ETO_OPAQUE,NULL,strTemp,nYMaxLength,NULL);
strTemp.Format (_T("%.*lf"), m_nXDecimals, m_dXLower) ;
nYMaxLength = strTemp.GetLength();
m_dcGrid.ExtTextOut(m_rectPlot.left,m_rectPlot.bottom+4,ETO_CLIPPED,NULL,strTemp,nYMaxLength,NULL);
// x max
strTemp.Format (_T("%.*lf"), m_nXDecimals, m_dXUpper) ;
nYMaxLength = strTemp.GetLength();
m_dcGrid.ExtTextOut(m_rectPlot.right-25,m_rectPlot.bottom+4,ETO_CLIPPED,NULL,strTemp,nYMaxLength,NULL);
// x units
m_dcGrid.ExtTextOut (((m_rectPlot.left+m_rectPlot.right)/2)-30,
m_rectPlot.bottom+12, ETO_CLIPPED,NULL,m_strXUnitsString,m_strXUnitsString.GetLength() ,NULL) ;
// restore the font
m_dcGrid.SelectObject(oldFont) ;
// y units
oldFont = m_dcGrid.SelectObject(&yUnitFont) ;
m_dcGrid.ExtTextOut (((m_rectClient.left+m_rectPlot.left)/2)-20,
((m_rectPlot.bottom+m_rectPlot.top)/2)+38, ETO_CLIPPED,NULL,m_strYUnitsString,m_strYUnitsString.GetLength() ,NULL) ;
m_dcGrid.SelectObject(oldFont) ;
if (m_dcPlot.GetSafeHdc() == NULL)
{
m_dcPlot.CreateCompatibleDC(&dc) ;
m_bitmapPlot.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;
m_pbitmapOldPlot = m_dcPlot.SelectObject(&m_bitmapPlot) ;
}
m_dcPlot.SetBkColor (m_crBackColor) ;
m_dcPlot.FillRect(m_rectClient, &m_brushBack) ;
InvalidateRect(m_rectClient) ;
}
BOOL MECGraphCtrl::Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID)
{
BOOL result ;
static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW) ;
result = CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE,
className, NULL, dwStyle,
rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID) ;
if (result != 0)
InvalidateCtrl() ;
return result ;
} // Create
void MECGraphCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
GetClientRect(m_rectClient) ;
m_nClientHeight = m_rectClient.Height() ;
m_nClientWidth = m_rectClient.Width() ;
m_rectPlot.left = 20 ;
m_rectPlot.top = 10 ;
m_rectPlot.right = m_rectClient.right-10 ;
m_rectPlot.bottom = m_rectClient.bottom-25 ;
m_nPlotHeight = m_rectPlot.Height() ;
m_nPlotWidth = m_rectPlot.Width() ;
m_dVerticalFactor = (double)m_nPlotHeight / m_dRange ;
}
void MECGraphCtrl::OnPaint()
{
CPaintDC dc(this);
CDC memDC ;
CBitmap memBitmap ;
CBitmap* oldBitmap ;
memDC.CreateCompatibleDC(&dc) ;
memBitmap.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;
oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ;
if (memDC.GetSafeHdc() != NULL)
{
memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight,
&m_dcGrid, 0, 0, SRCCOPY) ;
// now add the plot on top as a "pattern" via SRCPAINT.
// works well with dark background and a light plot
memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight,
&m_dcPlot, 0, 0, SRCPAINT) ; //SRCPAINT
// finally send the result to the display
dc.BitBlt(0, 0, m_nClientWidth, m_nClientHeight,
&memDC, 0, 0, SRCCOPY) ;
}
memDC.SelectObject(oldBitmap) ;
// Do not call CWnd::OnPaint() for painting messages
}
void MECGraphCtrl::SetRange(double dLower, double dUpper, int nDecimalPlaces)
{
ASSERT(dUpper > dLower) ;
m_dLowerLimit = dLower ;
m_dUpperLimit = dUpper ;
m_nYDecimals = nDecimalPlaces ;
m_dRange = m_dUpperLimit - m_dLowerLimit ;
m_dVerticalFactor = (double)m_nPlotHeight / m_dRange ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
}
void MECGraphCtrl::SetXUnits(CString string)
{
m_strXUnitsString = string ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
} // SetXUnits
void MECGraphCtrl::SetYUnits(CString string)
{
m_strYUnitsString = string ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
}
void MECGraphCtrl::SetGridColor(COLORREF color)
{
m_crGridColor = color ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
} // SetGridColor
void MECGraphCtrl::SetPlotColor(COLORREF color)
{
m_crPlotColor = color ;
m_penPlot.DeleteObject() ;
m_penPlot.CreatePen(PS_SOLID, 2, m_crPlotColor) ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
} // SetPlotColor
void MECGraphCtrl::SetBackgroundColor(COLORREF color)
{
m_crBackColor = color ;
m_brushBack.DeleteObject() ;
m_brushBack.CreateSolidBrush(m_crBackColor) ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
} // SetBackgroundColor
void MECGraphCtrl::SetXRange(double dLower, double dUpper, int nDecimalPlaces)
{
ASSERT(dUpper > dLower) ;
m_dXLower = dLower ;
m_dXUpper = dUpper ;
m_nXDecimals = nDecimalPlaces ;
m_XRange = m_dXUpper - m_dXLower ;
m_dHorizontalFactor = (double)m_nPlotWidth / m_XRange ;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl() ;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -