在为连连看编一个时间条的时候,因为要响应WM_ONTIMER,发现屏幕闪烁得厉害到让人无法忍受的程度,用了双缓存也不行。
而在ATI绘图的时候就没有这种情况。
不晓得为什么,不知道是不是在OnTimer()里用了Invalidate()的缘故。
百度了下解决方案。发现有一个非常之有效。
就 是重载OnEraseBkgnd(CDC *pDC),其功能相当于OnPaint()的自动重绘。但是要加入消息响应ON_WM_ERASEBKGND()。在OnPaint()中,必须自己创建一个DC(如CClientDC)才能调用bitblt()贴图。但是重载OnEraseBkgnd(CDC*pDC)因为传入了pDC,直接用pDC->bitblt()就OK了。很方便哪~
具体方法如下:
1) 在头文件中加个声明afx_msg BOOL OnEraseBkgnd(CDC*pDC);
2)加个ON_WM_ERASEBKGND() 消息响应,方法如下,在源文件中找到//{{AFX_MSG(CLs8_DlgMFCGameDlg),就是系统给你添加其他消息响应的地方。添加ON_WM_ERASEBKGND()
3)把要写在OnPaint()里的东西都挪到OnEraseBkgnd()里面。
哈哈!屏幕不闪了。但是却有令一个问题。发现时间条虽然在减少了,但是响应鼠标的绘图(比如在连连看牌上画方块)却没法长时间显示在屏幕上了。不怕不怕,听说过区域重绘,百度了下,发现用InvalidateRect(),试验了下。于是把OnTimer()里的Invalidate改成了InvalidateRect()。如下:
void CLs8_DlgMFCGameDlg::OnTimer(UINTnIDEvent)
{
// TODO: Add your message handler code here and/or calldefault
timer--;
CRect rect;
rect.SetRect(TIMERPOSX,TIMERPOSY,TIMERPOSX+600,TIMERPOSY+16);
InvalidateRect(rect,TRUE);
CDialog::OnTimer(nIDEvent);
}
运行了下,发现,安拉!!万事大吉!原来说得神乎其神的区域重画这么简单啊。原来是因为在响应鼠标的函数里也有个Invalidate()。这下两个重绘就可以分开了~