GDI用了双缓冲为什么还是闪?

时代阿三 2016-06-11 07:59:19
HDC hdc;
HDC yin_hdc=CreateCompatibleDC(hdc);
PAINTSTRUCT ps;
RECT rc;
HBITMAP hBmp = CreateCompatibleBitmap(hdc,1000,600);
HBITMAP hOldBmp = (HBITMAP)SelectObject(yin_hdc,hBmp);
。。。。。
case WM_CREATE:
SetTimer(hwnd,1,100,NULL); //建立计时器,每?秒发出WM_TIMER消息.
hdc=GetDC(hwnd);
hdctkr = CreateCompatibleDC(yin_hdc);
hdctkg = CreateCompatibleDC(yin_hdc);
hdctkt = CreateCompatibleDC(yin_hdc);
。。。。。
case WM_PAINT:
yin_hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rc);
。。。。。
DrawTransBitmap(yin_hdc,x1,y1,60,60,hdctkr,0,0,SRCPAINT);
DrawTransBitmap(yin_hdc,x2,y2,60,60,hdctkg,0,0,SRCPAINT);
BitBlt(hdc,0,0,1000,600,yin_hdc,0,0,SRCCOPY);
SelectObject(yin_hdc,hOldBmp);
EndPaint(hwnd,&ps);
break;
case WM_TIMER: //处理由计时器发出的消息.
InvalidateRect(hwnd,NULL,1); //刷新用户区.
break;
case WM_DESTROY:
。。。。。。

是不是用法错了?求大神解决
...全文
284 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
时代阿三 2016-06-12
  • 打赏
  • 举报
回复
引用 7 楼 jennyvenus 的回复:
双缓存就是在内存中画图,然后bitblt到屏幕上。
还是不行,弄出来全白qwq
xiaohuh421 2016-06-12
  • 打赏
  • 举报
回复
因为MFC比较坑, 背景的刷新与前景刷新,总不在同一时间片上. 只要调用invalidate, 必然会闪的. 一般都是直接绘制, 不需要invalidate. 当然, 这种方法就需要把背景都要绘制一编. 不然, 就会看到图像全部重叠在一起.
ooolinux 2016-06-12
  • 打赏
  • 举报
回复
引用 4 楼 baidu_33674471 的回复:
不对啊,感觉我并没有使用双缓冲的效果 删了BitBlt(hdc,0,0,1000,600,yin_hdc,0,0,SRCOPY);也能显示画面,这不是表示我本来就在屏幕上绘图,这应该是我没用到双缓冲吧,求教双缓冲怎么用。
你的代码: case WM_PAINT: yin_hdc=BeginPaint(hwnd,&ps); //这样子yin_hdc就成了直接绘图屏幕了,改成hdc=BeginPaint(hwnd,&ps); 后面BitBlt的逻辑就对了,SRCOPY应为SRCCOPY
用户 昵称 2016-06-12
  • 打赏
  • 举报
回复
双缓存就是在内存中画图,然后bitblt到屏幕上。
ooolinux 2016-06-12
  • 打赏
  • 举报
回复
试试看:
HDC hdc,yin_hdc; 
HBITMAP hBmp,hOldBmp;
。。。。。

case WM_CREATE: 
	hdc=GetDC(hwnd); 
    yin_hdc=CreateCompatibleDC(hdc); 
    hBmp = CreateCompatibleBitmap(hdc,1000,600); 
    hOldBmp = (HBITMAP)SelectObject(yin_hdc,hBmp);

//定时器放到最后    
	SetTimer(hwnd,1,100,NULL);    //建立计时器,每?秒发出WM_TIMER消息. 
    
    break;
    
case WM_PAINT: 
	全部绘图到yin_hdc;
	
	hdc=GetDC(hwnd); 
	BitBlt(hdc,0,0,1000,600,yin_hdc,0,0,SRCCOPY); //一次性Blt到hdc屏幕
	ReleaseDC(hwnd,hdc);
    break;
    
case WM_TIMER:                        //处理由计时器发出的消息. 
	InvalidateRect(hwnd,NULL,1);    //刷新用户区. 
	break; 
case WM_DESTROY: 
	DeleteObject(hBmp);
	DeleteDC(yin_hdc);
	删除计时器;
	break; 	
Eleven 2016-06-12
  • 打赏
  • 举报
回复
MSDN上有段双缓冲的代码可以参考一下:

The following example code, from an application that captures an image of the entire desktop, creates a compatible device context and a bitmap with the appropriate dimensions, selects the bitmap into the compatible DC, and then copies the image using the BitBlt function. 

// Create a normal DC and a memory DC for the entire screen. The 
// normal DC provides a "snapshot" of the screen contents. The 
// memory DC keeps a copy of this "snapshot" in the associated 
// bitmap. 
 
hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); 
hdcCompatible = CreateCompatibleDC(hdcScreen); 
 
