关于MFC画图闪烁的问题
出现了一个问题,整个画面一直在闪烁。而且时间越短闪烁越明显,当为100的时候,闪烁基本么有了。请问如何解决。看了好多什么双缓冲技术,貌似不行。我的程序代码如下:
void Chuatu::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.MoveTo(arrayx.GetAt(0),arrayy.GetAt(0));
for(int a=1;a<xunhuan;a++)
{
dc.LineTo(arrayx.GetAt(a),arrayy.GetAt(a));
}
}
BOOL Chuatu::OnInitDialog()
{
CDialog::OnInitDialog();
int i=0;
fstream in("c:\\restw.dat",ios::in);//读入数据,供OnPaint函数画图使用
while(!in.eof())
{
in>>xin>>yin;
arrayx.Add(xin);
arrayy.Add(yin);
i++;
}
xunhuan=0;
SetTimer(1,10,0);
return TRUE;
}
void Chuatu::OnTimer(UINT nIDEvent)
{
xunhuan++;
Invalidate();
CDialog::OnTimer(nIDEvent);
}
请问针对我的这个情况,应该如何解决呢? 展开
使用定时器和DC绘图做动画并不靠谱,你这个简单的还行,复杂的肯定没戏。不然也不会有OpenGl之类的东西了,很多动画效果和3D效果甚至需要GPU来进行。
SetTimer(1,10,0);//一般用1/20秒来做动画就可以连续了(一秒20帧效果),也就是50毫秒定时器,不需要10毫秒这么短。
最简单的优化方法:在OnTimer中,计算xunhuan和xunhuan-1两个点做构成的一个RECT,用InvalidateRect(RECT)代替Invalidate实现局部重绘,效果基本就可以忍受了。
双缓冲,对你这个程序是可以实现很好的优化的。过程稍微复杂,对话框成员变量的memDC,首次OnPaint创建兼容DC,OnTimer增加一套划线(MoveTo+LineTo),OnPaint里面只需要BitBlt就可以了。
谢谢你的回答,不过我是初学者,还有几个问题想请教您:
您3中说的这个在OnTimer中计算xunhuan和xunhuan-1两个点做构成的一个RECT,是不是就是将我原来在OnPaint中的绘图部分转换到OnTimer中,InvalidateRect(RECT)。OnPaint中的画图部分就不需要了??
不是,3方法中,OnPaint不动。
InvalidateRect 和 Invalidate 功能一样,都是触发重绘,只是前者是局部重绘。
推荐于2016-02-15
Timer时间太短,一次Paint的时间小于Timer时间的话,容易造成OnTimer事件堆积.(MFC事件最短时间间隔、肉眼感觉出闪烁的时间频率、Paint的处理时间 要计算并考虑好)
Invalidate会导致背景被重画,你可以不用重画背景。
每次画图,画过的线段都需要重新画一遍,可以考虑节省掉这部分动作(比如做个图片缓冲,每次画缓冲,再把缓冲Paint出去)
百度一下"OnPaint()函数的作用原理",先学学里面的知识。
我用了双缓冲以后,画图的时间比较长,因为每次都需要重绘,所以时间比较长,请问这个如何解决呢?我编写的程序在上面了,图片里面的就是我的程序
定义一个全局的内存DC,初始化一次就可以,不必每次都要在OnPaint函数里面创建兼容内存DC,内存兼容位图,然后从头画线,如果这样每次都会把前面的图给刷掉,因此需要重头画起,这样很费时间的。