C# Winform窗体加背景闪烁优化的几种方式

1.窗体打开时防止窗体闪烁

        //C# 窗体程序,窗体上控件过多,会导致打开程序时窗体闪烁,下面有个不错的方法
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

2.禁掉清除背景消息

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0014) // 禁掉清除背景消息
                return;

            base.WndProc(ref m);
        }

3.设置双缓存

        public Form1()
        {
            

            InitializeComponent();

            //根据我的理解,每个窗体的这地方加上以下几行代码就行了
            this.DoubleBuffered = true;//设置本窗体
            //采用双缓冲技术的控件必需的设置
            //SetStyle(ControlStyles.UserPaint, true);
            //SetStyle(ControlStyles.ResizeRedraw, true);
            //SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
            //SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            //SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            //SetStyle(ControlStyles.EnableNotifyMessage, true);
            //SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            SetStyle(
                ControlStyles.UserPaint//使用自定义的绘制方式
                | ControlStyles.ResizeRedraw//当控件大小发生变化时就重新绘制
                | ControlStyles.DoubleBuffer// 双缓冲
                | ControlStyles.SupportsTransparentBackColor//则控件接受 alpha 组件数小于 255 个的 BackColor 来模拟透明度
                | ControlStyles.AllPaintingInWmPaint//禁止擦除背景.则控件忽略窗口消息 WM_ERASEBKGND 以减少闪烁
                | ControlStyles.EnableNotifyMessage// 
                // Enable the OnNotifyMessage event so we get a chance to filter out 
                // Windows messages before they get to the form's WndProc
                | ControlStyles.OptimizedDoubleBuffer//则控件将首先绘制到缓冲区而不是直接绘制到屏幕,这可以减少闪烁
                , true);


        }

4.界面重绘

        Image curChartImage;//为当前控件/窗体生成截图
        private void DrawRectBackImage(Control c, int xStart, int yStart, int Width, int Height)
        {

            Bitmap bit = new Bitmap(c.Width, c.Height);//实例化一个和窗体一样大的bitmap
            Graphics g = Graphics.FromImage(bit);
            g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高
            g.CopyFromScreen(this.Location.X +8+ c.Left, this.Location.Y+30 + c.Top, 0, 0, new Size(c.Width, c.Height));//保存整个窗体为图片

            curChartImage = bit;
        }

在内存中绘好图之后,绘图到界面

        int xStart = 150, yStart = 150, xWidth = 100, yHeight = 100;
        //虚拟时钟
        //在内存中保存图像,直接刷新到界面
        double num = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {

            if (curChartImage == null)
            {
                DrawRectBackImage(panel1, xStart, yStart, 2 * xWidth, 2 * yHeight);
            }
            if (panel1.Width == 0)
                return;
            Bitmap memoryCanvas = new Bitmap(panel1.Width, panel1.Height);
            double x = xStart + xWidth * Math.Sin(num * Math.PI / 180);
            double y = yStart - yHeight * Math.Cos(num * Math.PI / 180);

            tsmi_tip.Text = Convert.ToString((num = num + 0.3));

            Graphics memDc = Graphics.FromImage(memoryCanvas);
            memDc.SmoothingMode = SmoothingMode.HighQuality;
            memDc.DrawImage(curChartImage, 0, 0, panel1.Width, panel1.Height);

            Pen p1 = new Pen(Color.Black, 1);
            memDc.DrawLine(p1, (float)xStart, (float)yStart, (float)x, (float)y);

            Graphics g = panel1.CreateGraphics();
            g.DrawImage(memoryCanvas, xStart, yStart - 20, 2 * xWidth, 2 * yHeight);

            panel1.BackgroundImage = memoryCanvas;

            memDc.Dispose();

        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@David Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值