手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

VC 大数据量绘图时无闪烁刷屏技术实现

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

{
 CFormView::OnInitialUpdate();
 GetParentFrame()->RecalcLayout();
 ResizeParentToFit();
 GetScreenRect();
 for(int i=0;i<m_DX;i )
  value[i].x=value[i].y=0;
 SetTimer(0,10,NULL);
}
void CWaveShowerView::OnOpenData()
{
 CString FileName="";
 CFile file;
 CFileDialog dlg(TRUE,"*","*.*",
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"所有文件(*.*)|*.*||",NULL);
 if(dlg.DoModal()==IDOK)
 {
  KillTimer(1);
  FileName=dlg.GetPathName();
  file.Open(FileName,CFile::modeReadWrite);
  m_BufLen=file.GetLength();
  buffer= new unsigned char[m_BufLen m_DX 10];
  file.Read(buffer,m_BufLen);
  file.Close();
  SetTimer(1,10,NULL);
 }
}
  下面将要添加的定时器响应函数正是本文的重点,为方便对比起见,笔者写了两个OnTimer响应函数,前一个是采用常规的普通方法描点的,运行起来可以很明显地看到画面的闪烁跳动。而后一种则是采用本文所述方法采用的内存画图的方法,运行后几乎画面无闪烁。下面便是两段对比代码的原码部分:

//代码一:有闪烁的代码
void CWaveShowerView::OnTimer(UINT nIDEvent)
{
 if(nIDEvent==0)
 {
  CleanScreen();
  for(int i=0;i<m_DX;i )
   DrawPoint(value[i],RGB(0,255,0));
 }
 if(nIDEvent==1)
 {
  m_dx =2;
  for(int i=0;i<m_DX;i )
  {
   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<m_DX;i )
   DrawPoint(value[i],RGB(0,255,0));
  dc.SelectObject(pOldBitmap);
  ReleaseDC(pDC);
 }
 if(nIDEvent==1)
 {
  m_dx =2;
  for(int i=0;i<m_DX;i )
  {
   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);
}
  虽然通过上述几步可以实现所有的功能,但为了防止内存泄露和养成良好的编程习惯,我们还须做些工作,在视类的构造函数中释放我们曾经申请过的内存以及定时器:

CWaveShowerView::~CWaveShowerView()
{
 delete[] value;
 KillTimer(0);
 KillTimer(1);
}
  小结

  编译运行此程序,通过菜单选取需要显示的文件(任意文件均可),如在定时器响应代码中采用的是第一种代码,则会看到数据显示的同时伴随着明显的闪烁而采用后一种代码编码则会很平稳的将数据显示出来。本文介绍的这种方法适用于各种牵扯到数组数据图形显示的程序,比如监控软件、数据分析软件、测量软件等等,具有广泛的应用前景。本文所述程度代码在Windows 2000 Professional SP4下由Microsoft Visual C 6.0编译通过。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

上一页 1 2下一页
[打印] [关闭]
Google
相关文章
上一篇:VC中自动改变控件位置和大小的对话框类
下一篇:在VC 中实现无标题栏对话框的拖动
热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS