关于ExcludeClipRect函数的一点疑惑

Ryanwen 2009-12-22 12:09:01
描述: 一个基于对话框的程序,主窗口上有数十个按钮控件,现在想美化一下主窗口,在主窗口画一幅背景图片,为了防止界面闪烁,画之前先剪裁掉按钮控件的区域,再双缓冲绘图。

现在的问题是,当窗口被其他窗口遮挡后,按钮区域会先变成灰白色,再变为原来的样子,这个过程明显能看出来,当用一个窗口频繁的在主窗口上移动时更明显,但是用FillRect填充背景则不会有这个问题,难道BitBlt函数忽略ExcludeClipRect函数剪裁的区域?



OnInitDialog: 修改窗口属性
ModifyStyle(0, WS_CLIPCHILDREN|WS_CLIPSIBLINGS);

OnEraseBkgnd: 画背景
if(m_hWnd)
{
for(CWnd* pChild = GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
{//剪裁所有子窗口
if(!pChild->IsWindowVisible()) continue;

CRect r;
pChild->GetWindowRect(&r);
ScreenToClient(&r);
pDC->ExcludeClipRect(&r);
}

//用这段注释掉的代码就没有问题
//CRect rcClient;
//GetClientRect(&rcClient);
//CBrush brush(RGB(0,0,0));
//pDC->FillRect(&rcClient, &brush);

CRect rcClient;
GetClientRect(&rcClient);

//Prepare drawing
CBitmap *pOldBitmap;
CBitmap bitmap;
CDC memDC;
memDC.CreateCompatibleDC(pDC);

//画背景
bitmap.LoadBitmap(IDB_MAIN);
pOldBitmap = (CBitmap*)memDC.SelectObject(&bitmap);

pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, MERGECOPY);

memDC.SelectObject(pOldBitmap);
bitmap.DeleteObject();
memDC.DeleteDC();
}

return TRUE;

...全文
860 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jccdream 2010-07-05
  • 打赏
  • 举报
回复
我要看看
sandyandy 2009-12-22
  • 打赏
  • 举报
回复
bitblt 一贴, 应该就是整张位图, 不会裁剪其他区域
cnzdgs 2009-12-22
  • 打赏
  • 举报
回复
要验证裁剪是否对BitBlt是否有效也不难,你在空白窗口上随便裁剪掉一块,然后拿其它窗口来覆盖再移开就看出来。
另外再重复提一下,窗口设置了WS_CLIPCHILDREN风格就不需要自己对控件区域做裁剪了。
Ryanwen 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 nintendo_dskay 的回复:]
应该不会的,我之前也试过用ExcludeClipRect来排除部分不绘制区域,完全不会出现楼主所说的情况。
一般来说,只要控件是主窗口的子窗口,用ClipChildren就可以达到楼主的目的了。Edit控件除外。
[/Quote]

我开了空白工程试了下,即使剪裁了区域,好像BitBlt更新的时候还是直接整个窗口覆盖了

工程控件除了按钮外都是嵌套的,一般都有2到3层的嵌套
Ryanwen 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cnzdgs 的回复:]
闪烁的原因就是绘制时间太长。
[/Quote]
谢谢你的回复。

这个问题确实存在,因为是一个工程控制软件,窗口内控件比较多,且所有控件都是自绘的,我将图片导入部分修改了一下,速度确实快了不少,但还是能感觉有一些闪烁,尤其是开启实时更新窗口的函数后,看来还得继续在处理速度上找原因。

原来考虑采用DirectUI方式直接在窗口贴图,但是逻辑处理比较繁琐
nintendo_dskay 2009-12-22
  • 打赏
  • 举报
回复
应该不会的,我之前也试过用ExcludeClipRect来排除部分不绘制区域,完全不会出现楼主所说的情况。
一般来说,只要控件是主窗口的子窗口,用ClipChildren就可以达到楼主的目的了。Edit控件除外。
cnzdgs 2009-12-22
  • 打赏
  • 举报
回复
闪烁的原因就是绘制时间太长。
Ryanwen 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cnzdgs 的回复:]
代码效率比较低。
在对话框类中定义一个CBitmap对象,初始化时LoadBitmap。在OnEraseBkgnd中创建内存DC然后贴图即可。窗口甚至了WS_CLIPCHILDREN风格就不需要再裁剪了。
[/Quote]

每次导入图片效率确实不好,这个只是个测试程序,现在的疑惑是在绘制背景的时候如何不绘制剪裁区域,BitBlt函数好像直接把整个窗口给填充了,子窗口再自己更新窗口,这样就造成了闪烁
cnzdgs 2009-12-22
  • 打赏
  • 举报
回复
代码效率比较低。
在对话框类中定义一个CBitmap对象,初始化时LoadBitmap。在OnEraseBkgnd中创建内存DC然后贴图即可。窗口甚至了WS_CLIPCHILDREN风格就不需要再裁剪了。

15,980

社区成员

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

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