VC++为什么我使用双缓冲,窗口还是闪啊!!

时间:2022-09-07 23:26:28

void CMyFirstMFCView::OnDraw(CDC* pDC)                                                                                         
{
CMyFirstMFCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

if(AssiDlg.m_hWnd==NULL)
{
this->AssiDlg.InitDlg(100,100,200,1,this);
this->AssiDlg.Create(IDD_SET,this);
this->AssiDlg.SetWindowPos(0,coorlist->Distance*DefaultBoard+100,0,NULL,NULL,SWP_NOSIZE|SWP_NOZORDER);
this->AssiDlg.ShowWindow(SW_SHOW);
}

CDC MemDC; //首先定义一个显示设备对象    
CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设备 
MemDC.CreateCompatibleDC(NULL);//这时还不能绘图,因为没有地方画  
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小,也可以自己定义(如:有滚动条时就要大于当前窗口的大小,在BitBlt时决定拷贝内存的哪部分到屏幕上)   
MemBitmap.CreateCompatibleBitmap(pDC,400,400);//将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);//先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色     

this->coorlist->ReDraw(&MemDC,AssiDlg.R,AssiDlg.G,AssiDlg.B,AssiDlg.Scale);   //自绘控件

pDC->BitBlt(0,0,400,400,&MemDC,0,0,SRCCOPY);//绘图完成后的清理 //把前面的pOldBit选回来.在删除MemBitmap之前要先从设备中移除它    
MemDC.SelectObject(pOldBit);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
}



自绘的控件是一个围棋棋盘和他上面的围棋,就算我的算法效率再低,用了双缓冲不应该闪的啊!!!!!!

21 个解决方案

#1


双缓冲失败  要不不会闪的 除非你刷新的时间很短 100ms 刷新一次差不多了  你先把你要花在节目上的图全画在一张图上 然后再把那张图画在设备上 图必须是临时对象 要不会保留之前的图面  我看你有句代码是清空背景什么的 其实没必要 函数结束或你delete后 就被释放掉了  不需要重置图面

#2


引用 1 楼  的回复:
双缓冲失败  要不不会闪的 除非你刷新的时间很短 100ms 刷新一次差不多了  你先把你要花在节目上的图全画在一张图上 然后再把那张图画在设备上 图必须是临时对象 要不会保留之前的图面  我看你有句代码是清空背景什么的 其实没必要 函数结束或你delete后 就被释放掉了  不需要重置图面
其实没有清空背景的代码,那是一些多余的注释。我现在有个疑问,除了我的自绘棋盘外,旁边还有一个工具对话框,那不是自绘的。不知道该怎么处理。如果把整个窗口都放到缓冲区,那个窗口恐怕就被盖住了

#3


将CDC MemDC; 做为类成员变量。不需要delete

#4


看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

#5


引用 4 楼  的回复:
看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

好,我试一试

#6


引用 4 楼  的回复:
看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

我对整个窗口都使用双缓冲来绘制了,还是不行

#7


引用 3 楼  的回复:
将CDC MemDC; 做为类成员变量。不需要delete

作为成员变量看不出有什么好处啊?

#8


不要在ONDRAW函数里绘,这个函数里只是贴图

#9


引用 3 楼  的回复:
将CDC MemDC; 做为类成员变量。不需要delete

我尝试了,但还是不行,程序会报错。

#10


引用 8 楼  的回复:
不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?

#11


引用 10 楼  的回复:
引用 8 楼 的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


View 类里面有OnPaint函数。
那个也可以绘图

#12


引用 10 楼  的回复:
引用 8 楼  的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


OnPaint

#13


引用 12 楼  的回复:
引用 10 楼  的回复:

引用 8 楼  的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


OnPaint


我尝试了,还是没有任何区别

#14


提醒:全屏黑白轮流显示,无论采用什么技术都会闪!

#15


引用 14 楼  的回复:
提醒:全屏黑白轮流显示,无论采用什么技术都会闪!
那么说,我应该把背景设定为和我的棋盘颜色接近的颜色吗?

#16


闪有N种原因:
·前后两帧画面差别太大(只能通过调整画面内容改善,比如淡入淡出)
·绘制新帧的过程慢且显示出来导致某一瞬间看到的图像是残缺图像(用双缓存技术可改善)
·没在显示器回扫期更新显存,出现闪或雪花(旧显卡)
·……

#17


