⽬的:使⽤控制台程序带MFC类库画⼀个动态曲线图
参考链接:
操作步骤
1. 创建⼀个勾选MFC类库的控制台程序
上⼀章讲过,此处不做赘述。
2. 新建⼀个窗⼝程序
3. 编写动态折线图
chart.cpp
// chart.cpp : implementation file
//
#include "pch.h"
#include "stdafx.h"
#include "CPUUsage.h"
#include "chart.h"
#include "afxdialogex.h"
// chart dialog
IMPLEMENT_DYNAMIC(chart, CDialog)
chart::chart(CWnd* pParent /*=nullptr*/)
: CDialog(IDD_chart, pParent)
{
}
chart::~chart()
{
}
void chart::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CUSTOM_CHART, m_ChartCtrl); }
BEGIN_MESSAGE_MAP(chart, CDialog)
ON_WM_SIZE()
ON_WM_TIMER()
ON_WM_PAINT()
END_MESSAGE_MAP()
#define DATA_SHOW_LENGHT 2000 //总共显⽰的点个数#define DATA_UPDATE_LENGHT 10 //每次更新的点个数#define DATA_SHOW_X_AXIS 2000 //X轴显⽰的点最⼤值#define DATA_SHOW_Y_AXIS 1000 //Y轴显⽰的点最⼤值//要显⽰点的缓冲数据
static double xBuff[DATA_SHOW_LENGHT] = { 0 };
static double yBuff[DATA_SHOW_LENGHT] = { 0 };
//显⽰点数据包初始化
void chart::DataBuffInit(void)
{
for (int i = 0; i < DATA_SHOW_LENGHT; i++) {
xBuff[i] = i;
yBuff[i] = 50;// cos((i)) * 10 + 50;
}
//初始化画图界⾯窗⼝
void chart::ChartCtrlInit(void) {
//⼿动创建显⽰窗⼝
//CRect rect, rectChart;
//GetDlgItem(IDC_CUSTOM_SHOW)->GetWindowRect(&rect);
//ScreenToClient(rect);
//rectChart = rect;
//rectChart.top = rect.bottom + 3;
//rectChart.bottom = rectChart.top + rect.Height();
//m_ChartCtrl2.Create(this, rectChart, IDC_CUSTOM_SHOW2);
//m_ChartCtrl2.ShowWindow(SW_SHOWNORMAL);
///////////////////////显⽰主题/////////////////////////////
m_ChartCtrl.GetTitle()->AddString(_T("CPU Usage"));
///////////////////////创建坐标xy标识/////////////////////////////
//m_ChartCtrl.GetBottomAxis()->GetLabel()->SetText(_T("强度"));
//m_ChartCtrl.GetLeftAxis()->GetLabel()->SetText(_T("采样点"));
///////////////////////创建坐标显⽰范围/////////////////////////////
CChartAxis *pAxis = NULL;
pAxis = m_ChartCtrl.CreateStandardAxis(CChartCtrl::BottomAxis);
pAxis->SetMinMax(0, DATA_SHOW_X_AXIS);
pAxis = m_ChartCtrl.CreateStandardAxis(CChartCtrl::LeftAxis);
pAxis->SetMinMax(0, DATA_SHOW_Y_AXIS);
}
// CmyApplicationDlg 消息处理程序
BOOL chart::OnInitDialog()
{
CDialog::OnInitDialog();
//获取显⽰的对话框⼤⼩
CRect rect;
GetClientRect(&rect);
oldPiont.x = rect.right - rect.left;
oldPiont.y = rect.bottom - rect.top;
// 设置此对话框的图标。当应⽤程序主窗⼝不是对话框时,框架将⾃动
// 执⾏此操作
// TODO: 在此添加额外的初始化代码
DataBuffInit();
ChartCtrlInit();
SetTimer(0, 100, NULL);
return TRUE; // 除⾮将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最⼩化按钮,则需要下⾯的代码
// 来绘制该图标。对于使⽤⽂档/视图模型的 MFC 应⽤程序,
// 这将由框架⾃动完成。
void chart::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // ⽤于绘制的设备上下⽂
SendMessage(WM_ICONERASEBKGND, reinterpret_cast // 使图标在⼯作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; } else { CDialog::OnPaint(); } } void chart::Resize(void) { float fsp[2]; POINT newPoint;//获取当前对话框⼤⼩ CRect newRect;//获取当前对话框的坐标 GetClientRect(&newRect); newPoint.x = newRect.right - newRect.left; newPoint.y = newRect.bottom - newRect.top; fsp[0] = (float)newPoint.x / oldPiont.x; fsp[1] = (float)newPoint.y / oldPiont.y;int woc; CRect rect; CPoint oldTLPoint, newTLPoint;//左上⾓ CPoint oldBRPoint, newBRPoint;//右下⾓ //列出所有的⼦空间 HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); while (hwndChild) { woc = ::GetDlgCtrlID(hwndChild);//取得ID GetDlgItem(woc)->GetWindowRect(rect); ScreenToClient(rect); oldTLPoint = rect.TopLeft(); newTLPoint.x = long(oldTLPoint.x*fsp[0]); newTLPoint.y = long(oldTLPoint.y*fsp[1]); oldBRPoint = rect.BottomRight(); newBRPoint.x = long(oldBRPoint.x*fsp[0]); newBRPoint.y = long(oldBRPoint.y*fsp[1]); rect.SetRect(newTLPoint, newBRPoint); GetDlgItem(woc)->MoveWindow(rect, TRUE); hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT); } oldPiont = newPoint; return; } void chart::OnSize(UINT nType, int cx, int cy) { //窗体⼤⼩发⽣变动。处理函数resize if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED) { Resize(); } } void chart::DataShow(double *xb, double *yb, int len) { m_ChartCtrl.EnableRefresh(false); CChartLineSerie *pLineSerie; m_ChartCtrl.RemoveAllSeries(); pLineSerie = m_ChartCtrl.CreateLineSerie(); pLineSerie->SetSeriesOrdering(poNoOrdering);//设置为⽆序 pLineSerie->AddPoints(xb, yb, len); UpdateWindow(); m_ChartCtrl.EnableRefresh(true); } void chart::OnTimer(UINT nIDEvent) { static int offset = 0; for (int m = 0; m < DATA_SHOW_LENGHT - DATA_UPDATE_LENGHT; m++) { //xd[m] = xd[DATA_UPDATE_LENGHT + m]; yBuff[m] = yBuff[DATA_UPDATE_LENGHT + m]; } int index = DATA_SHOW_LENGHT - DATA_UPDATE_LENGHT; for (int i = 0; i < DATA_UPDATE_LENGHT; i++) { //yd[index + i] = cos((index + i + w)/5) * 50 + 100+rand() / 1000; yBuff[index + i] = cos((i + offset) / 5) * DATA_SHOW_Y_AXIS / 4 + rand() / 1000 + DATA_SHOW_Y_AXIS / 2; } DataShow(xBuff, yBuff, DATA_SHOW_LENGHT); offset++; if (offset > 10000) { offset = 0; } } View Code chart.h #pragma once #include "ChartCtrl/ChartCtrl.h" #include "ChartCtrl/ChartTitle.h" #include "ChartCtrl/ChartLineSerie.h" #include "ChartCtrl/ChartAxisLabel.h" // chart dialog class chart : public CDialog { DECLARE_DYNAMIC(chart) public: chart(CWnd* pParent = nullptr); // standard constructorvirtual ~chart(); // Dialog Data #ifdef AFX_DESIGN_TIME enum { IDD = IDD_chart }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // 实现 protected: // ⽣成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnTimer(UINT nIDEvent); DECLARE_MESSAGE_MAP() public: POINT oldPiont; void Resize(void); CChartCtrl m_ChartCtrl; void ChartCtrlInit(void); void DataBuffInit(void); void DataShow(double *xb, double *yb, int len); }; View Code 4. 控制台调⽤动态折线图 chart *chartdialog = new chart; int ReturnValue = chartdialog->DoModal(); // Show the dialog printf("%d View Code 效果图 可能出现的问题 1. 在编译的时候,ChartCtrl⾥⾯的cpp⽼是出现没有"pch.h"即预编译头的问题,所以⼲脆取消了预编译头进⾏编译。 2. 将ChartCtrl库放到项⽬⾥。添加之后取名为ChartCtrl,然后将⽂件都已Add --> Existing Item的⽅式加进项⽬⾥。ChartCtrl⽂件夹的存放路径与控制台的cpp⽂件同⽬录。 源码: CPUUsage.cpp // CPUUsage.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include "pch.h" #include "framework.h" #include "chart.h" #include "CPUUsage.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // The one and only application object CWinApp theApp; using namespace std; int main() { int nRetCode = 0; HMODULE hModule = ::GetModuleHandle(nullptr); if (hModule != nullptr) { // initialize MFC and print and error on failure if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0)) { // TODO: code your application's behavior here. wprintf(L"Fatal Error: MFC initialization failed\\n"); nRetCode = 1; } else { // TODO: code your application's behavior here. chart *chartdialog = new chart; int ReturnValue = chartdialog->DoModal(); // Show the dialog printf("%d } } else { // TODO: change error code to suit your needs wprintf(L"Fatal Error: GetModuleHandle failed\\n"); nRetCode = 1; } return nRetCode; } View Code OK.下载本文