最近刚刚学习了使用 gdi+ 在窗口上绘制 png 图片, 但还是遇到一个老问题, 就是闪屏的情况。
百度了一下,使用【双缓冲】解决闪屏,其实关于闪屏的问题,3年前我也收藏过相关的文章,现在连我自己都忘记了。
参考资料: https://bbs.csdn.net/topics/350077253 @码侬
//创建内存DC HDC hdcMem = CreateCompatibleDC(hdc); //创建一个bmp内存空间 HBITMAP hBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT); //将bmp内存空间分配给内存DC HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp); //这是使用者需要绘制的画面,全部往内存DC绘制 // 绘制代码....................... 如: Rectangle(hdcMem,0,0,SCREEN_WIDTH,SCREEN_HEIGHT); //将内存DC的内容复制到屏幕显示DC中,完成显示 BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,hdcMem,0,0,SRCCOPY); //清除资源 SelectObject(hdcMem,hOldSel); DeleteDC(hdcMem); 另外,重载OnEraseBkgnd(CDC* pDC),在该函数中不要绘制背景,中直接返回TRUE。 也就是: switch(message) { case WM_ERASEBKGND: { // 重载OnEraseBkgnd(CDC* pDC),在该函数中不要绘制背景,中直接返回TRUE。 return TRUE; }
还有一篇类似的资料: https://blog.csdn.net/lanyzh0909/article/details/5913836
另外有两篇:基于GDI+实现双缓冲技术 https://blog.csdn.net/woaisia/article/details/46788965 https://blog.csdn.net/htt9931/article/details/28641039
下面这个,我没测试:
CPaintDC dc(this); // device context for painting Graphics gr(dc.m_hDC); // Graphics to paint Rect rGdi; gr.GetVisibleClipBounds(&rGdi); // The same as the clip rect //创建缓冲区 Bitmap clBmp(rGdi.Width, rGdi.Height); // Mem bitmap Graphics* grPtr = Graphics::FromImage(&clBmp); // As memDC //利用grPtr在clBmp缓冲区绘图 grPtr->DrawImage(m_PngMeter,clock_Rect); grPtr->TranslateTransform(Pcenter.X,Pcenter.Y); grPtr->RotateTransform(i); grPtr->TranslateTransform(-Pcenter.X,-Pcenter.Y); grPtr->DrawImage(m_PngArrow,picRect); grPtr->ResetTransform(); //将clBmp缓冲区绘制到窗口 gr.DrawImage(&clBmp, rGdi); delete grPtr; //注:使用完缓冲区后,一定要及时释放内才能,尤其是在OnPaint中,否则程序很快占满物理内存,崩溃!