www.pudn.com > PressMonitor_q.zip > 3DTrendCtrl.cpp


// 3DTrendCtrl.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "3DTrendCtrl.h" 
#include "MemDC.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// C3DTrendCtrl 
 
#define PANE_LEFT		16 
#define PANE_RIGHT		5 
#define PANE_TOP		10 
#define PANE_BOTTOM		10 
 
C3DTrendCtrl::C3DTrendCtrl() 
{ 
	//fontHeight Value 
	m_nScaleHeight		= 12; 
	m_nUnitHeight		= 12; 
	m_nNameHeight		= 12; 
	m_nValueHeight		= 14; 
	m_nTimeHeight		= 14; 
	m_nFrameWidth		= 4; 
 
    m_nValueStep        = 4; 
	m_nTimeStep			= 5;   
	m_nTimeStepCount	= 10; 
	m_nCurveDataCount   = m_nTimeStepCount*m_nTimeStep; 
 
	m_bGridBelow		= true; 
   
 
    m_crWindowText		= GetSysColor(COLOR_WINDOWTEXT); 
    m_crWindow		    = GetSysColor(COLOR_WINDOW); 
    m_cr3DFace          = GetSysColor(COLOR_3DFACE); 
	m_crShadow          = GetSysColor(COLOR_3DSHADOW) ; 
	m_crDkShadow        = GetSysColor(COLOR_3DDKSHADOW); 
	m_crLight           = GetSysColor(COLOR_3DLIGHT); 
	m_crHighlight       = GetSysColor(COLOR_3DHIGHLIGHT) ; 
 
	m_crFrame			= GetSysColor(COLOR_3DFACE); 
	m_crBkGnd			= RGB(0,128,128); 
    m_crGrid		    = RGB(255,255,255); 
	m_crPane            = GetSysColor(COLOR_3DFACE); 
	m_crValue			= GetSysColor(COLOR_WINDOWTEXT); 
	m_crName			= RGB(255,255,255); 
	m_crRulerScale		= GetSysColor(COLOR_WINDOWTEXT); 
	m_crRulerTime		= GetSysColor(COLOR_WINDOWTEXT); 
	m_crTime			= GetSysColor(COLOR_WINDOWTEXT); 
} 
 
C3DTrendCtrl::~C3DTrendCtrl() 
{ 
	if ((m_pBitmapOldBackground) &&  
		  (m_bitmapBackground.GetSafeHandle()) &&  
			(m_dcBackground.GetSafeHdc())) 
	{ 
			m_dcBackground.SelectObject(m_pBitmapOldBackground); 
			m_dcBackground.DeleteDC() ; 
			m_bitmapBackground.DeleteObject(); 
	} 
	RemoveAllCurves(); 
} 
 
 
BEGIN_MESSAGE_MAP(C3DTrendCtrl, CStatic) 
	//{{AFX_MSG_MAP(C3DTrendCtrl) 
	ON_WM_ERASEBKGND() 
	ON_WM_PAINT() 
	ON_WM_SIZE() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// C3DTrendCtrl message handlers 
 
BOOL C3DTrendCtrl::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	return TRUE; 
} 
 
void C3DTrendCtrl::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
		 
	// Find out how big we are 
	GetClientRect (&m_rectCtrl) ; 
 
//	ULONG totalNumber	= m_BarItemArray.GetSize();	 
 
//    if(totalNumber <=0) 
//    { 
//       TRACE("OnPaint(): No items!\n"); 
//        return; 
//   } 
 
 
	// make a memory dc 
	CMemDC memDC(&dc, &m_rectCtrl); 
 
	// set up a memory dc for the background stuff  
	// if one isn't being used 
	if ((m_dcBackground.GetSafeHdc() == NULL) || (m_bitmapBackground.m_hObject == NULL)) 
	{ 
		m_dcBackground.CreateCompatibleDC(&dc) ; 
		m_bitmapBackground.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(), m_rectCtrl.Height()) ; 
		m_pBitmapOldBackground = m_dcBackground.SelectObject(&m_bitmapBackground) ; 
 
		// Fill this bitmap with the background. 
 
		// Note: This requires some serious drawing and calculating,  
		// therefore it is drawn "once" to a bitmap and  
		// the bitmap is stored and blt'd when needed. 
		DrawFrame(&m_dcBackground); 
		DrawPane(&m_dcBackground); 
		DrawRuler(&m_dcBackground); 
		DrawUnit(&m_dcBackground); 
		DrawScale(&m_dcBackground); 
		if(m_bGridBelow) 
			DrawGrid(&m_dcBackground); 
	} 
 
	// drop in the background 
	memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(),  
			           &m_dcBackground, 0, 0, SRCCOPY) ; 
 
 
	DrawCurves(&memDC); 
	DrawTime(&memDC); 
	DrawName(&memDC); 
//	DrawValue(&memDC); 
	if(!m_bGridBelow) 
		DrawGrid(&memDC); 
} 
 
void C3DTrendCtrl::OnSize(UINT nType, int cx, int cy)  
{ 
	CStatic::OnSize(nType, cx, cy); 
 
	ReconstructControl() ; 
	 
} 
 
void C3DTrendCtrl::ReconstructControl() 
{ 
	// if we've got a stored background - remove it! 
	if ((m_pBitmapOldBackground) &&  
		  (m_bitmapBackground.GetSafeHandle()) &&  
			(m_dcBackground.GetSafeHdc())) 
	{ 
			m_dcBackground.SelectObject(m_pBitmapOldBackground); 
			m_dcBackground.DeleteDC() ; 
			m_bitmapBackground.DeleteObject(); 
			m_bitmapBackground.Detach(); 
	} 
	ReCalculating(); 
	Invalidate () ; 
} 
 
