首先,设置Timer,然后在OnTimer函数中完成数据收集和绘图动作:
设置Timer:
void CTabPage2::OnStartDraw()
{
SetTimer(1, 1000, NULL);
}
完成Timer操作:
void CTabPage2::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CDC *pDC; //建立目标设备DC
pDC=GetDlgItem(IDC_Bmp)->GetDC(); //将目标设备--位图控件的DC付给pDC
CBitmap bmp; //建立后台位图
bmp.CreateCompatibleBitmap(pDC,900,380); //根据上面目标设备pDC的性能为后台位图创建内存
CDC bDC; //创建后台DC指针
bDC.CreateCompatibleDC(pDC); //根据目标设备pDC性能为后台DC创建内存
bDC.SelectObject(&bmp); //后台DC选择上后台位图
//----------------------------------------------------------------------------------------------------------------------------------------------
// 在后台DC中完成绘图
//----------------------------------------------------------------------------------------------------------------------------------------------
//*******************************************
//设置剪裁区
CRgn rgn;
rgn.CreateRectRgn(0,0,900,380); //创建一个矩形裁剪区,对象为rgn
bDC.SelectClipRgn(&rgn); //选择该裁剪区,绘图在此裁剪区中完成,超出部分不显示
//*******************************************
//画背景
CBrush brush(RGB(128,128,128));
CBrush *old = bDC.SelectObject(&brush);
CRect rect;
rect.SetRect(0,0,900,380);
bDC.Rectangle(rect);
bDC.SelectObject(old);
//*********************************************
//根据USB传回数据画两个圆
//Draw Circle use brush
CBrush brush1(RGB(255,0,0)); //red
old = bDC.SelectObject(&brush1);
CRect cRect;
cRect.SetRect(m_IObuffer.USB_Buffer[0],m_IObuffer.USB_Buffer[0],m_IObuffer.USB_Buffer[0],m_IObuffer.USB_Buffer[0]); //圆心是USBbuffer第一个字节数据
cRect.InflateRect(50,50); //半径是50
bDC.Ellipse(cRect);
bDC.SelectObject(old);
CBrush brush2(RGB(255,255,0)); //yellow
old = bDC.SelectObject(&brush2);
cRect.SetRect(m_IObuffer.USB_Buffer[1],m_IObuffer.USB_Buffer[1],m_IObuffer.USB_Buffer[1],m_IObuffer.USB_Buffer[1]); //圆心是USBbuffer第二个字节数据
cRect.InflateRect(30,30); //半径是30
bDC.Ellipse(cRect);
bDC.SelectObject(old);
//---------------------------------------------------------------------------------------------------------------------------------------
//将后台的画面在目标位图控件上显示
//----------------------------------------------------------------------------------------------------------------------------------------
pDC->BitBlt(0,0,900, 380, &bDC, 0, 0, SRCCOPY);
CDialog::OnTimer(nIDEvent);
return;
}
总结:
本例应用场合是,实时采集USB传回的坐标数据,并以接收到的数据坐标为圆心绘圆。使用BitBlt绘图的原因是,前一次收到的点绘出的圆不出现在下次的画面上。采用的方法———重绘。即,每次先将图画在后台,画好后用BitBlt将图copy到真正的位图控件中显示。所以在真正的位图控件中每次都是重新绘图,会将上一次的图擦去,不会把之前画的圆留在画面上。
重绘的步骤:
1. 建立后台DC和后台位图,该DC和BMP都是虚拟的;
CDC bDC;
CBitmap bmp;
2.创建实际位图DC
CDC *pDC;
pDC=GetDlgItem(IDC_Bmp)->GetDC();
3. 根据实际位图DC为后台DC和BMP分配内存
bDC.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,900,380);
4. 让后台DC选择后台BMP用以画图
bDC.SelectObject(&bmp);
5.根据具体绘图要求在后台DC中绘图(注意这里画的图都是画在内存中,不会显示出来)
如:
bDC.SelectClipRgn(&rgn); //选择该裁剪区,绘图在此裁剪区中完成,超出部分不显示
bDC.Rectangle(rect);
bDC.Ellipse(cRect);
等等;
6.最后用BitBlt函数将后台DC中画好的图显示到实际的位图中
pDC->BitBlt(0,0,900, 380, &bDC, 0, 0, SRCCOPY);