(7)下面添加的定时器响应函数正是本文的重点,为方便对比起见,笔者写了两个OnTimer响应函数,前一个是采用常规的普通方法描点的,运行起来可以很明显地看到画面的闪烁跳动。而后一种则是采用本文所述方法采用的内存画图的方法,运行后几乎画面无闪烁。下面便是两段对比代码的原码部分:
//代码一:有闪烁的代码 void CWaveShowerView::OnTimer(UINT nIDEvent) { if(nIDEvent==0) { CleanScreen(); for(int i=0;i td> DrawPoint(value[i],RGB(0,255,0)); } if(nIDEvent==1) { m_dx+=2; for(int i=0;i td> { value[i].x=i; if(m_dx+i<0) buffer[m_dx+i]=128; if(m_dx+i<-m_DX) m_dx-=2; if(m_dx+i>m_BufLen) buffer[m_dx+i]=128; if(m_dx+i>m_BufLen+m_DX) m_dx-=2; value[i].y=m_DY*(buffer[m_dx+i]-128)/256; } } CFormView::OnTimer(nIDEvent); }
//代码二:无闪烁的代码 void CWaveShowerView::OnTimer(UINT nIDEvent) { if(nIDEvent==0) { CDC* pDC=GetDC(); CDC dc; CBitmap bitmap; CBitmap* pOldBitmap; CRect client; pDC->GetClipBox(client); //检取无效区 //创建一个与pDC兼容的内存设备环境 if(dc.CreateCompatibleDC(pDC)) { //创建一与pDC兼容的位图,大小为整个客户区 if(bitmap.CreateCompatibleBitmap(pDC,rect.Width(), rect.Height())) { //使dc与pDC具有同样的映射关系 OnPrepareDC(&dc,NULL); //将位图选入内存环境 pOldBitmap=dc.SelectObject(&bitmap); //使dc的整个客户区都成无效区 dc.SelectClipRgn(NULL); //再"与上"检取的无效区,使内存环境与 //pDC检取的无效区相等 dc.IntersectClipRect(client); } } CleanScreen(); for(int i=0;i td> DrawPoint(value[i],RGB(0,255,0)); dc.SelectObject(pOldBitmap); ReleaseDC(pDC); } if(nIDEvent==1) { m_dx+=2; for(int i=0;i td> { value[i].x=i; if(m_dx+i<0) buffer[m_dx+i]=128; if(m_dx+i<-m_DX) m_dx-=2; if(m_dx+i>m_BufLen) buffer[m_dx+i]=128; if(m_dx+i>m_BufLen+m_DX) m_dx-=2; value[i].y=m_DY*(buffer[m_dx+i]-128)/256; } } CFormView::OnTimer(nIDEvent); }
(8)虽然通过上述几步可以实现所有的功能,但为了防止内存泄露和养成良好的编程习惯,我们还须做些工作,在视类的构造函数中释放我们曾经申请过的内存以及定时器:
CWaveShowerView::~CWaveShowerView() { delete[] value; KillTimer(0); KillTimer(1); }
四、 编译运行 编译运行此程序,通过菜单选取需要显示的文件(任意文件均可),如在定时器响应代码中采用的是第一种代码,则会看到数据显示的同时伴随着明显的闪烁而采用后一种代码编码则会很平稳的将数据显示出来。
结论:本文介绍的这种方法适用于各种牵扯到数组数据图形显示的程序,比如监控软件、数据分析软件、测量软件等等,具有广泛的应用前景 
说明:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
2/2 首页 上一页 1 2 |