void C3DTrendCtrl::DrawFrame(CDC *pDC) 
{ 
	CPen penFrame,penHighlight,penShadow,*pPenOld; 
	penFrame.CreatePen(PS_SOLID, m_nFrameWidth*2,m_crFrame) ; 
	penHighlight.CreatePen(PS_SOLID, 1, m_crHighlight) ; 
	penShadow.CreatePen(PS_SOLID, 1, m_crShadow) ; 
 
    CBrush brushBack,*pBrushOld; 
	brushBack.CreateSolidBrush(m_crBkGnd) ; 
 
// 画外边框 
	pPenOld = pDC->SelectObject(&penFrame) ; 
	pBrushOld = pDC->SelectObject(&brushBack) ; 
 
	pDC->Rectangle(m_rectCtrl) ; 
/* 
	// draw the left and top sides with the highlight 
	pDC->SelectObject(&penHighlight) ; 
	pDC->MoveTo(m_rectCtrl.left, m_rectCtrl.bottom) ; 
	pDC->LineTo(m_rectCtrl.left, m_rectCtrl.top) ; 
	pDC->LineTo(m_rectCtrl.right-1, m_rectCtrl.top) ; 
 
	// draw the right and bottom sides with the shadow 
	pDC->SelectObject(&penShadow) ; 
	pDC->LineTo(m_rectCtrl.right-1, m_rectCtrl.bottom-1) ; 
	pDC->LineTo(m_rectCtrl.left, m_rectCtrl.bottom-1) ; 
*/ 
 
	// draw the left and top sides with the shadow 
	pDC->SelectObject(&penShadow) ; 
	pDC->MoveTo(m_rectPane.left, m_rectPane.bottom) ; 
	pDC->LineTo(m_rectPane.left, m_rectPane.top) ; 
	pDC->LineTo(m_rectPane.right-1, m_rectPane.top) ; 
 
	// draw the right and bottom sides with the highlight 
	pDC->SelectObject(&penHighlight) ; 
	pDC->LineTo(m_rectPane.right-1, m_rectPane.bottom-1) ; 
	pDC->LineTo(m_rectPane.left, m_rectPane.bottom-1) ; 
 
	pDC->SelectObject(pPenOld); 
	pDC->SelectObject(pBrushOld); 
} 
 
void C3DTrendCtrl::DrawPane(CDC *pDC) 
{ 
    CBrush brushPane,*pBrushOld; 
	brushPane.CreateSolidBrush(m_crPane) ; 
	CPen	penDkShadow,penShadow,penHighlight,*pPenOld; 
	penShadow.CreatePen(PS_SOLID, 1, m_crShadow) ; 
	penDkShadow.CreatePen(PS_SOLID, 1, m_crDkShadow) ; 
	penHighlight.CreatePen(PS_SOLID, 1, m_crHighlight) ; 
 
	pBrushOld=pDC->SelectObject(&brushPane) ; 
 
     // Draw Pane left part 
    pDC->FillRect(CRect(m_rectPaneLeft.left+1, m_rectPaneTop.top+1,  
		m_rectChart.left,  m_rectPaneBottom.bottom-1), 
        &brushPane); 
	//Draw Pane right part 
    pDC->FillRect(CRect(m_rectChart.right, m_rectPaneTop.top+1,  
        m_rectPaneRight.right-1,  m_rectPaneBottom.bottom-1), 
        &brushPane); 
 
    // Draw Pane top part 
    pDC->FillRect(CRect(m_rectPaneTop.left, m_rectPaneTop.top+1, 
        m_rectPaneTop.right,  m_rectChart.top), 
        &brushPane); 
 
	// Draw Pane bottom part 
    pDC->FillRect(CRect(m_rectPaneBottom.left, m_rectChart.bottom, 
        m_rectPaneBottom.right,  m_rectPaneBottom.bottom-1), 
        &brushPane); 
 
	//对Chart区画3D边框 
	// draw the left and top sides with the shadow 
	pPenOld=pDC->SelectObject(&penDkShadow) ; 
	pDC->MoveTo(m_rectChart.left-1, m_rectChart.bottom+1) ; 
	pDC->LineTo(m_rectChart.left-1, m_rectChart.top-1) ; 
	pDC->LineTo(m_rectChart.right+1, m_rectChart.top-1) ; 
 
	pDC->SelectObject(&penShadow) ; 
	pDC->MoveTo(m_rectChart.left-2, m_rectChart.bottom+2) ; 
	pDC->LineTo(m_rectChart.left-2, m_rectChart.top-2) ; 
	pDC->LineTo(m_rectChart.right+2, m_rectChart.top-2) ; 
 
	// draw the right and bottom sides with the highlight 
	pDC->SelectObject(&penHighlight) ; 
	pDC->MoveTo(m_rectChart.right+1, m_rectChart.top-1) ; 
	pDC->LineTo(m_rectChart.right+1, m_rectChart.bottom+1) ; 
	pDC->LineTo(m_rectChart.left-1, m_rectChart.bottom+1) ; 
 
	pDC->MoveTo(m_rectChart.right+2, m_rectChart.top-2) ; 
	pDC->LineTo(m_rectChart.right+2, m_rectChart.bottom+2) ; 
	pDC->LineTo(m_rectChart.left-2, m_rectChart.bottom+2) ; 
	 
	pDC->SelectObject(pPenOld); 
	pDC->SelectObject(pBrushOld); 
} 
 
