首先说明一点,onpaint 是更新面板用的,作图的话应在控件上进行。
新建 MFC 对话框工程,面板上添加按钮 IDC_START , IDC_SHOW , IDC_STOP
添加两个对话框,ID 分别设为(简写)ld 和 cd。
ld 上添加三个图片控件,并且每一个均关联一个 CSTATIC 型变量。
cd 上添加一个图片控件,操作如上。
分别为两个对话框添加类,名称自己设,我的是 CLineDlg 和 CCompDlg .
主对话框头文件中包含两个类的头文件。
添加声明:
CLineDlg * line_dlg; CCompDlg * comp_dlg;
模态对话框生成:
<pre name="code" class="cpp">line_dlg = new CLineDlg; line_dlg->Create(IDD_LINE_DIALOG, this); comp_dlg = new CCompDlg; comp_dlg->Create(IDD_COMP_DIALOG, this);
void CDrawDlg::OnBnClickedBtStart() { // TODO: 在此添加控件通知处理程序代码 srand((unsigned)time(NULL)); SetTimer(1, 100, NULL); }SHOW 按钮响应函数
void CDrawDlg::OnBnClickedBtShow() { // TODO: 在此添加控件通知处理程序代码 line_dlg->ShowWindow(SW_SHOW); comp_dlg->ShowWindow(SW_SHOW); }STOP 按钮响应函数:
void CDrawDlg::OnBnClickedBtStop() { // TODO: 在此添加控件通知处理程序代码 KillTimer(1); }定时器响应函数:
void CDrawDlg::OnTimer(UINT_PTR nIDEvent) { double k = rand() % 60 / 1.0; line_dlg->DrawLine1(k); k = rand() % 40 / 1.0; line_dlg->DrawLine2(k); k = rand() % 20 / 1.0; line_dlg->DrawLine3(k); double c1 = rand() % 30 / 1.0 + 30; double c2 = rand() % 30 / 1.0; comp_dlg->CompLine(c1, c2); }LineDlg.h 中添加定义:
public: afx_msg void DrawWave(CDC *pDC, CRect &rectPicture, int flags, double m_nzValues[POINT_COUNT]); afx_msg void DrawLine1(double line1); afx_msg void DrawLine2(double line2); afx_msg void DrawLine3(double line3); double m_nzValues1[POINT_COUNT]; double m_nzValues2[POINT_COUNT]; double m_nzValues3[POINT_COUNT]; CStatic m_Line1; CStatic m_Line2; CStatic m_Line3;LineDlg.cpp 中实现:
void CLineDlg::DrawWave(CDC *pDC, CRect &rectPicture, int flags, double m_nzValues[POINT_COUNT]) { float fDeltaX; // x轴相邻两个绘图点的坐标距离 float fDeltaY; // y轴每个逻辑单位对应的坐标值 int nX; // 在连线时用于存储绘图点的横坐标 int nY; // 在连线时用于存储绘图点的纵坐标 CPen newPen; // 用于创建新画笔 CPen *pOldPen; // 用于存放旧画笔 CBrush newBrush; // 用于创建新画刷 CBrush *pOldBrush; // 用于存放旧画刷 //memset(m_nzValues, 0, sizeof(int) * POINT_COUNT); // 计算fDeltaX和fDeltaY fDeltaX = (float)rectPicture.Width() / (POINT_COUNT - 1); if(flags == 1) fDeltaY = (float)rectPicture.Height() / 60; else if(flags == 2) fDeltaY = (float)rectPicture.Height() / 40; else if(flags == 3) fDeltaY = (float)rectPicture.Height() / 20; // 创建黑色新画刷 newBrush.CreateSolidBrush(RGB(0,0,0)); // 选择新画刷,并将旧画刷的指针保存到pOldBrush pOldBrush = pDC->SelectObject(&newBrush); // 以黑色画刷为绘图控件填充黑色,形成黑色背景 pDC->Rectangle(rectPicture); // 恢复旧画刷 pDC->SelectObject(pOldBrush); // 删除新画刷 newBrush.DeleteObject(); // 创建实心画笔,粗度为1,颜色为绿色 newPen.CreatePen(PS_SOLID, 1, RGB(0,255,0)); // 选择新画笔,并将旧画笔的指针保存到pOldPen pOldPen = pDC->SelectObject(&newPen); // 将当前点移动到绘图控件窗口的左下角,以此为波形的起始点 pDC->MoveTo(rectPicture.left, rectPicture.bottom); // 计算m_nzValues数组中每个点对应的坐标位置,并依次连接,最终形成曲线 for (int i=0; i<POINT_COUNT; i++) { nX = rectPicture.left + (int)(i * fDeltaX); nY = rectPicture.bottom - (int)(m_nzValues[i] * fDeltaY); pDC->LineTo(nX, nY); } // 恢复旧画笔 pDC->SelectObject(pOldPen); // 删除新画笔 newPen.DeleteObject(); } void CLineDlg::DrawLine1(double line1) { for (int i=0; i<POINT_COUNT-1; i++) { m_nzValues1[i] = m_nzValues1[i+1]; } // 为最后一个元素赋一个80以内的随机数值(整型) m_nzValues1[POINT_COUNT-1] = line1; CWnd * pWnd = GetDlgItem(IDC_LINE1); CDC * pDC = pWnd->GetDC(); CRect rectPicture; GetDlgItem(IDC_LINE1)->GetClientRect(&rectPicture); // 绘制波形图 DrawWave(pDC, rectPicture, 1, m_nzValues1); } void CLineDlg::DrawLine2(double line2) { for (int i=0; i<POINT_COUNT-1; i++) { m_nzValues2[i] = m_nzValues2[i+1]; } // 为最后一个元素赋一个80以内的随机数值(整型) m_nzValues2[POINT_COUNT-1] = line2; CWnd * pWnd = GetDlgItem(IDC_LINE2); CDC * pDC = pWnd->GetDC(); CRect rectPicture; GetDlgItem(IDC_LINE2)->GetClientRect(&rectPicture); // 绘制波形图 DrawWave(pDC, rectPicture, 2, m_nzValues2); } void CLineDlg::DrawLine3(double line3) { for (int i=0; i<POINT_COUNT-1; i++) { m_nzValues3[i] = m_nzValues3[i+1]; } // 为最后一个元素赋一个80以内的随机数值(整型) m_nzValues3[POINT_COUNT-1] = line3; CWnd * pWnd = GetDlgItem(IDC_LINE3); CDC * pDC = pWnd->GetDC(); CRect rectPicture; GetDlgItem(IDC_LINE3)->GetClientRect(&rectPicture); // 绘制波形图 DrawWave(pDC, rectPicture, 3, m_nzValues3); }
CompDlg.h 中添加:
public: CStatic m_Comp; afx_msg void CompWave(CDC *pDC, CRect &rectPicture, double m_nzValues1[POINT_COUNT], double m_nzValues2[POINT_COUNT]); afx_msg void CompLine(double line1, double line2); double m_nzValues1[POINT_COUNT]; double m_nzValues2[POINT_COUNT];CompDlg.cpp 中实现:
void CCompDlg::CompWave(CDC *pDC, CRect &rectPicture, double m_nzValues1[POINT_COUNT], double m_nzValues2[POINT_COUNT]) { float fDeltaX; // x轴相邻两个绘图点的坐标距离 float fDeltaY; // y轴每个逻辑单位对应的坐标值 int nX; // 在连线时用于存储绘图点的横坐标 int nY; // 在连线时用于存储绘图点的纵坐标 CPen newPen[2]; // 用于创建新画笔 CPen *pOldPen[2]; // 用于存放旧画笔 CBrush newBrush; // 用于创建新画刷 CBrush *pOldBrush; // 用于存放旧画刷 //memset(m_nzValues, 0, sizeof(int) * POINT_COUNT); // 计算fDeltaX和fDeltaY fDeltaX = (float)rectPicture.Width() / (POINT_COUNT - 1); fDeltaY = (float)rectPicture.Height() / 60; // 创建黑色新画刷 newBrush.CreateSolidBrush(RGB(0,0,0)); // 选择新画刷,并将旧画刷的指针保存到pOldBrush pOldBrush = pDC->SelectObject(&newBrush); // 以黑色画刷为绘图控件填充黑色,形成黑色背景 pDC->Rectangle(rectPicture); // 恢复旧画刷 pDC->SelectObject(pOldBrush); // 删除新画刷 newBrush.DeleteObject(); // 创建实心画笔,粗度为1,颜色为绿色 newPen[0].CreatePen(PS_SOLID, 1, RGB(0,255,0)); // 选择新画笔,并将旧画笔的指针保存到pOldPen pOldPen[0] = pDC->SelectObject(&newPen[0]); // 将当前点移动到绘图控件窗口的左下角,以此为波形的起始点 pDC->MoveTo(rectPicture.left, rectPicture.bottom); // 计算m_nzValues数组中每个点对应的坐标位置,并依次连接,最终形成曲线 for (int i=0; i<POINT_COUNT; i++) { nX = rectPicture.left + (int)(i * fDeltaX); nY = rectPicture.bottom - (int)(m_nzValues1[i] * fDeltaY); pDC->LineTo(nX, nY); } // 恢复旧画笔 pDC->SelectObject(pOldPen); // 创建实心画笔,粗度为1,颜色为绿色 newPen[1].CreatePen(PS_SOLID, 1, RGB(255,0,0)); // 选择新画笔,并将旧画笔的指针保存到pOldPen pOldPen[1] = pDC->SelectObject(&newPen[1]); // 将当前点移动到绘图控件窗口的左下角,以此为波形的起始点 pDC->MoveTo(rectPicture.left, rectPicture.bottom); // 计算m_nzValues数组中每个点对应的坐标位置,并依次连接,最终形成曲线 for (int i=0; i<POINT_COUNT; i++) { nX = rectPicture.left + (int)(i * fDeltaX); nY = rectPicture.bottom - (int)(m_nzValues2[i] * fDeltaY); pDC->LineTo(nX, nY); } // 恢复旧画笔 pDC->SelectObject(pOldPen); // 删除新画笔 newPen[0].DeleteObject(); newPen[1].DeleteObject(); } void CCompDlg::CompLine(double line1, double line2) { for (int i=0; i<POINT_COUNT-1; i++) { m_nzValues1[i] = m_nzValues1[i+1]; m_nzValues2[i] = m_nzValues2[i+1]; } // 为最后一个元素赋一个80以内的随机数值(整型) m_nzValues1[POINT_COUNT-1] = line1; m_nzValues2[POINT_COUNT-1] = line2; CWnd * pWnd = GetDlgItem(IDC_COMP); CDC * pDC = pWnd->GetDC(); CRect rectPicture; GetDlgItem(IDC_COMP)->GetClientRect(&rectPicture); // 绘制波形图 CompWave(pDC, rectPicture, m_nzValues1, m_nzValues2); }
最后,不要忘记数组初始化。不初始化的话,图像起始会有一些毛病。
memset(m_nzValues1, 0, sizeof(double) * POINT_COUNT); memset(m_nzValues2, 0, sizeof(double) * POINT_COUNT); memset(m_nzValues3, 0, sizeof(double) * POINT_COUNT);
原文地址:http://blog.csdn.net/u010477528/article/details/43835125