对话框拉左/上边改变大小时产生的画面的抖动问题

xjy1204 2011-03-22 02:15:39
碰到一个难以解决的问题,特来求教大家
对话框程序, 拉左边或者上边改变大小时(即不仅改变大小并且需要移动窗口)
现在跟踪调试得出的结论是, 系统会先移动窗口,并且会将屏幕上当前内容使用COPYBITS的模式复制过去
然后改变大小, 我的程序里会在OnSize时改变控件的位置
那么现在问题就出现了, 比如我有一个CStatic始终是要显示在窗口底部的
那么在迅速拉上边改变大小时, 效果就是控件显示内容会抖动(被先copy到上面的位置, 然后OnSize后重绘才回到最下面)

请问大家有没有办法能够避免这种抖动的效果?
我自己已经尝试了在OnWindowPosChanaged里判断并增加上SWP_NOCOPYBITS属性, 但是没有作用, 不知道是什么原因

分数不是问题, 完全可以另外开帖给分
希望有经验的兄弟来帮帮忙~非常感谢
...全文
259 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
davenky 2011-03-31
  • 打赏
  • 举报
回复
像看代码啊,只有原理,没有代码还是不会啊。笨笨……
no7mks 2011-03-25
  • 打赏
  • 举报
回复
CS_HREDRAW | CS_VREDRAW
M_S_D_N 2011-03-22
  • 打赏
  • 举报
回复
用dialog即使没有控件都会闪。

[Quote=引用 7 楼 cpp2017 的回复:]

用Dialog没问题的,另外最好加上WS_CLIPCHILDREN样式。
[/Quote]
M_S_D_N 2011-03-22
  • 打赏
  • 举报
回复
自己创建窗口类。

[Quote=引用 6 楼 xjy1204 的回复:]

引用 1 楼 m_s_d_n 的回复:

不用dialog即可,因为dialog带CS_SAVEBITS风格。


不用Dialog用什么呢?
如何去除CS_SAVEBITS风格?
[/Quote]
jackiesen 2011-03-22
  • 打赏
  • 举报
回复
应该是移动窗口刷新问题!
xjy1204 2011-03-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 m_s_d_n 的回复:]

不用dialog即可,因为dialog带CS_SAVEBITS风格。
[/Quote]

我又去查了下MSDN, 貌似CS_SAVEBITS没说和本身有关, 只是说本窗口移除后, 不会导致下面的窗口重绘, 会保留被遮盖的图像而已啊
xjy1204 2011-03-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cometnet 的回复:]

界面上窗口很多,而且改变大小时很多窗口都要移动和改变大小,如果使用MoveWindow或者SetWindowPos两个API来
改变窗口的大小和位置,由于他们是等待窗口重画完成后才返回,所以过程很慢,这样视觉效果就可能会闪烁。

解决方法:

使用以下API来处理窗口移动,BeginDeferWindowPos, DeferWindowPos,EndDeferWindowPos
……
[/Quote]
这些函数我知道, 但是我的问题现在不是控件移动的问题
我的控件现在都是使用SetWindowPos带SWP_NOCOPYBITS参数移动的
我的问题主要出现在Dialog在移动时会自动COPYBITS, 这才导致画面抖动的问题
看了一楼说的,我觉得问题可能就在CS_SAVEBITS上了

另外感谢大家捧场~~

PS: 我发现在Dialog设置了WS_CLIPCHILDREN时Edit控件使用SWP_NOCOPYBITS无效果, 非常奇怪,其他控件都是正常的..不得已我只有去除了WS_CLIPCHILDREN并且手动ClipChildren了
cpp2017 2011-03-22
  • 打赏
  • 举报
回复
用Dialog没问题的,另外最好加上WS_CLIPCHILDREN样式。
xjy1204 2011-03-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 m_s_d_n 的回复:]

不用dialog即可,因为dialog带CS_SAVEBITS风格。
[/Quote]

不用Dialog用什么呢?
如何去除CS_SAVEBITS风格?
看不见的裂痕 2011-03-22
  • 打赏
  • 举报
回复
赞下2楼的方法,当初俺用VC6.0实现VISIO的时候可是没这么好的API的.低版本的WINXP也是没这个效果的.不过这个方法确实是正解.减少屏幕重绘
邓学彬 2011-03-22
  • 打赏
  • 举报
回复
cpp2017 2011-03-22
  • 打赏
  • 举报
回复
方法有很多,像上的使用BeginDeferWindowPos这一组函数可以批量移动窗口,并且还有个参数
SWP_NOCOPYBITS
邓学彬 2011-03-22
  • 打赏
  • 举报
回复
界面上窗口很多,而且改变大小时很多窗口都要移动和改变大小,如果使用MoveWindow或者SetWindowPos两个API来
改变窗口的大小和位置,由于他们是等待窗口重画完成后才返回,所以过程很慢,这样视觉效果就可能会闪烁。

解决方法:

使用以下API来处理窗口移动,BeginDeferWindowPos, DeferWindowPos,EndDeferWindowPos
先调用 BeginDeferWindowPos 设定需要移动的窗口的个数
使用DeferWindowPos,来移动窗口,这个API并不真的造成窗口移动
EndDeferWindowPos 一次性完成所有窗口的大小和位置的改变。

有个地方要特别注意,要仔细计算清楚要移动多少个窗口,BeginDeferWindowPos设定
的个数一定要和实际的个数一致,否则在Win9x下,如果实际移动的窗口数多于调用BeginDeferWindowPos
时设定的个数,可能会造成系统崩溃。在Windows NT系列下不会有这样的问题。

M_S_D_N 2011-03-22
  • 打赏
  • 举报
回复
不用dialog即可,因为dialog带CS_SAVEBITS风格。

15,976

社区成员

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

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