void C3DTrendCtrl::DrawRuler(CDC *pDC) 
{ 
	int  yy,xx; 
	double nHeight,nWidth; 
	CPen penRulerScale,penRulerTime,*pPenOld; 
	penRulerScale.CreatePen(PS_SOLID,1,m_crRulerScale); 
	penRulerTime.CreatePen(PS_SOLID,1,m_crRulerTime); 
 
 
	pPenOld=pDC->SelectObject(&penRulerScale); 
 
	nHeight=m_rectChart.Height()*1.0/ m_nValueStep; 
	for(int i=0; i<= m_nValueStep ;i++) 
	{ 
		yy = m_rectChart.bottom -(int)(i * nHeight); 
		pDC->MoveTo(m_rectChart.left-3,yy); 
		pDC->LineTo(m_rectChart.left-10,yy); 
 
	} 
 
	for( i=0; i<= 5*m_nValueStep ;i++) 
	{ 
		yy =m_rectChart.bottom -(int)(0.2 * i * nHeight ); 
		pDC->MoveTo(m_rectChart.left-3,yy); 
		pDC->LineTo(m_rectChart.left-7,yy); 
	} 
 
	for( i=0; i<= m_nValueStep ;i++) 
	{ 
		yy = m_rectChart.bottom -(int)(i * nHeight); 
		pDC->MoveTo(m_rectChart.right+3,yy); 
		pDC->LineTo(m_rectChart.right+10,yy); 
 
	} 
 
	for( i=0; i<= 5*m_nValueStep ;i++) 
	{ 
		yy =m_rectChart.bottom -(int)(0.2* i * nHeight); 
		pDC->MoveTo(m_rectChart.right+3,yy); 
		pDC->LineTo(m_rectChart.right+7,yy); 
	} 
 
	pDC->SelectObject(&penRulerTime); 
 
	nWidth=m_rectChart.Width()*1.0/m_nTimeStep; 
	for(i=0;i<=m_nTimeStep;i++) 
	{ 
		xx = m_rectChart.left +(int)(i * nWidth); 
		pDC->MoveTo(xx,m_rectChart.top-3); 
		pDC->LineTo(xx,m_rectChart.top-10); 
	} 
 
	for(i=0;i<=5*m_nTimeStep;i++) 
	{ 
		xx = m_rectChart.left +(int)(0.2 * i * nWidth); 
		pDC->MoveTo(xx,m_rectChart.top-3); 
		pDC->LineTo(xx,m_rectChart.top-7); 
	} 
	for(i=0;i<=m_nTimeStep;i++) 
	{ 
		xx = m_rectChart.left +(int)(i * nWidth); 
		pDC->MoveTo(xx,m_rectChart.bottom+3); 
		pDC->LineTo(xx,m_rectChart.bottom+10); 
	} 
 
	for(i=0;i<=5*m_nTimeStep;i++) 
	{ 
		xx = m_rectChart.left +(int)(0.2 * i * nWidth); 
		pDC->MoveTo(xx,m_rectChart.bottom+3); 
		pDC->LineTo(xx,m_rectChart.bottom+7); 
	} 
 
	pDC->SelectObject(pPenOld); 
} 
 
