这里先吐槽一下CSDN,更新之后各种bug,复制的东西还不能撤销,删除还删不全,经常写着写着格式就出问题,网页还会死掉,然后又要重新写。完全不如以前的老版本,除了能复制图片,一无是处。不是我们不想写好文章,写好文章需要时间,你这样别人几个小时写好的文章被你这样一弄,谁还有兴趣写第二遍?
首先在界面上添加picture控件。
初始化
// 以时间为种子来构造随机数生成器
srand((unsigned)time(NULL));
// 启动定时器,ID为1,定时时间为200ms
SetTimer(1, 200, NULL);
通过类向导生成timer事件
void Cpicture绘制Dlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CStatic *m_picDraw = (CStatic*)GetDlgItem(IDC_STATIC); //加载图片控件
CRect rectPicture;
// 将数组中的所有元素前移一个单位,第一个元素丢弃
for (int i=0; i<POINT_COUNT-1; i++)
{
m_nzValues[i] = m_nzValues[i+1];
}
// 为最后一个元素赋一个80以内的随机数值(整型)
m_nzValues[POINT_COUNT-1] = rand() % 80;
// 获取绘图控件的客户区坐标
// (客户区坐标以窗口的左上角为原点,这区别于以屏幕左上角为原点的屏幕坐标)
m_picDraw->GetClientRect(&rectPicture);
// this->GetClientRect(&rectPicture);
// 绘制波形图
drawwave(m_picDraw->GetDC(), rectPicture);
//drawwave(this->GetDC(), rectPicture);
CDialogEx::OnTimer(nIDEvent);
}
编写绘制函数
void Cpicture绘制Dlg::drawwave(CDC *pDC, CRect &rectPicture)
{
float fDeltaX; // x轴相邻两个绘图点的坐标距离
float fDeltaY; // y轴每个逻辑单位对应的坐标值
int nX; // 在连线时用于存储绘图点的横坐标
int nY; // 在连线时用于存储绘图点的纵坐标
CPen newPen; // 用于创建新画笔
CPen *pOldPen; // 用于存放旧画笔
CBrush newBrush; // 用于创建新画刷
CBrush *pOldBrush; // 用于存放旧画刷
// 计算fDeltaX和fDeltaY
fDeltaX = (float)rectPicture.Width() / (POINT_COUNT - 1);
fDeltaY = (float)rectPicture.Height() / 80;
// 创建黑色新画刷
newBrush.CreateSolidBrush(RGB(100,100,100));
// 选择新画刷,并将旧画刷的指针保存到pOldBrush
pOldBrush = pDC->SelectObject(&newBrush);
// 以黑色画刷为绘图控件填充黑色,形成黑色背景
pDC->Rectangle(rectPicture);
// 恢复旧画刷
pDC->SelectObject(pOldBrush);
// 删除新画刷
newBrush.DeleteObject();
// 创建实心画笔,粗度为1,颜色为绿色
newPen.CreatePen(PS_SOLID, 1, RGB(255,100,50));
// 选择新画笔,并将旧画笔的指针保存到pOldPen
pOldPen = pDC->SelectObject(&newPen);
// 将当前点移动到绘图控件窗口的左下角,以此为波形的起始点
pDC->MoveTo(rectPicture.left, rectPicture.bottom);
// 计算m_nzValues数组中每个点对应的坐标位置,并依次连接,最终形成曲线
for (int i=0; i<POINT_COUNT; i++)
{
nX = rectPicture.left -1+ (int)(i * fDeltaX);
nY = rectPicture.bottom -1- (int)(m_nzValues[i] * fDeltaY);
pDC->LineTo(nX, nY);
}
// 恢复旧画笔
pDC->SelectObject(pOldPen);
// 删除新画笔
newPen.DeleteObject();
}
效果