MFC 学习之 模态对话框图片控件上作图

首先说明一点,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);


START 按钮响应函数:

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);











展开阅读全文

没有更多推荐了,返回首页