void C3DTrendCtrl::DrawUnit(CDC *pDC) 
{ 
	CRect rectUnit; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nUnitHeight,0,0,0,900, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
 
	//top unit 
	for(int i=0;i<3;i++) 
	{ 
		pDC->SetTextColor(m_scale[i].clr); 
		switch(m_scale[i].nStyle) 
		{ 
		case SCALE_LEFT: 
			rectUnit.SetRect(m_rectPaneLeft.left+8,m_rectPane.top,m_rectPaneLeft.right-12,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_LEFT|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		case SCALE_CENTER: 
			rectUnit.SetRect(m_rectPaneLeft.left+4,m_rectPane.top,m_rectPaneLeft.right-12,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_CENTER|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		case SCALE_RIGHT: 
			rectUnit.SetRect(m_rectPaneLeft.left+4,m_rectPane.top,m_rectPaneLeft.right-8,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_RIGHT|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		} 
	} 
	//bottom unit 
//    rectUnit.SetRect(m_rectPaneLeft.left,m_rectPaneLeft.bottom+(int)(m_nScaleHeight),m_rectPaneLeft.right-10,m_rectPane.bottom); 
 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::DrawScale(CDC *pDC) 
{ 
	int  yy; 
	double  nHeight; 
    CString pStr; 
 
	CRect rectScale_L,rectScale_C,rectScale_R; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nScaleHeight,0,0,0,600, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Times New Roman");//"Arial Narrow") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
 
	nHeight=m_rectChart.Height()*1.0/ m_nValueStep; 
	for(int i=0; i<= (int)m_nValueStep ;i++) 
	{ 
		for(int j=0;j<3;j++) 
		{ 
/*			if(m_scale[j].strUnit==CURVE_UNIT_C) 
				pStr.Format("%.0f", m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
			else 
				pStr.Format("%.1f", m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
*/ 
			if(m_scale[j].strUnit==CURVE_UNIT_C) 
				pStr.Format("%.0f",m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
			else if(m_scale[j].strUnit==CURVE_UNIT_V) 
				pStr.Format("%.1f",m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
			else if(m_scale[j].strUnit==CURVE_UNIT_MM || m_scale[j].strUnit==CURVE_UNIT_MPA) 
				pStr.Format("%d",(int)(m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep)); 
 
			pDC->SetTextColor(m_scale[j].clr); 
			yy = m_rectChart.bottom -(int)(i*nHeight); 
	 
			rectScale_L.SetRect(m_rectPaneLeft.left+4-4,yy-(int)(nHeight/2),m_rectPaneLeft.right-12-4,yy+(int)(nHeight/2)); 
			rectScale_C.SetRect(m_rectPaneLeft.left+4,yy-(int)(nHeight/2),m_rectPaneLeft.right-12,yy+(int)(nHeight/2)); 
			rectScale_R.SetRect(m_rectPaneLeft.left+4+4,yy-(int)(nHeight/2),m_rectPaneLeft.right-12+4,yy+(int)(nHeight/2)); 
			switch(m_scale[j].nStyle) 
			{ 
			case SCALE_LEFT: 
				pDC->DrawText(pStr,&rectScale_L,DT_LEFT|DT_VCENTER|DT_SINGLELINE); 
				break; 
			case SCALE_CENTER: 
				pDC->DrawText(pStr,&rectScale_C,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
				break; 
			case SCALE_RIGHT: 
				pDC->DrawText(pStr,&rectScale_R,DT_RIGHT|DT_VCENTER|DT_SINGLELINE); 
				break; 
			} 
		} 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::DrawGrid(CDC *pDC) 
{ 
	int  yy,xx; 
	double nHeight,nWidth; 
	CPen penGrid,*pPenOld; 
	penGrid.CreatePen(PS_DOT,1,m_crGrid); 
 
	pPenOld=pDC->SelectObject(&penGrid); 
	int nBkMode=pDC->SetBkMode(TRANSPARENT); 
 
	nHeight=m_rectChart.Height()*1.0/ m_nValueStep; 
	nWidth=m_rectChart.Width()*1.0/m_nTimeStep; 
	for(int i=1; iMoveTo(m_rectChart.left,yy); 
		pDC->LineTo(m_rectChart.right,yy); 
 
	} 
 
	for( i=1; iMoveTo(xx,m_rectChart.bottom); 
		pDC->LineTo(xx,m_rectChart.top); 
 
	} 
	pDC->SelectObject(pPenOld); 
	pDC->SetBkMode(nBkMode); 
} 
 
void C3DTrendCtrl::ReCalculating() 
{ 
    GetClientRect(&m_rectCtrl); 
	m_rectPane=m_rectCtrl; 
	m_rectPane.DeflateRect(m_nFrameWidth,m_nFrameWidth,m_nFrameWidth,m_nFrameWidth); 
 
	m_rectPaneLeft.left=m_rectPane.left; 
	m_rectPaneLeft.right=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneLeft.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectPaneLeft.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_rectPaneRight.left=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneRight.right=m_rectPane.right; 
	m_rectPaneRight.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectPaneRight.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_rectPaneTop.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneTop.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneTop.top=m_rectPane.top; 
	m_rectPaneTop.bottom=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
 
	m_rectPaneBottom.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneBottom.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneBottom.top=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
	m_rectPaneBottom.bottom=m_rectPane.bottom; 
 
	m_rectChart.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectChart.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectChart.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectChart.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_nNameHeight=(int)(m_rectPaneTop.Height()*0.37); 
	m_nValueHeight=(int)(m_rectPaneTop.Height()*0.35); 
	m_nScaleHeight=(int)(m_rectPaneLeft.Height()*0.20/m_nValueStep); 
	m_nUnitHeight=(int)(m_rectPaneTop.Height()*0.4); 
	m_nTimeHeight=(int)(m_rectPaneBottom.Height()*0.35); 
 
	for(int i=0;i<3;i++) 
	{ 
		m_scale[i].VertRatio = (float)m_rectChart.Height()/(float)(m_scale[i].MaxiValue - m_scale[i].MiniValue); 
	} 
 
} 
 
BOOL C3DTrendCtrl::Initialize(Scale* scale,int nStepCount,int nTimeStep,int nValueStep,bool bPrint) 
{ 
	m_nTimeStepCount=nStepCount; 
	m_nTimeStep=nTimeStep; 
	m_nCurveDataCount=m_nTimeStepCount*m_nTimeStep; 
 
    SetScale(scale,nValueStep); 
 
	if(!bPrint) 
		ReCalculating(); 
 
	return TRUE; 
} 
 
BOOL C3DTrendCtrl::SetScale(Scale* scale, int ValueStep) 
{ 
	for(int i=0;i<3;i++) 
	{ 
		m_scale[i].MaxiValue=scale[i].MaxiValue; 
		m_scale[i].MiniValue=scale[i].MiniValue; 
		m_scale[i].nStyle=scale[i].nStyle; 
		m_scale[i].strUnit=scale[i].strUnit; 
		m_scale[i].clr=scale[i].clr; 
	} 
 
    m_nValueStep = ValueStep ; 
 
	return TRUE; 
} 
 
 
 
bool C3DTrendCtrl::AddCurve(CString strName,COLORREF clr, CString strUnit,int nPenSize,  bool bHide) 
{ 
    int index = m_curveArray.Add(new CTrendCurve(strName,strUnit,nPenSize,clr,bHide)); 
	if(index <0) 
        return false; 
 
    return true; 
} 
 
bool C3DTrendCtrl::RemoveAllCurves() 
{ 
	for(int i=0;im_dataArray.GetSize();i++) 
		{ 
			CDataInfo* data = (CDataInfo*)curve->m_dataArray.GetAt(i); 
			if(data) 
				delete data; 
		} 
		curve->m_dataArray.RemoveAll(); 
		if(curve) 
			delete curve; 
	} 
	m_curveArray.RemoveAll(); 
    return true; 
 
} 
 
bool C3DTrendCtrl::AddCurveData(int index, double value, CTime time) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
    if ( curve ) 
    { 
		return curve->AddData(value,time); 
	} 
	return false; 
} 
 
void C3DTrendCtrl::ShiftCurveData(int index, double value, CTime time) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
	{ 
		curve->ShiftData(value,time); 
	} 
} 
 
void C3DTrendCtrl::SetCurveData(int index, int dataIndex, double value, CTime time) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
	{ 
		curve->SetData(dataIndex,value,time); 
	} 
} 
 
void C3DTrendCtrl::SetCurvePenSize(int index, int nPenSize) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
	{ 
		curve->SetPenSize(nPenSize); 
	} 
} 
 
void C3DTrendCtrl::HideCurve(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
	{ 
		curve->HideCurve(); 
	} 
} 
 
void C3DTrendCtrl::ShowCurve(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
	{ 
		curve->ShowCurve(); 
	} 
} 
 
CString C3DTrendCtrl::GetCurveName(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetName(); 
    else 
    { 
        ASSERT(FALSE); 
        return ""; 
    } 
} 
 
CDataInfo* C3DTrendCtrl::GetCurveData(int index,int dataIndex) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetData(dataIndex); 
    else 
    { 
        ASSERT(FALSE); 
        return NULL; 
    } 
} 
 
double C3DTrendCtrl::GetCurveDataValue(int index, int dataIndex) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetDataValue(dataIndex); 
    else 
    { 
        ASSERT(FALSE); 
        return 0; 
    } 
} 
 
CTime C3DTrendCtrl::GetCurveDataTime(int index, int dataIndex) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetDataTime(dataIndex); 
    else 
    { 
        ASSERT(FALSE); 
		CTime time; 
		time=time.GetCurrentTime(); 
        return time; 
    } 
} 
 
int C3DTrendCtrl::GetCurveDataArraySize(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	return curve->GetDataArraySize(); 
} 
 
COLORREF C3DTrendCtrl::GetCurveColor(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetColor(); 
    else 
    { 
        ASSERT(FALSE); 
        return RGB(0,0,0); 
    } 
} 
 
int C3DTrendCtrl::GetCurvePenSize(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetPenSize(); 
    else 
    { 
        ASSERT(FALSE); 
        return 0; 
    } 
} 
 
CString C3DTrendCtrl::GetCurveUnit(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	if( curve ) 
		return curve->GetUnit(); 
    else 
    { 
        ASSERT(FALSE); 
        return ""; 
    } 
} 
 
bool C3DTrendCtrl::GetCurveDispState(int index) 
{ 
	CTrendCurve* curve=(CTrendCurve*)m_curveArray.GetAt(index); 
	return curve->GetDispState(); 
 
} 
 
 
void C3DTrendCtrl::DrawCurve(CDC *pDC, int index) 
{ 
	CPen penCurve,*pPenOld; 
	// let's calc the data point width 
	double nWidth = (double)(m_rectChart.Width()-3)/(double)(GetCurveDataArraySize(index)-1); 
	int	f; 
	int xx,yy; 
	int xx1,yy1; 
	double nValue,nValue1; 
	int nScale=-1; 
 
	for(int i=0;i<3;i++) 
	{ 
		if(m_scale[i].strUnit==GetCurveUnit(index)) 
			nScale=i; 
	} 
	if(nScale==-1) 
		return; 
 
 
		// let's rock 
	penCurve.CreatePen(PS_SOLID, GetCurvePenSize(index), GetCurveColor(index)); 
	pPenOld=pDC->SelectObject(&penCurve); 
 
		// yy will contains a parametrized data  
	for( f=GetCurveDataArraySize(index)-1; f>0; f-- )  
	{ 
		nValue=GetCurveDataValue(index, f); 
		if(nValue==DATA_VALUE_INVALID) 
			break; 
		xx = m_rectChart.left+(int)(nWidth*f); 
		yy = m_rectChart.bottom-(int)((nValue-m_scale[nScale].MiniValue)*m_scale[nScale].VertRatio); 
 
		nValue1=GetCurveDataValue(index,f-1); 
		if(nValue1==DATA_VALUE_INVALID) 
			break; 
		xx1=m_rectChart.left+(int)(nWidth*(f-1)); 
		yy1=m_rectChart.bottom-(int)((nValue1-m_scale[nScale].MiniValue)*m_scale[nScale].VertRatio); 
 
		if(yyMoveTo(xx1,yy1); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.top-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,m_rectChart.top); 
				pDC->LineTo( xx1, yy1 ); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				xx1=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.top-yy1)*1.0/(yy-yy1)); 
 
				pDC->MoveTo(xx,m_rectChart.top); 
				pDC->LineTo(xx1,m_rectChart.bottom); 
			} 
		} 
		else if(yy<=m_rectChart.bottom&&yy>=m_rectChart.top) 
		{ 
			if(yy1MoveTo( xx,yy ); 
				pDC->LineTo( xx1,m_rectChart.top ); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				pDC->MoveTo(xx,yy); 
				pDC->LineTo(xx1,yy1); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				xx1=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,yy); 
				pDC->LineTo( xx1,m_rectChart.bottom ); 
			} 
		} 
		else if(yy>m_rectChart.bottom) 
		{ 
			if(yy1MoveTo(xx,m_rectChart.bottom); 
				pDC->LineTo(xx1,m_rectChart.top); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,m_rectChart.bottom); 
				pDC->LineTo( xx1, yy1 ); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				pDC->MoveTo(xx1,yy1); 
			} 
		} 
	} 
	pDC->SelectObject( pPenOld ); 
} 
 
