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)这样
的函数.(不过这种情况下,窗口覆盖等造成的刷新还是要闪一
下,所以不是彻底的解决方法)
标签:hdcBuf,OnEraseBkGnd,闪动,内存,HBITMAP,WinCE,hdc,画屏,hdcBmp 来源: https://blog.51cto.com/u_15298588/3034550