【MFC】关于 OnPaint 里面使用双缓冲绘图 依然不停闪烁

智能牛蛙 2014-02-27 04:43:34
代码如下:

void CdlgPlayerWnds::OnPaint()
{
CPaintDC dc(this);

RECT rect;
SetParent(CWnd::FromHandle(m_hwndOld));
GetParent()->GetClientRect(&rect);//获取窗口大小信息

CDC mdc,bufdc;
HBITMAP bmp;
mdc.CreateCompatibleDC(&dc);
bufdc.CreateCompatibleDC(&dc);
bmp=CreateCompatibleBitmap(dc.GetSafeHdc(),rect.right,rect.bottom);

mdc.SelectObject(&bmp);
m_hBmpNoVedio=(HBITMAP)LoadImage(NULL,"./res/nobmp.bmp",IMAGE_BITMAP,900,600,LR_LOADFROMFILE);//从文件导入位图

BITMAP bmInfo;
GetObject(m_hBmpNoVedio,sizeof(BITMAP),(LPBYTE)&bmInfo); //得到图片尺寸

bufdc.SelectObject(&m_hBmpNoVedio);
mdc.StretchBlt(0,0,rect.right,rect.bottom,&bufdc,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY);
dc.BitBlt(0,0,rect.right,rect.bottom,&bufdc,0,0,SRCCOPY);
}

程序执行后窗口里面的背景图不停得闪烁,是因为以上代码的原因?还是因为这个OnPaint函数在一个死循环中?
...全文
608 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuh2013 2014-03-01
  • 打赏
  • 举报
回复
引用 6 楼 u011021711 的回复:
我把绘图代码写到OnEraseBkgnd(CDC* dc)里面了,如下: BOOL CdlgPlayerWnds::OnEraseBkgnd(CDC* dc) { if(1==m_lViewNumber) { RECT rect; GetParent()->GetClientRect(&rect); dc=GetDC(); CDC mdc; mdc.CreateCompatibleDC(dc); HBITMAP hold; CBitmap cbmp; cbmp.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP_NOVEDIO)); hold=(HBITMAP)mdc.SelectObject(&cbmp); BITMAP bmInfo; GetObject(cbmp, sizeof(BITMAP), (LPBYTE)&bmInfo); //得到图片尺寸 dc->StretchBlt(0,0,rect.right,rect.bottom,&mdc,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY); mdc.SelectObject(&hold); mdc.DeleteDC(); CWnd::ReleaseDC(dc); DeleteObject(cbmp); } return TRUE; } 现在窗口不动的话背景图不闪烁了,但是拉伸窗口背景图还是闪烁啊...而且有其他窗口遮挡这窗口的时候,窗口上就会出现背景图,怎么让遮挡的时候不重绘呢?
这个MFC基本解决不了,要用到Windows API. 你可以在View 里屏蔽掉所有消息,自己来绘图。
worldy 2014-02-28
  • 打赏
  • 举报
回复
矫枉过正,按下面思路写吧,这里不好编辑,花挎号可能没配对,你你自己配对一下 BOOL CdlgPlayerWnds::OnEraseBkgnd(CDC* dc) { return true; } BOOL CdlgPlayerWnds::OnPaint() { if(1==m_lViewNumber) { RECT rect; GetParent()->GetClientRect(&rect); CPaintDC dc(this); CDC mdc; mdc.CreateCompatibleDC(&dc); HBITMAP hold; CBitmap cbmp; cbmp.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP_NOVEDIO)); hold=(HBITMAP)mdc.SelectObject(&cbmp); BITMAP bmInfo; GetObject(cbmp, sizeof(BITMAP), (LPBYTE)&bmInfo); //得到图片尺寸 dc.StretchBlt(0,0,rect.width(),rect.height(),&mdc,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY); mdc.SelectObject(&hold); }
thinp 2014-02-28
  • 打赏
  • 举报
回复
OnEraseBkgnd 刷窗口了
智能牛蛙 2014-02-28
  • 打赏
  • 举报
回复
我把绘图代码写到OnEraseBkgnd(CDC* dc)里面了,如下: BOOL CdlgPlayerWnds::OnEraseBkgnd(CDC* dc) { if(1==m_lViewNumber) { RECT rect; GetParent()->GetClientRect(&rect); dc=GetDC(); CDC mdc; mdc.CreateCompatibleDC(dc); HBITMAP hold; CBitmap cbmp; cbmp.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP_NOVEDIO)); hold=(HBITMAP)mdc.SelectObject(&cbmp); BITMAP bmInfo; GetObject(cbmp, sizeof(BITMAP), (LPBYTE)&bmInfo); //得到图片尺寸 dc->StretchBlt(0,0,rect.right,rect.bottom,&mdc,0,0,bmInfo.bmWidth,bmInfo.bmHeight,SRCCOPY); mdc.SelectObject(&hold); mdc.DeleteDC(); CWnd::ReleaseDC(dc); DeleteObject(cbmp); } return TRUE; } 现在窗口不动的话背景图不闪烁了,但是拉伸窗口背景图还是闪烁啊...而且有其他窗口遮挡这窗口的时候,窗口上就会出现背景图,怎么让遮挡的时候不重绘呢?
worldy 2014-02-27
  • 打赏
  • 举报
回复
OnEraseBkgnd 返回 TRUE这个是防止闪烁的最关键的技术,使用两个memDC是无病呻吟的做法
Eleven 2014-02-27
  • 打赏
  • 举报
回复
你的GDI操作的最后需要SelectObject 旧的HBRUSH
「已注销」 2014-02-27
  • 打赏
  • 举报
回复 1
OnEraseBkgnd 返回 TRUE
智能牛蛙 2014-02-27
  • 打赏
  • 举报
回复
引用 1 楼 happyparrot 的回复:
你反复刷新会闪烁。解决办法: 将OnPaint中的绘图代码独立封装成一个函数,CDC作为参数。然后在OnPaint中调用这个函数。另外,在你所有需要刷新的地方,调用这个函数即可,不要用Invalidate之类的函数!
好我试试,不过我上面这段代码估计也有问题吧......
快乐鹦鹉 2014-02-27
  • 打赏
  • 举报
回复
你反复刷新会闪烁。解决办法: 将OnPaint中的绘图代码独立封装成一个函数,CDC作为参数。然后在OnPaint中调用这个函数。另外,在你所有需要刷新的地方,调用这个函数即可,不要用Invalidate之类的函数!

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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