void C3DTrendCtrl::DrawCurves(CDC *pDC) 
{ 
	if(GetCurveCount()==0) 
		return; 
	for(int i=0;iSelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
	pDC->SetTextColor(m_crTime); 
 
	nWidth=m_rectChart.Width()*1.0/m_nTimeStep; 
	for(i=0; i<= m_nTimeStep ;i++) 
	{ 
		j=i*m_nTimeStepCount; 
		if(GetCurveCount()==0) 
			pStr.Format("MM:SS"); 
		else if(GetCurveDataValue(0,j)==DATA_VALUE_INVALID) 
			pStr.Format("MM:SS"); 
		else 
		{ 
			time=GetCurveDataTime(0,j); 
			pStr=time.Format("%M:%S"); 
		} 
 
		xx = m_rectChart.left+(int)(i*nWidth); 
			 
        rectTime.SetRect(xx-(int)(nWidth/2),m_rectPaneBottom.top,xx+(int)(nWidth/2),m_rectPaneBottom.bottom); 
		pDC->DrawText(pStr,&rectTime,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::DrawName(CDC *pDC) 
{ 
	if(GetCurveCount()==0) 
		return; 
	int  xx; 
	double  nWidth; 
    CString pStr; 
 
	CRect rectName; 
	CFont fontUse,*pFontOld; 
 
	 
	fontUse.CreateFont(14/*m_nNameHeight*/,0,0,0,600, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
	pDC->SetTextColor(m_crName); 
 
	nWidth=m_rectChart.Width()*1.0/ GetCurveCount(); 
	for(int i=0; i< GetCurveCount() ;i++) 
	{ 
		if(GetCurveDispState(i)) 
			continue; 
        pStr.Format("%s", GetCurveName(i)); 
		xx = m_rectChart.left+(int)(i*nWidth); 
        rectName.SetRect((int)(xx+nWidth/10), 
							m_rectPaneTop.CenterPoint().y-m_nNameHeight*3/4, 
							(int)(xx+nWidth), 
							m_rectPaneTop.CenterPoint().y+m_nNameHeight*3/4); 
 
		PaintNameBack(pDC, rectName,i); 
		pDC->DrawText(pStr,&rectName,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::PaintNameBack(CDC *pDC, CRect &rect,int index) 
{ 
	CBrush brushFill; 
	brushFill.CreateSolidBrush(GetCurveColor(index)); 
	pDC->FillRect(&rect,&brushFill); 
	pDC->DrawEdge(&rect,EDGE_SUNKEN,BF_RECT); 
} 
 
 
void C3DTrendCtrl::DrawValue(CDC *pDC) 
{ 
	if(GetCurveCount()==0) 
		return; 
	int  xx; 
	double  nWidth,nValue; 
    CString pStr; 
 
	CRect rectValue; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nValueHeight,0,0,0,800, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
	pDC->SetTextColor(m_crValue); 
 
	nWidth=m_rectChart.Width()*1.0/ GetCurveCount(); 
	for(int i=0; i< GetCurveCount() ;i++) 
	{ 
		if(GetCurveDispState(i)) 
			continue; 
		nValue=GetCurveDataValue(i,m_nCurveDataCount); 
		if(nValue==DATA_VALUE_INVALID) 
			break; 
        pStr.Format("%3.1f",nValue ); 
		xx = m_rectChart.left+(int)(i*nWidth); 
		pDC->SetTextColor(GetCurveColor(i)); 
        rectValue.SetRect(xx,m_rectPaneTop.top,(int)(xx+nWidth),m_rectPaneTop.bottom); 
		rectValue.DeflateRect(4,4,4,4); 
		pDC->DrawText(pStr,&rectValue,DT_RIGHT|DT_VCENTER|DT_SINGLELINE); 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
 
} 
 
//图形打印函数 
 
void C3DTrendCtrl::OnPrint(CDC *pDC, CRect &rect) 
{ 
	PrintCalculating(rect); 
	PrintUnit(pDC); 
	PrintScale(pDC); 
	PrintGrid(pDC); 
	PrintCurves(pDC); 
	PrintTime(pDC); 
	PrintName(pDC); 
 
} 
 
void C3DTrendCtrl::PrintCalculating(CRect &rect) 
{ 
	m_rectPane=rect; 
	m_rectPane.DeflateRect(m_nFrameWidth,m_nFrameWidth,m_nFrameWidth,m_nFrameWidth); 
 
	m_rectPaneLeft.left=m_rectPane.left; 
	m_rectPaneLeft.right=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneLeft.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectPaneLeft.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_rectPaneRight.left=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneRight.right=m_rectPane.right; 
	m_rectPaneRight.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectPaneRight.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_rectPaneTop.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneTop.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneTop.top=m_rectPane.top; 
	m_rectPaneTop.bottom=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
 
	m_rectPaneBottom.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectPaneBottom.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectPaneBottom.top=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
	m_rectPaneBottom.bottom=m_rectPane.bottom; 
 
	m_rectChart.left=m_rectPane.left+m_rectPane.Width()*PANE_LEFT/100; 
	m_rectChart.right=m_rectPane.right-m_rectPane.Width()*PANE_RIGHT/100; 
	m_rectChart.top=m_rectPane.top+m_rectPane.Height()*PANE_TOP/100; 
	m_rectChart.bottom=m_rectPane.bottom-m_rectPane.Height()*PANE_BOTTOM/100; 
 
	m_nNameHeight=(int)(m_rectPaneTop.Height()*0.29); 
	m_nValueHeight=(int)(m_rectPaneTop.Height()*0.35); 
	m_nScaleHeight=(int)(m_rectPaneLeft.Height()*0.20/m_nValueStep); 
	m_nUnitHeight=(int)(m_rectPaneTop.Height()*0.40); 
	m_nTimeHeight=(int)(m_rectPaneBottom.Height()*0.35); 
 
	for(int i=0;i<3;i++) 
	{ 
		m_scale[i].VertRatio = (float)m_rectChart.Height()/(float)(m_scale[i].MaxiValue - m_scale[i].MiniValue); 
	} 
} 
 
void C3DTrendCtrl::PrintUnit(CDC *pDC) 
{ 
	CRect rectUnit; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nUnitHeight,0,0,0,900, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS,"Times New Roman");//"Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
 
	//top unit 
	for(int i=0;i<3;i++) 
	{ 
		pDC->SetTextColor(m_scale[i].clr); 
		switch(m_scale[i].nStyle) 
		{ 
		case SCALE_LEFT: 
			rectUnit.SetRect(m_rectPaneLeft.left+6,m_rectPane.top,m_rectPaneLeft.right-10,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_LEFT|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		case SCALE_CENTER: 
			rectUnit.SetRect(m_rectPaneLeft.left+3,m_rectPane.top,m_rectPaneLeft.right-10,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_CENTER|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		case SCALE_RIGHT: 
			rectUnit.SetRect(m_rectPaneLeft.left+3,m_rectPane.top,m_rectPaneLeft.right-6,m_rectPaneLeft.top-(int)(m_nScaleHeight)); 
			pDC->DrawText(m_scale[i].strUnit,&rectUnit,DT_RIGHT|DT_BOTTOM|DT_SINGLELINE); 
			break; 
		} 
	} 
	//bottom unit 
//    rectUnit.SetRect(m_rectPaneLeft.left,m_rectPaneLeft.bottom+(int)(m_nScaleHeight),m_rectPaneLeft.right-10,m_rectPane.bottom); 
 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::PrintScale(CDC *pDC) 
{ 
	int  yy; 
	double  nHeight; 
    CString pStr; 
 
	CRect rectScale; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nScaleHeight,0,0,0,600, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Times New Roman");//"Arial Narrow") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
 
	nHeight=m_rectChart.Height()*1.0/ m_nValueStep; 
	for(int i=0; i<= (int)m_nValueStep ;i++) 
	{ 
		for(int j=0;j<3;j++) 
		{ 
			if(m_scale[j].strUnit==CURVE_UNIT_C) 
				pStr.Format("%.0f",m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
			else if(m_scale[j].strUnit==CURVE_UNIT_V) 
				pStr.Format("%.0f",m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep); 
			else if(m_scale[j].strUnit==CURVE_UNIT_MM || m_scale[j].strUnit==CURVE_UNIT_MPA) 
				pStr.Format("%d",(int)(m_scale[j].MiniValue + (m_scale[j].MaxiValue  - m_scale[j].MiniValue) *  i/ m_nValueStep)); 
 
			pDC->SetTextColor(m_scale[j].clr); 
			yy = m_rectChart.bottom -(int)(i*nHeight); 
	 
			rectScale.SetRect(m_rectPaneLeft.left+4,yy-(int)(nHeight/2),m_rectPaneLeft.right-12,yy+(int)(nHeight/2)); 
			switch(m_scale[j].nStyle) 
			{ 
			case SCALE_LEFT: 
				pDC->DrawText(pStr,&rectScale,DT_LEFT|DT_VCENTER|DT_SINGLELINE); 
				break; 
			case SCALE_CENTER: 
				pDC->DrawText(pStr,&rectScale,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
				break; 
			case SCALE_RIGHT: 
				pDC->DrawText(pStr,&rectScale,DT_RIGHT|DT_VCENTER|DT_SINGLELINE); 
				break; 
			} 
		} 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::PrintGrid(CDC *pDC) 
{ 
	int  yy,xx; 
	double nHeight,nWidth; 
	CPen penGrid,*pPenOld; 
	penGrid.CreatePen(PS_DOT,1,m_crShadow); 
 
	pPenOld=pDC->SelectObject(&penGrid); 
	int nBkMode=pDC->SetBkMode(TRANSPARENT); 
	pDC->Rectangle(m_rectChart); 
 
	nHeight=m_rectChart.Height()*1.0/ m_nValueStep; 
	nWidth=m_rectChart.Width()*1.0/m_nTimeStep; 
	for(int i=1; iMoveTo(m_rectChart.left,yy); 
		pDC->LineTo(m_rectChart.right,yy); 
 
	} 
 
	for( i=1; iMoveTo(xx,m_rectChart.bottom); 
		pDC->LineTo(xx,m_rectChart.top); 
 
	} 
	pDC->SelectObject(pPenOld); 
	pDC->SetBkMode(nBkMode); 
} 
 
void C3DTrendCtrl::PrintCurves(CDC *pDC) 
{ 
	if(GetCurveCount()==0) 
		return; 
	for(int i=0;iSelectObject(&penCurve); 
 
		// yy will contains a parametrized data  
	for( f=GetCurveDataArraySize(index)-1; f>0; f-- )  
	{ 
		nValue=GetCurveDataValue(index, f); 
		if(nValue==DATA_VALUE_INVALID) 
			break; 
		xx = m_rectChart.left+(int)(nWidth*f); 
		yy = m_rectChart.bottom-(int)((nValue-m_scale[nScale].MiniValue)*m_scale[nScale].VertRatio); 
 
		nValue1=GetCurveDataValue(index,f-1); 
		if(nValue1==DATA_VALUE_INVALID) 
			break; 
		xx1=m_rectChart.left+(int)(nWidth*(f-1)); 
		yy1=m_rectChart.bottom-(int)((nValue1-m_scale[nScale].MiniValue)*m_scale[nScale].VertRatio); 
 
		if(yyMoveTo(xx1,yy1); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.top-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,m_rectChart.top); 
				pDC->LineTo( xx1, yy1 ); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				xx1=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.top-yy1)*1.0/(yy-yy1)); 
 
				pDC->MoveTo(xx,m_rectChart.top); 
				pDC->LineTo(xx1,m_rectChart.bottom); 
			} 
		} 
		else if(yy<=m_rectChart.bottom&&yy>=m_rectChart.top) 
		{ 
			if(yy1MoveTo( xx,yy ); 
				pDC->LineTo( xx1,m_rectChart.top ); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				pDC->MoveTo(xx,yy); 
				pDC->LineTo(xx1,yy1); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				xx1=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,yy); 
				pDC->LineTo( xx1,m_rectChart.bottom ); 
			} 
		} 
		else if(yy>m_rectChart.bottom) 
		{ 
			if(yy1MoveTo(xx,m_rectChart.bottom); 
				pDC->LineTo(xx1,m_rectChart.top); 
			} 
			else if(yy1<=m_rectChart.bottom&&yy1>=m_rectChart.top) 
			{ 
				xx=xx1+(int)((xx-xx1)*(m_rectChart.bottom-yy1)*1.0/(yy-yy1)); 
				pDC->MoveTo(xx,m_rectChart.bottom); 
				pDC->LineTo( xx1, yy1 ); 
			} 
			else if(yy1>m_rectChart.bottom) 
			{ 
				pDC->MoveTo(xx1,yy1); 
			} 
		} 
	} 
	pDC->SelectObject( pPenOld ); 
} 
 
void C3DTrendCtrl::PrintTime(CDC *pDC) 
{ 
	int i,j; 
	int  xx; 
	double  nWidth; 
	CTime time; 
    CString pStr; 
 
	CRect rectTime; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nTimeHeight,0,0,0,100, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
	pDC->SetTextColor(m_crTime); 
 
	nWidth=m_rectChart.Width()*1.0/m_nTimeStep; 
	for(i=0; i<= m_nTimeStep ;i++) 
	{ 
		j=i*m_nTimeStepCount; 
		if(GetCurveCount()==0) 
			pStr.Format("MM:SS"); 
		else if(GetCurveDataValue(0,j)==DATA_VALUE_INVALID) 
			pStr.Format("MM:SS"); 
		else 
		{ 
			time=GetCurveDataTime(0,j); 
			pStr=time.Format("%M:%S"); 
		} 
 
		xx = m_rectChart.left+(int)(i*nWidth); 
			 
        rectTime.SetRect(xx-(int)(nWidth/2),m_rectPaneBottom.top,xx+(int)(nWidth/2),m_rectPaneBottom.bottom); 
		pDC->DrawText(pStr,&rectTime,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
} 
 
void C3DTrendCtrl::PrintName(CDC *pDC) 
{ 
	if(GetCurveCount()==0) 
		return; 
	int  xx; 
	double  nWidth; 
    CString pStr; 
 
	CRect rectName; 
	CFont fontUse,*pFontOld; 
 
	fontUse.CreateFont(m_nNameHeight,0,0,0,600, 
						FALSE, FALSE, 0, ANSI_CHARSET, 
						OUT_DEFAULT_PRECIS,  
						CLIP_DEFAULT_PRECIS, 
						DEFAULT_QUALITY,  
						DEFAULT_PITCH|FF_SWISS, "Arial") ; 
	pFontOld=pDC->SelectObject(&fontUse); 
 
	int nBkModeOld=pDC->SetBkMode(TRANSPARENT); 
	pDC->SetTextColor(m_crName); 
 
	nWidth=m_rectChart.Width()*1.0/ GetCurveCount(); 
	for(int i=0; i< GetCurveCount() ;i++) 
	{ 
		if(GetCurveDispState(i)) 
			continue; 
        pStr.Format("%s", GetCurveName(i)); 
		xx = m_rectChart.left+(int)(i*nWidth); 
        rectName.SetRect((int)(xx+nWidth/8), 
							m_rectPaneTop.CenterPoint().y-m_nNameHeight*3/4, 
							(int)(xx+nWidth), 
							m_rectPaneTop.CenterPoint().y+m_nNameHeight*3/4); 
 
		PaintNameBack(pDC, rectName,i); 
		pDC->DrawText(pStr,&rectName,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
 
	} 
	pDC->SelectObject(pFontOld); 
	pDC->SetBkMode(nBkModeOld); 
}