C# 完美解决窗体切换闪屏问题
2015-10-21 16:37
381 查看
1, 将以下代码块加在父窗体中的任意位置:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
原理很简单,引用以下原话:
A form that has a lot of controls takes
a long time to paint. Especially the Button control in its default style is expensive. Once you get over 50 controls, it starts getting noticeable. The Form class paints its background first and leaves "holes" where the controls need to go. Those holes
are usually white, black when you use the Opacity or TransparencyKey property. Then each control gets painted, filling in the holes. The visual effect is ugly and there's no ready solution for it in Windows Forms. Double-buffering can't solve it as it only
works for a single control, not a composite set of controls.
I discovered a new Windows style in the SDK header files, available for Windows XP and (presumably) Vista: WS_EX_COMPOSITED. With that
style turned on for your form, Windows XP does double-buffering on the form and all its child controls.
由于窗体上控件多,且有背景的情况下,控件设为背景设为透明,会导致窗体的刷新很慢很卡,从而窗体在闪烁,卡顿。
之前一直在网上搜寻解决的办法,试过了很多什么双缓冲啊之类的,发现效果并不大。
最后找到下面的方法可以解决了。但是奇怪的是,在有些电脑上运行时会发生窗体不刷新的问题。然后就参考下面的那个网址,最下面的答案。
http://stackoverflow.com/questions/5859826/datagridview-draws-wrong
个人总结一下,可能是系统版本的问题所导致的。网上有说是因为“xp特有的双缓冲绘图机制”。后来用上这个WS_EX_COMPOSITED(用双缓冲从下到上绘制窗口的所有子孙),再开启窗体的透明样式,问题都解决了。
只要把透明样式开启便可,所以我把透明度设置为100%,不想让窗体透明。
#defineWS_EX_COMPOSITED 0x02000000L
#endif/* _WIN32_WINNT >= 0x0501 */
准备把语言写的精炼一些,这样节省作者和读者的时间.
相关资料:这里不再摘录,请自行查看msdn
问题描述:在窗口使用了WS_EX_COMPOSITED 风格后,绘图就会变得不正常了,原因是xp特有的双缓冲绘图机制(可能后续版本Windows没有,参考WS_EX_COMPOSITED 风格的定义,在msdn里)的bug(应该算是一个系统的bug)
问题1:GetDC系绘图API不可用,表现为画出来的内容会被立即刷新掉,这个应该不算bug,
解决方法:
把所有的绘图操作放到WM_ERASEBKGND和WM_PAINT消息处理函数里,这个应该满足大多数情况下的要求,特殊情况可以使用加bool标志的方法在这两个函数里面绘图,然后在需要使用GetDC的地方设置bool标志
问题2:即使在上述的两个消息handler里面,GDI+绘图操作还是无法正常工作,而同一个消息处理函数里面的GDI函数就可以工作,这个问题msdn论坛上有人问过,也给出了解决方案,我试了一下果然ok,这个问题应该是GDI+函数内部的问题,具体原因不明
解决方法:
使用内存dc绘图.创建内存兼容dc,然后把这个内存兼容dc传给GDI+,绘图完成后,bitblt到原dc
至此,xp下的系统双缓冲窗口可以正常工作了,也使用GDI+来绘图了.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
原理很简单,引用以下原话:
A form that has a lot of controls takes
a long time to paint. Especially the Button control in its default style is expensive. Once you get over 50 controls, it starts getting noticeable. The Form class paints its background first and leaves "holes" where the controls need to go. Those holes
are usually white, black when you use the Opacity or TransparencyKey property. Then each control gets painted, filling in the holes. The visual effect is ugly and there's no ready solution for it in Windows Forms. Double-buffering can't solve it as it only
works for a single control, not a composite set of controls.
I discovered a new Windows style in the SDK header files, available for Windows XP and (presumably) Vista: WS_EX_COMPOSITED. With that
style turned on for your form, Windows XP does double-buffering on the form and all its child controls.
2, 防止窗口抖动以及窗体不刷新问题:
由于窗体上控件多,且有背景的情况下,控件设为背景设为透明,会导致窗体的刷新很慢很卡,从而窗体在闪烁,卡顿。之前一直在网上搜寻解决的办法,试过了很多什么双缓冲啊之类的,发现效果并不大。
最后找到下面的方法可以解决了。但是奇怪的是,在有些电脑上运行时会发生窗体不刷新的问题。然后就参考下面的那个网址,最下面的答案。
http://stackoverflow.com/questions/5859826/datagridview-draws-wrong
个人总结一下,可能是系统版本的问题所导致的。网上有说是因为“xp特有的双缓冲绘图机制”。后来用上这个WS_EX_COMPOSITED(用双缓冲从下到上绘制窗口的所有子孙),再开启窗体的透明样式,问题都解决了。
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED if (this.IsXpOr2003 == true) { cp.ExStyle |= 0x00080000; // Turn on WS_EX_LAYERED this.Opacity = 1; } return cp; } } //防止闪烁 private Boolean IsXpOr2003 { get { OperatingSystem os = Environment.OSVersion; Version vs = os.Version; if (os.Platform == PlatformID.Win32NT) if ((vs.Major == 5) && (vs.Minor != 0)) return true; else return false; else return false; } }
只要把透明样式开启便可,所以我把透明度设置为100%,不想让窗体透明。
3, XP下WS_EX_COMPOSITED问题总结:
#if(_WIN32_WINNT>=0x0501)#defineWS_EX_COMPOSITED 0x02000000L
#endif/* _WIN32_WINNT >= 0x0501 */
准备把语言写的精炼一些,这样节省作者和读者的时间.
相关资料:这里不再摘录,请自行查看msdn
问题描述:在窗口使用了WS_EX_COMPOSITED 风格后,绘图就会变得不正常了,原因是xp特有的双缓冲绘图机制(可能后续版本Windows没有,参考WS_EX_COMPOSITED 风格的定义,在msdn里)的bug(应该算是一个系统的bug)
问题1:GetDC系绘图API不可用,表现为画出来的内容会被立即刷新掉,这个应该不算bug,
解决方法:
把所有的绘图操作放到WM_ERASEBKGND和WM_PAINT消息处理函数里,这个应该满足大多数情况下的要求,特殊情况可以使用加bool标志的方法在这两个函数里面绘图,然后在需要使用GetDC的地方设置bool标志
问题2:即使在上述的两个消息handler里面,GDI+绘图操作还是无法正常工作,而同一个消息处理函数里面的GDI函数就可以工作,这个问题msdn论坛上有人问过,也给出了解决方案,我试了一下果然ok,这个问题应该是GDI+函数内部的问题,具体原因不明
解决方法:
使用内存dc绘图.创建内存兼容dc,然后把这个内存兼容dc传给GDI+,绘图完成后,bitblt到原dc
至此,xp下的系统双缓冲窗口可以正常工作了,也使用GDI+来绘图了.
相关文章推荐
- 关于C#对EXCEL的一些简单操作
- C#中Image类与byte[]之间的转换
- C#windows service C#windows 服务安装卸载SC
- Reshaper的使用
- Uninstall from GAC In C# code
- c#编写检测代理IP是否可用
- C# Window编程随记——多线程和线程池
- C# 控制左右声道
- C# .Net实现URL绝对路径和相对路径之间互相转换
- 【C#基础】反射
- C#指针操作Marshal实例
- C#批量替换文本文件内容的核心代码
- C#中DataTable中的Compute方法使用收集
- c# webapi POST 参数解决方法
- c# 判断点是否在区域内 点在区域内 在多边形内 判断
- 我们曾经心碎的C#之 第一章.我的第一个C#程序
- GDI+(C#)
- C#基础巩固(3)-Linq To XML 读取XML
- C#批量修改文件名的核心代码
- C# 加载图片image --(C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法