// Create a compatible bitmap for hdcScreen. 
 
hbmScreen = CreateCompatibleBitmap(hdcScreen, 
                     GetDeviceCaps(hdcScreen, HORZRES), 
                     GetDeviceCaps(hdcScreen, VERTRES)); 
 
if (hbmScreen == 0) 
    errhandler("hbmScreen", hwnd); 
 
// Select the bitmaps into the compatible DC. 
 
if (!SelectObject(hdcCompatible, hbmScreen)) 
    errhandler("Compatible Bitmap Selection", hwnd); 
 
        // Hide the application window. 
 
        ShowWindow(hwnd, SW_HIDE); 
 
         //Copy color data for the entire display into a 
         //bitmap that is selected into a compatible DC. 
 
        if (!BitBlt(hdcCompatible, 
               0,0, 
               bmp.bmWidth, bmp.bmHeight, 
               hdcScreen, 
               0,0, 
               SRCCOPY)) 
 
        errhandler("Screen to Compat Blt Failed", hwnd); 
 
        // Redraw the application window. 
 
        ShowWindow(hwnd, SW_SHOW); 
时代阿三 2016-06-12
  • 打赏
  • 举报
回复
引用 12 楼 u010165006 的回复:
试试: HDC yin_hdc; //全局变量放开头部分 HBITMAP hBmp; //全局变量放开头部分
感谢,解决了,居然要设置成全局,都没想到qwq
时代阿三 2016-06-12
  • 打赏
  • 举报
回复
不对啊,感觉我并没有使用双缓冲的效果 删了BitBlt(hdc,0,0,1000,600,yin_hdc,0,0,SRCOPY);也能显示画面,这不是表示我本来就在屏幕上绘图,这应该是我没用到双缓冲吧,求教双缓冲怎么用。
时代阿三 2016-06-12
  • 打赏
  • 举报
回复
但我除了背景都需要改变啊
ooolinux 2016-06-12
  • 打赏
  • 举报
回复
试试: HDC yin_hdc; //全局变量放开头部分 HBITMAP hBmp; //全局变量放开头部分 。。。。。 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT rc; case WM_CREATE: hdc=GetDC(hwnd); yin_hdc=CreateCompatibleDC(hdc); hBmp = CreateCompatibleBitmap(hdc,1000,600); SelectObject(yin_hdc,hBmp); ReleaseDC(hwnd,hdc); hdctkr = CreateCompatibleDC(yin_hdc); hdctkg = CreateCompatibleDC(yin_hdc); hdctkt = CreateCompatibleDC(yin_hdc); //定时器放到最后 SetTimer(hwnd,1,100,NULL); //建立计时器,每?秒发出WM_TIMER消息. break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); //yin_hdc改成hdc,这行也可以放在BitBlt前面 GetClientRect(hwnd,&rc); 。。。。。 DrawTransBitmap(yin_hdc,x1,y1,60,60,hdctkr,0,0,SRCPAINT); DrawTransBitmap(yin_hdc,x2,y2,60,60,hdctkg,0,0,SRCPAINT); BitBlt(hdc,0,0,1000,600,yin_hdc,0,0,SRCCOPY); // SelectObject(yin_hdc,hOldBmp); 注释掉这句 EndPaint(hwnd,&ps); break; case WM_TIMER: //处理由计时器发出的消息. InvalidateRect(hwnd,NULL,1); //刷新用户区. 1应该写true break; case WM_DESTROY: DeleteObject(hBmp); DeleteDC(yin_hdc); KillTimer(hwnd,1); PostQuitMessage(0); break; ———————————————————————— 不明白你为什么要: hdctkr = CreateCompatibleDC(yin_hdc); hdctkg = CreateCompatibleDC(yin_hdc); hdctkt = CreateCompatibleDC(yin_hdc); 这么多dc,最好绘图全部绘制到yin_hdc,然后一次性BitBlt到hdc屏幕。
科学家 2016-06-12
  • 打赏
  • 举报
回复
三招: 1.重载并禁用WM_ERASEBKGND消息 2.OnPaint中双缓冲 3.如果A窗口上有按钮等子控件或子窗口,请给A窗口添加WS_CLIPCHILDREN和WS_CLIPSIBLINGS俩属性
走好每一步 2016-06-11
  • 打赏
  • 举报
回复
话说要搞MFC,英文得过关。
走好每一步 2016-06-11
  • 打赏
  • 举报
回复
case WM_TIMER: //处理由计时器发出的消息. InvalidateRect(hwnd,NULL,1); //刷新用户区. 你刷屏幕刷的这么凶,什么双缓冲都是浮云。。。。 InvalidateRect是使某个区域无效,参数NULL是全部客户区了。 一般来说,你要使得不闪烁,就不能刷全部的客户区,只能刷要改变界面的地方。

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