欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#中使用CreateParams的ExStyle拓展双缓冲解决界面刷新缓慢与闪烁问题

程序员文章站 2022-06-10 10:49:29
...

ExStyle

1. 分析

在一个项目中对3000个控件实时上传3000个字节的数据改变控件属性, 在实测中遇到了界面刷新速度的问题.
界面刷新速度上限之一为winform中的控件本身的刷新机制(经过测试当控件数超过50个由这种情况产生的卡顿将变的明显)
但我们可以通过在父界面代码中重载CreateParams属性来设置界面减少闪烁加快绘制速度以优化界面显示

ExStyle是属于System.Windows.Forms.Control.CreateParams类的属性.

System.Windows.Forms是用于创建Windows应用程序的类, 使用WindowsOS的用户图形界面功能. 其中Control类用于定义控件的基类, 其中控件指定为带有可视化表示形式的组件. CreateParams获取创建控件句柄时所需要的创建参数。

根据资料, 则ExStyle是用于定义可视化组件的属性的属性, 可以通过指定ExStyle的属性来设置控件的拓展风格.

2.参数

本次所使用参数为: ExStyle |= 0x02000000; 意为ExStyle |= WS_EX_COMPOSITED, 所包含的意义为将一个窗体的所有子窗口使用双缓冲按照从低到高方式绘制出来.
所用代码: 将改代码放置在父界面即可重载父界面及其子界面的双缓冲机制

protected override CreateParams CreateParams
{
    get         //减少界面闪烁
    {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}
3. 双缓冲

双缓冲的原理:尽量快的输出图像,使输出在一个刷新周期内完成,如果输出内容很多比较慢,那么采用内存缓冲的方法,先把要输出的内容在内存准备好,然后一次性输出到窗体上,简单的说来就是在窗口刷新一次的过程中,让所有图元同时显示到窗口中。

对于图像编程来说窗口闪烁是个常见的问题,当窗口有大量的复杂的图元数据需要重绘,或者拥有自定义控件中的窗口闪烁问题更是显而易见的。出现闪烁的原因有很多种,大部分原因主要是因为触发WM_PAINT消息时窗体进行了重绘操作,此过程先是用窗体的背景色擦除窗口表面,再把窗体的图像绘制上去,但是如果这2个操作不在同一时间段完成的话,就会先看到背景色(大部分为白色)接着才看到图像,这样就会出现我们所说的窗体闪烁现象。

4.ExStyle其他参数
'窗口风格
Private Const WS_CAPTION = &HC00000     '带标题栏的窗口
Private Const WS_MAXIMIZEBOX = &H10000   '带最大化按钮的窗口
Private Const WS_MINIMIZEBOX = &H20000   '带最小化按钮的窗口
Private Const WS_SYSMENU = &H80000     '带系统菜单的窗口
Private Const WS_CLIPSIBLINGS = &H4000000  '不重绘层叠子窗口
Private Const WS_CLIPCHILDREN = &H2000000  '绘图时排子窗口区域
Private Const WS_OVERLAPPED = &H0&     '具有标题栏和边框的层叠窗口
Private Const WS_THICKFRAME = &H40000    '具有可调边框
'WS_OVERLAPPEDWINDOW具有标题栏、窗口菜单、可调边框和最大化、最小化按钮的窗口
Private Const WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)
Private Const WS_GROUP = &H20000      '指定一组控制的第一个控制
Private Const WS_POPUP = &H80000000     '弹出式窗口
Private Const WS_BORDER = &H800000     '单边框窗口
Private Const WS_POPUPWINDOW = (WS_POPUP Or WS_BORDER Or WS_SYSMENU) '具有单边框、标题栏菜单的弹出式窗口
Private Const WS_MINIMIZE = &H20000000   '窗口最小化
Private Const WS_VISIBLE = &H10000000    '窗口可见
Private Const WS_DISABLED = &H8000000    '窗口被禁用
Private Const WS_MAXIMIZE = &H1000000    '窗口最大化
Private Const WS_DLGFRAME = &H400000    '对话框边框风格
Private Const WS_VSCROLL = &H200000     '具有垂直滚动条
Private Const WS_HSCROLL = &H100000     '具有水平滚动条
Private Const WS_TABSTOP = &H10000     '具有TAB键控制
Private Const WS_CHILD = &H40000000
Private Const WS_CHILDWINDOW = (WS_CHILD)  '具有子窗口

'扩展风格
Private Const WS_EX_WINDOWEDGE = &H100&     '窗口具有凸起的3D边框
Private Const WS_EX_CLIENTEDGE = &H200&     '窗口具有阴影边界
Private Const WS_EX_TOOLWINDOW = &H80&     '小标题工具窗口
Private Const WS_EX_TOPMOST = &H8&       '窗口总在顶层
Private Const WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE) 'WS_EX-CLIENTEDGE和WS_EX_WINDOWEDGE的组合
Private Const WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST) 'WS_EX_WINDOWEDGE和WS_EX_TOOLWINDOW和WS_EX_TOPMOST的组合
Private Const WS_EX_DLGMODALFRAME = &H1&    '带双边的窗口
Private Const WS_EX_NOPARENTNOTIFY = &H4&    '窗口在创建和销毁时不向父窗口发送WM_PARENTNOTIFY消息
Private Const WS_EX_TRANSPARENT = &H20&     '窗口透眀
Private Const WS_EX_MDICHILD = &H40&      'MDI子窗口
Private Const WS_EX_CONTEXTHELP = &H400&    '标题栏包含问号联机帮助按钮
Private Const WS_EX_RIGHT = &H1000&       '窗口具有右对齐属性
Private Const WS_EX_RTLREADING = &H2000&    '窗口文本自右向左显示
Private Const WS_EX_LEFTSCROLLBAR = &H4000&   '标题栏在客户区的左边
Private Const WS_EX_CONTROLPARENT = &H10000   '允许用户使用Tab键在窗口的子窗口间搜索
Private Const WS_EX_STATICEDGE = &H20000    '为不接受用户输入的项创建一个三维边界风格
Private Const WS_EX_APPWINDOW = &H40000     '在任务栏上显示顶层窗口的标题按钮
Private Const WS_EX_LAYERED = &H80000      '窗口具有透眀属性(Win2000)以上
Private Const WS_EX_NOINHERITLAYOUT = &H100000 '窗口布局不传递给子窗口(Win2000)以上
Private Const WS_EX_LAYOUTRTL = &H400000    '水平起点在右边的窗口
Private Const WS_EX_NOACTIVATE = &H8000000   '窗口不会变成前台窗口(Win2000)以上
Private Const WS_EX_LEFT = &H0&         '窗口具有左对齐属性
Private Const WS_EX_LTRREADING = &H0&      '窗口文本自左向右显示
Private Const WS_EX_RIGHTSCROLLBAR = &H0&    '垂直滚动条在窗口的右边界
Private Const WS_EX_ACCEPTFILES = &H10&     '接受文件拖曳
Private Const WS_EX_COMPOSITED = &H2000000   '窗体所有子窗口使用双缓冲从低到高绘制