关于MFC画图闪烁的问题

我要在一个对话框上绘图。首先在OnInitDialog()函数中定义了一个计数器SetTimer(1,10,0),然后再OnTimer函数中Invalidate();重绘... 我要在一个对话框上绘图。首先在OnInitDialog()函数中定义了一个计数器SetTimer(1,10,0),然后再OnTimer函数中Invalidate();重绘,来调用OnPaint()函数画图,在Onpaint()函数中画图【】;每次只是多画一个点,这样体现出动态画图的效果。
出现了一个问题,整个画面一直在闪烁。而且时间越短闪烁越明显,当为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);
}
请问针对我的这个情况,应该如何解决呢?
展开
 我来答
bhtzu
2014-03-09 · TA获得超过1.1万个赞
知道大有可为答主
回答量:8088
采纳率:85%
帮助的人:4158万
展开全部
  1. 使用定时器和DC绘图做动画并不靠谱,你这个简单的还行,复杂的肯定没戏。不然也不会有OpenGl之类的东西了,很多动画效果和3D效果甚至需要GPU来进行。

  2. SetTimer(1,10,0);//一般用1/20秒来做动画就可以连续了(一秒20帧效果),也就是50毫秒定时器,不需要10毫秒这么短。

  3. 最简单的优化方法:在OnTimer中,计算xunhuan和xunhuan-1两个点做构成的一个RECT,用InvalidateRect(RECT)代替Invalidate实现局部重绘,效果基本就可以忍受了。

  4. 双缓冲,对你这个程序是可以实现很好的优化的。过程稍微复杂,对话框成员变量的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
展开全部
  1. Timer时间太短,一次Paint的时间小于Timer时间的话,容易造成OnTimer事件堆积.(MFC事件最短时间间隔、肉眼感觉出闪烁的时间频率、Paint的处理时间 要计算并考虑好)

  2. Invalidate会导致背景被重画,你可以不用重画背景。

  3. 每次画图,画过的线段都需要重新画一遍,可以考虑节省掉这部分动作(比如做个图片缓冲,每次画缓冲,再把缓冲Paint出去)

  4. 百度一下"OnPaint()函数的作用原理",先学学里面的知识。

更多追问追答
追问

追答
pDC是野指针,调用CreateCompatibleDC()会有问题的。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
归悦欣cf
2014-03-09 · TA获得超过1443个赞
知道大有可为答主
回答量:4250
采纳率:59%
帮助的人:1311万
展开全部
闪烁的原因是你每隔10毫秒(从视觉效果来看,50毫秒画一次就可以了)Invalidate();一次,这个函数会引起背景不断刷新,因此会有闪烁,解决办法是:结合双缓冲,禁止背景刷新就可以解决这个问题。其实只要你是算法高手,利用这种办法就可以解决很多问题。
追问
我用了双缓冲以后,画图的时间比较长,因为每次都需要重绘,所以时间比较长,请问这个如何解决呢?我编写的程序在上面了,图片里面的就是我的程序
追答
定义一个全局的内存DC,初始化一次就可以,不必每次都要在OnPaint函数里面创建兼容内存DC,内存兼容位图,然后从头画线,如果这样每次都会把前面的图给刷掉,因此需要重头画起,这样很费时间的。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
archmageee4
2014-03-09 · TA获得超过1516个赞
知道大有可为答主
回答量:1581
采纳率:78%
帮助的人:918万
展开全部
奉劝最好别用mfc的图像绘制,很麻烦 我记得用MemDC 可以解决闪烁问题, 但是效果也并不好..所以我奉劝你使用OpenGl来绘制 ,或者采用QT ,wxwidget 等库.MFC 已经过时了,画啥都麻烦
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式