2024年4月17日发(作者:)
基于VC++6.O实现无闪烁连续实时曲线
王玉菡;曾自强
【摘 要】工业现场常需要实时采集数据并在软件中将数据动态显示出来.运用VC
++6.0编程工具,在基本对话框中的静态文本控件上,利用双缓冲技术实现无闪烁
时间驱动的动态实时曲线,并在实践中取到了较好的效果.
【期刊名称】《重庆理工大学学报》
【年(卷),期】2014(028)004
【总页数】4页(P123-126)
【关键词】VC++6;0;基本对话框;双缓冲;实时曲线;VC;++;6;0
【作 者】王玉菡;曾自强
【作者单位】重庆理工大学电子信息与自动化学院,重庆400054;川庆钻探工程有
限公司测井公司,重庆400021
【正文语种】中 文
【中图分类】TP39
在生产和实验过程中,常常需要对被测对象进行实时数据采集,然后将数据传输到
工控机,以动态曲线的方式显示出来,以便人们对现场的了解和控制。因此显示动
态实时曲线在工控自动化的界面程序设计中是一种不可缺少的功能。它不但可以给
人呈现出一种直观的视觉效果,更重要的是能够实时地显示、存储采集到的数据
[1]。
在实现实时动态曲线的过程中会发现编写出来的曲线经常会出现闪烁的情况,而且
随着显示界面复杂程度的增加和刷新时间的加快,闪烁越加明显,严重影响了软件
的效果[2]。为了解决这一问题,可以采用第三方的软件来进行处理。例如:一是
可以使用组态软件来进行开发;二是使用别人开发的类和DLL库。对于组态软件,
虽然功能较齐全,能够大大缩短工业监控系统开发研制的周期,提高系统的可靠性,
但它们的价格相对比较昂贵,带有加密狗,而且对于小型监控系统来说,有许多功
能用不上,造成了资源的浪费[3]。对于第二种方法,虽然有不少类可以实现动
态曲线,但是大多数实例都是基于单文档的动态曲线,没有X轴动态时间坐标,
而用得最多的基本对话框就更少了,并且这些封装好了的库文件不可修改,引入这
些控件或类后将在工程中加入不少文件,使得工程文件变得庞大。
本文利用VC++6.0平台,基于MFC基本对话框中的静态文本控件,利用双缓冲
技术实现无闪烁时间驱动的动态实时曲线[4]。
地面监控系统软件在定时器的控制下每隔一段时间就采集一次数据,并将数据显示
成曲线。Windows中负责系统与绘图程序之间的信息交换和图形输出的是
GDI(图形设备接口)。GDI建立在抽象层之上,与设备无关,使程序员无需关心硬
件设备及设备驱动就可以将应用程序的输出转化为硬件设备上的输出。在
Windows的MFC中,发送绘图的消息为WM_PAINT,它的响应函数是On-
Paint()函数,所有的GDI绘图程序都在OnPaint ()函数中。当窗口发生变化,创
建窗体或调用了Invalidate(),InvalidateRect()等函数时就会触发WM_PAINT消
息重绘窗口;在重绘窗口时,先响应OnEraseBkgnd()函数利用背景色擦除窗口显
示区,再调用OnPaint()函数重新绘图;当背景色和显示窗口颜色相差较大且刷新
时间较快时,由于这样的一擦一绘,造成了图像颜色的反差,就出现了闪烁问题
[5-7]。如果背景颜色差别较大闪烁就更为明显。
为了解决闪烁问题,单纯的禁止背景重绘是不够的。因为如果这样,每次绘制图像
时都没有将原来的图像清除,造成了图像的残留,于是在窗体重绘时,画面往往会
变得乱七八糟[8]。要实现快速的绘图必须采用双缓冲绘图技术,其基本思路是
先在内存中作图,然后用BitBlt函数将作好的图复制到前台。
2.1 双缓冲
在基本对话框中,为了实现曲线绘制的无闪烁必须采用双缓冲。所谓双缓冲,就是
指绘图不是直接绘制在当前设备上(前端缓冲),而是首先创建一个与当前设备环境
兼容的内存设备环境(后端缓冲),所有绘图工作都在内存中完成,最后再利用
BitBlt将内存设备环境中的内容拷贝到前端设备环境,步骤见图1。由于所有的绘
图操作都是在后端缓冲区内完成的,而在屏幕上只执行一次图形操作,因而能消除
由多重绘制所引起的图形闪烁。
2.2 调用OnPaint()函数和UpdateWindow()函数
所有文献都提到了双缓冲,但是仅使用该方法是不够的。由于MFC具有消息机制,
为了重绘一般是在定时器OnTimer()函数中使用Invalidate ()函数触发
WM_PAINT消息,从而调用OnPaint ()函数进行绘图。但是由于WM_PAINT消
息的优先级很低,需要等消息队列中的其他消息发送完后才能被处理,所以调用
Invalidate等函数后窗口不会立即重绘,还是会出现闪烁。本文的做法是在
OnTimer()函数中直接调用OnPaint()函数,不使用函数触发WM_PAINT消息,
同时在OnPaint ()函数中在获取了静态文本框窗口句柄pWnd后使用它的
UpdateWindow()函数。UpdateWindow与Invalidate类似,都可以触发
WM_PAINT消息,不同之处在于UpdateWindow发送的WM_PAINT消息立即
被执行无需排队,这样就解决了闪烁问题。
采集数据的实时绘制是一个经常需要用到的功能。本文以数据采集为例来说明如何
消除曲线的闪烁。整个采集系统框图如图2所示。首先地面软件每一秒钟向下位
机发送命令请求单片机发送数据,单片机判断请求并作出相应的响应。如果数据格
式正确则回应,否则不回应。上位机收到下位机发送上来的数据后,根据固定格式
读取出数据,并以曲线的方式显示出来。数据及其计算的结果还被存储在数据库中,
以便查询。历史曲线以曲线的方式显示历史数据。
采用本文方法的曲线绘制程序主要步骤:
之后进行前后效果对比。由于是每秒采集一次数据即每秒画一次图,当程序最小化
再放大或是快速拖动时会出现短暂的无曲线现象(见图3)。采用本文的方法后,无
论怎么拖动、遮挡、最小化都不会出现闪烁(见图4)。当停止定时器,中断了与下
位机的通讯后,画面固定,也不会消失。
本文较好地解决了对话框绘图闪烁的问题,能够实现实时滚动的动态曲线,且时间
能够相应地变化。当停止了计时器时,曲线并不会消失。当再次启动定时器时,程
序将根据当前的时间重新绘图。掌握了这种方法之后,用户可以根据自己的需要加
以扩展和改变,就能得到复杂的动态曲线。程序更改后可以同时绘制多条曲线,也
可以设置曲线颜色、线型等属性。
由于本文中对时间精度要求不高,一秒一次,所以采用SetTimer定时器即可。若
要提高要求应采用多媒体定时器。为了更好地绘制不同形状的曲线,最好使用
GDI++,这样效果更佳。
【相关文献】
[1]王玉菡.Visual C++编程实现动态曲线的4种方法[J].重庆工学院学报:自然科学版,2008,
22(6):95-97.
[2]陈喜阳,张克危,彭玉成.VC在监测系统中图形刷新问题的研究[J].工业控制计算机,
2004,17(4):27-29.
[3]魏庆勇,王阳明,陈久康.VC环境下工业监控软件趋势曲线显示画面的实现[J].机电一体化,
2001(6):62-64.
[4]寇光杰,武玉强.基于VC++线程的动态数据曲线的绘制方法[J].计算机应用研究,
2004(5):178-180.
[5]程岩,汤永佐,刘岩.基于VC++实现实时数据监控和显示方法[J].山东科学,2010(2):83
-85.
[6]唐海全,邵才瑞,李洪强.随钻测井曲线无闪烁绘制技术[J].测井技术,2010,34(5):479
-482.
[7]江建国,温少营,张瑞楠.基于双缓冲技术的GDI+无闪烁绘图[J].计算机应用,2012,
32(S2):136-139.
[8]张亮.基于双缓冲技术的VC++图形刷新技术的原理和实现[J].福建电脑,2010(6):110.
[9]Thompson R 开发人员参考手册[M].北京:机械工业出版社,1998.
[10]Davis Chapman.学用Visual C++6.0[M].骆长乐,译.北京:清华大学出版社,1999.


发布评论