WinCE 防止屏幕闪动的画屏方法

int nWidth = int(GetSystemMetrics(SM_CXSCREEN));//屏幕宽度
int nHeight = int(GetSystemMetrics(SM_CYSCREEN));//屏幕高度

HDC  hdc = ::GetDC(NULL);//hdc指向屏幕

HBITMAP m_hbmBuffer = CreateCompatibleBitmap(hdc, nWidth, nHeight);//创建备份位图

HDC hdcBuf = CreateCompatibleDC(hdc);//指向内存
HBITMAP hbmpBuf = (HBITMAP)SelectObject(hdcBuf, m_hbmBuffer);// 将要绘制的位图设置到内存句柄中

把图像画入内存/

HBITMAP hbitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BACKGROUND));
HDC hdcBmp = CreateCompatibleDC(hdc);
BITMAP bmInfo;
HBITMAP hbmpBmp =  (HBITMAP)SelectObject(hdcBmp, hbitmap);//载入图像信息到hdcBmp
::GetObject(hbitmap,sizeof(bmInfo),&bmInfo);//得到图像大小信息
StretchBlt(hdcBuf,0,0,nWidth,nHeight,hdcBmp,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY);//图像载入内存

SelectObject(hdcBmp, hbmpBmp);
DeleteDC(hdcBmp);//清理句柄

DeleteObject(hbitmap);

//同样把其它图像载入到内存,最后把内存的图像画到屏幕,多个小位图在同一屏时就只要画一次屏,从而避免闪动

///

BitBlt(hdc,0,0,nWidth,nHeight,hdcBuf,0,0,SRCCOPY);//把内存上的图像画到屏幕上

SelectObject(hdcBuf, hbmpBuf);

DeleteDC(hdcBuf);

DeleteDC(hdc);

    在OnEraseBkGnd中,如果你不调用原来缺省的OnEraseBkGnd只是重画背景则不会有闪烁.而在OnPaint里面, 由于它隐含的调用了OnEraseBkGnd,而你又没有处理OnEraseBkGnd函数,这时就和窗口缺省的背景刷相关了.缺省的OnEraseBkGnd操作使用窗口的缺省背景刷刷新背景(一般情况下是白刷),而随后你又自己重画背景造成屏幕闪动. 
    另外一个问题是OnEraseBkGnd不是每次都会被调用的.如果你调用Invalidate的时候参数为TRUE,那么在OnPaint里面隐含调用BeginPaint的时候就产生WM_ERASEBKGND消息,如果参数是FALSE,则不会重刷背景. 

所以解决方法有三个半: 
1.用OnEraseBkGnd实现,不要调用原来的OnEraseBkGnd函数. 
2.用OnPaint实现,同时重载OnEraseBkGnd,其中直接返回. 
3.用OnPaint实现,创建窗口时设置背景刷为空 
4.用OnPaint实现,但是要求刷新时用Invalidate(FALSE)这样 
的函数.(不过这种情况下,窗口覆盖等造成的刷新还是要闪一 
下,所以不是彻底的解决方法) 

上一篇:MFCSpy 的学习


下一篇:2021-07-30