引用 16 楼  的回复:
闪有N种原因:
·前后两帧画面差别太大(只能通过调整画面内容改善,比如淡入淡出)
·绘制新帧的过程慢且显示出来导致某一瞬间看到的图像是残缺图像(用双缓存技术可改善)
·没在显示器回扫期更新显存,出现闪或雪花(旧显卡)
·……

看来图形编程的挣扎之路还长,多谢前辈指导

#18


http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。

#19


引用 18 楼  的回复:
http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。


好呀,多谢了!

#20


刷新的区域尽量小,频率60Hz左右。

#21


引用 18 楼  的回复:
http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。


多亏了各位,还有18楼hymrjgc的源代码,问题终于解决了。的确是把Invalidate的参数设置为FALSE 就好了

#1


双缓冲失败  要不不会闪的 除非你刷新的时间很短 100ms 刷新一次差不多了  你先把你要花在节目上的图全画在一张图上 然后再把那张图画在设备上 图必须是临时对象 要不会保留之前的图面  我看你有句代码是清空背景什么的 其实没必要 函数结束或你delete后 就被释放掉了  不需要重置图面

#2


引用 1 楼  的回复:
双缓冲失败  要不不会闪的 除非你刷新的时间很短 100ms 刷新一次差不多了  你先把你要花在节目上的图全画在一张图上 然后再把那张图画在设备上 图必须是临时对象 要不会保留之前的图面  我看你有句代码是清空背景什么的 其实没必要 函数结束或你delete后 就被释放掉了  不需要重置图面
其实没有清空背景的代码,那是一些多余的注释。我现在有个疑问,除了我的自绘棋盘外,旁边还有一个工具对话框,那不是自绘的。不知道该怎么处理。如果把整个窗口都放到缓冲区,那个窗口恐怕就被盖住了

#3


将CDC MemDC; 做为类成员变量。不需要delete

#4


看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

#5


引用 4 楼  的回复:
看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

好,我试一试

#6


引用 4 楼  的回复:
看上去应该是别的地方出了问题。
不过你那个OnDraw是应该绘制整个窗口的。
而且范围就算覆盖了上面的子控件也不会有问题。
因为子窗口是在父窗口上层。
不会被你绘制的图片覆盖。

我对整个窗口都使用双缓冲来绘制了,还是不行

#7


引用 3 楼  的回复:
将CDC MemDC; 做为类成员变量。不需要delete

作为成员变量看不出有什么好处啊?

#8


不要在ONDRAW函数里绘,这个函数里只是贴图

#9


引用 3 楼  的回复:
将CDC MemDC; 做为类成员变量。不需要delete

我尝试了,但还是不行,程序会报错。

#10


引用 8 楼  的回复:
不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?

#11


引用 10 楼  的回复:
引用 8 楼 的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


View 类里面有OnPaint函数。
那个也可以绘图

#12


引用 10 楼  的回复:
引用 8 楼  的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


OnPaint

#13


引用 12 楼  的回复:
引用 10 楼  的回复:

引用 8 楼  的回复:

不要在ONDRAW函数里绘,这个函数里只是贴图

那该怎么做?


OnPaint


我尝试了,还是没有任何区别

#14


提醒:全屏黑白轮流显示,无论采用什么技术都会闪!

#15


引用 14 楼  的回复:
提醒:全屏黑白轮流显示,无论采用什么技术都会闪!
那么说,我应该把背景设定为和我的棋盘颜色接近的颜色吗?

#16


闪有N种原因:
·前后两帧画面差别太大(只能通过调整画面内容改善,比如淡入淡出)
·绘制新帧的过程慢且显示出来导致某一瞬间看到的图像是残缺图像(用双缓存技术可改善)
·没在显示器回扫期更新显存,出现闪或雪花(旧显卡)
·……

#17


引用 16 楼  的回复:
闪有N种原因:
·前后两帧画面差别太大(只能通过调整画面内容改善,比如淡入淡出)
·绘制新帧的过程慢且显示出来导致某一瞬间看到的图像是残缺图像(用双缓存技术可改善)
·没在显示器回扫期更新显存,出现闪或雪花(旧显卡)
·……

看来图形编程的挣扎之路还长,多谢前辈指导

#18


http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。

#19


引用 18 楼  的回复:
http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。


好呀,多谢了!

#20


刷新的区域尽量小,频率60Hz左右。

#21


引用 18 楼  的回复:
http://download.csdn.net/detail/hymrjgc/1546561

我以前写的中国象棋的源码,里面就用到了,你参考一下吧。


多亏了各位,还有18楼hymrjgc的源代码,问题终于解决了。的确是把Invalidate的参数设置为FALSE 就好了