⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linechartctrl.cpp

📁 此 InterVolve 应用程序不仅介绍了使用 Microsoft 基础类的基本知识
💻 CPP
字号:
// LineChartCtrl.cpp : implementation file
//
// Written by Yuheng Zhao (yuheng@ministars.com) 
// http://www.ministars.com
// The original idea and part of the code from Ken C. Len's CHistogramCtrl
// http://www.codeguru.com/controls/histogram_control.shtml
//
// Copyright (c) 1998.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. If 
// the source code in  this file is used in any commercial application 
// then a simple email would be nice.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage whatsoever.
// It's free - so you get what you pay for.
//

#include "stdafx.h"
#include "LineChartCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLineChartCtrl

CLineChartCtrl::CLineChartCtrl()
{
	CLineChartCtrl::RegisterWndClass(AfxGetInstanceHandle());
}

CLineChartCtrl::~CLineChartCtrl()
{
	int nCount = m_items.GetSize();
	
	for (int i = 0; i < nCount; i++)
		delete m_items.GetAt(i);
	m_items.RemoveAll();
}


BEGIN_MESSAGE_MAP(CLineChartCtrl, CWnd)
	//{{AFX_MSG_MAP(CLineChartCtrl)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CLineChartCtrl::RegisterWndClass(HINSTANCE hInstance)
{
	WNDCLASS wc;
	wc.lpszClassName = "LINE_CHART_CTRL"; // matches class name in client
	wc.hInstance = hInstance;
	wc.lpfnWndProc = ::DefWindowProc;
	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = 0;
	wc.lpszMenuName = NULL;
	wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH);
	wc.style = CS_GLOBALCLASS; // To be modified
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;

	return (::RegisterClass(&wc) != 0);
}

void CLineChartCtrl::InvalidateCtrl()
{
	CClientDC dc(this);
	CRect rcClient;
	GetClientRect(rcClient);

	if (m_MemDC.GetSafeHdc() == NULL)
	{
		m_MemDC.CreateCompatibleDC(&dc);
		m_Bitmap.CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height());
		m_MemDC.SelectObject(m_Bitmap);
		
		// draw scale
		m_MemDC.SetBkColor(RGB(0,0,0));
		CBrush bkBrush(HS_CROSS,RGB(0,128,0));
		m_MemDC.FillRect(rcClient,&bkBrush);
	}

	InvalidateRect(rcClient, FALSE);
}

UINT CLineChartCtrl::SetPos(int nIndex, UINT nPos)
{
	if (nIndex >= m_items.GetSize())
		return 0;

	CLineChartItem* pItem = m_items.GetAt(nIndex);

	if (nPos > pItem->m_nUpper)
		nPos = pItem->m_nUpper;
	if (nPos < pItem->m_nLower)
		nPos = pItem->m_nLower;

	pItem->m_nOldPos = pItem->m_nPos;
	pItem->m_nPos = nPos;

	return pItem->m_nOldPos;
}

void CLineChartCtrl::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	CRect rcClient;
	GetClientRect(rcClient);

	// draw scale
	if (m_MemDC.GetSafeHdc() != NULL)
		dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY);
}

void CLineChartCtrl::DrawSpike()
{
	CRect rcClient;
	GetClientRect(rcClient);

	if (m_MemDC.GetSafeHdc() != NULL)
	{
		m_MemDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 4, 0, SRCCOPY);

		// draw scale
		CRect rcRight = rcClient;
		rcRight.left = rcRight.right - 4;
		m_MemDC.SetBkColor(RGB(0,0,0));

		CBrush bkBrush(HS_HORIZONTAL,RGB(0,128,0));  
		m_MemDC.FillRect(rcRight,&bkBrush);

		static BOOL bDrawVerticle = FALSE;
		bDrawVerticle = !bDrawVerticle;

		// Draw Verticle lines only every two steps
		if (bDrawVerticle)
		{
			CPen pen(PS_SOLID, 1, RGB(0,128,0));
			CPen* pOldPen = m_MemDC.SelectObject(&pen);
			m_MemDC.MoveTo(CPoint(rcClient.right-2, rcClient.top));
			m_MemDC.LineTo(CPoint(rcClient.right-2, rcClient.bottom));
			m_MemDC.SelectObject(pOldPen);
		}

		int nCount = m_items.GetSize();
		CLineChartItem* pItem;
		CPoint ptOld, ptNew;
		for (int i=0; i<nCount; i++)
		{
			pItem = m_items.GetAt(i);

			UINT  nRange = pItem->m_nUpper - pItem->m_nLower;
			ptOld.x = rcRight.left-1; // Minus one to make sure to draw inside the area
			ptNew.x = rcRight.right-1;
			ptOld.y = (int)((((float)(nRange - pItem->m_nOldPos))/(float)nRange)
				* (float)rcRight.Height());
			ptNew.y = (int)((((float)(nRange - pItem->m_nPos))/(float)nRange)
				* (float)rcRight.Height());

			CPen pen(PS_SOLID, 1, pItem->m_colorLine);
			CPen* pOldPen = m_MemDC.SelectObject(&pen);
			m_MemDC.MoveTo(ptOld);
			m_MemDC.LineTo(ptNew);
			m_MemDC.SelectObject(pOldPen);
		}
	}
}

BOOL CLineChartCtrl::Add(COLORREF color, UINT Upper, UINT Lower)
{
	CLineChartItem* pItem = new CLineChartItem;
	pItem->m_colorLine = color;
	pItem->m_nLower = Lower;
	pItem->m_nUpper = Upper;
	pItem->m_nPos = 0;
	pItem->m_nOldPos = 0;

	try 
	{
		m_items.Add(pItem);

		InvalidateCtrl();
		return TRUE;
	}
	catch (CMemoryException* e)
	{
		if (pItem !=NULL) 
			delete pItem;
		e->Delete();
		return FALSE;
	}
}

void CLineChartCtrl::Go()
{
	DrawSpike();

	Invalidate(FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -