C#自定义控件以及GDI测试

C#自定义控件

  1. 选择“解决方案”,右键-选择“添加”,选择“新建项目”,弹出对话框:

选择“窗体控件库”

 

  1. 新建的自定义控件,继承自那个控件,在新建的.cs文件中直接修改即可,如下如所示
  2. namespace SplitContainer_EX
    {
        public partial class My_SP_EX : SplitContainer
        {
            public My_SP_EX()
            {
                //控件自定义-双缓冲设置1
                this.SetStyle(
                  ControlStyles.UserPaint |
                  ControlStyles.AllPaintingInWmPaint |
                  ControlStyles.OptimizedDoubleBuffer, true);
    
                InitializeComponent();
            }
    
            protected override CreateParams CreateParams//控件自定义-双缓冲设置2
            {
                get
                {
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x02000000;
                    return cp;
                }
            }
        }
    }

     

  3. 编译一下软件,在bin->debug文件夹中会生成.dll文件
  4. 选择“工具箱”,右键选择“选择项”,在“.NET Framework组件”中添加刚才生成的.dll文件即可

测试代码

        private void Form1_Load(object sender, EventArgs e)
        {
            ScopeTimer = new System.Threading.Timer(new TimerCallback(Scope_TimerUpdateData_Elapsed), this, 0, 20);

            this.SetStyle(
                  ControlStyles.UserPaint |
                  ControlStyles.AllPaintingInWmPaint |
                  ControlStyles.OptimizedDoubleBuffer, true);
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
        void Scope_TimerUpdateData_Elapsed(object sender)//示波器采用的定时器用于更新显示或者发送测试数据的
        {
            
            Sin_test_Count++;

            int temppp = (int)(Math.Sin(Sin_test_Count * 6.2830 / 360) * userControl11.Panel1.Height / 3);//splitContainer1.Panel1  userControl11
            list.Add(temppp);
            if (Sin_test_Count >= 360)
            {
                Sin_test_Count = 0;
 
            }
            this.BeginInvoke(new Action(() =>
            {
                userControl11.Panel1.Invalidate(true);
                userControl11.Panel1.Update();
            }), null);
            
        }

        //void DrawScreen(Image* image)
        //{
        //    bitmap = (Bitmap*)image;                    //image转为bitmap
        //    bitmap->GetHBITMAP(Color(0, 0, 0), &hBitmap);  //获取bitmap对应GDI位图句柄

        //    CDC* cdc = GetDC();                          //创建目标dc
        //    HDC srchdc = CreateCompatibleDC(cdc->m_hDC); //创建源dc

        //    SelectObject(srchdc, hBitmap);               //将源位图句柄选入源dc

        //    BitBlt(cdc->m_hDC, 0, 0, CLIENT_WIDTH, CLIENT_HEIGHT, srchdc, 0, 0, SRCCOPY);//绘图

        //    DeleteObject(hBitmap);
        //    DeleteDC(srchdc);
        //    ReleaseDC(cdc);
        //}

        private void userControl11_Panel1_Paint(object sender, PaintEventArgs e)
        {
            DateTime t = DateTime.Now;

            Graphics g = e.Graphics;
            // Graphics g = this.CreateGraphics();
            Bitmap bmp = new Bitmap(userControl11.Panel1.Width, userControl11.Panel1.Height);
            Graphics bufg = Graphics.FromImage(bmp);
            //g.Clear(this.BackColor);//可用可不用,视具体情况
            //bufg.Clear(this.BackColor);//可用可不用
            //bufg.DrawLine(new Pen(Color.Black, 1), startP, endP);



            //Graphics  offScreenDC = Graphics.FromImage(bmp);

            //Graphics  ClientDC = e.Graphics;// this.CreateGraphics();

            //ClientDC.SetClip(new RectangleF(0, 0, 600, 600));

            //HDC hdc = ClientDC.GetHdc();

            //memdc = GDI.CreateCompatibleDC(hdc);

            //GDI.SelectObject(memdc, bitmap.GetHbitmap());

            //Graphics memDC = Graphics.FromHdc(memdc);

            if ((list.Count - 1) >= (userControl11.Panel1.Width))
            {
                list.RemoveRange(0, list.Count - userControl11.Panel1.Width - 1);
            }
            for (int i = 0; i < list.Count - 1; i++)//绘制
            {
                Point sp = new Point(i, userControl11.Panel1.Width / 6 + list[i]);
                Point ep = new Point((i + 1), userControl11.Panel1.Width / 6 + list[i + 1]);
                bufg.DrawLine(Pens.DarkGreen, sp, ep);
            }



            g.DrawImage(bmp, 0, 0);

            bufg.Dispose();
            bmp.Dispose();

            DateTime t2 = DateTime.Now;


            spppp = t2 - t;
            float per = 1000 / spppp.Milliseconds;

            this.label1.Text = "速度:" + per.ToString() + "帧/秒"; 

        }

测试在窗体中是否增加双缓冲设置1和双缓冲设置2,以及在自定义的控件中是否增加双缓冲设置1和双缓冲设置2,验证对绘图刷新的速度。

 

在窗体放入一个自定义的SplitContainer控件,利用一个定时器产生Panel1的Paint事件,在Paint中绘图,观察绘图刷新的情况;分为以下几种情况验证

  1. 在窗体中设置双缓冲设置1和双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:60-80帧/秒

 

 

  1. 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2观察绘图刷新情况;

 

是否闪烁:不闪烁

刷新速度:40-70帧/秒

 

  1. 在窗体中仅仅设置双缓冲设置1,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;

 

是否闪烁:不闪烁

刷新速度:40-70帧/秒

 

  1. 在窗体中仅仅设置双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;

 

 

是否闪烁:闪烁

刷新速度:60-70帧/秒

 

 

以上测试在自定义控件中增加双缓冲设置1和双缓冲设置2,只要不在窗体控件中增加双缓冲设置2就没有问题

 

  1. 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中不设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:20-30帧/秒

 

 

  1. 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中不设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:20-110帧/秒

 

  1. 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1,观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:20-110帧/秒

 

 

  1. 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:帧/秒

  1. 在窗体中仅仅设置双缓冲设置1,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:帧/秒

 

  1. 在窗体中仅仅设置双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:帧/秒

 

 

  1. 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2,观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:20-110帧/秒

 

 

  1. 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;

 

是否闪烁:不闪烁

刷新速度:50-80帧/秒

  1. 在窗体中仅仅设置双缓冲设置1,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;

 

是否闪烁:不闪烁

刷新速度:60-110帧/秒

 

  1. 在窗体中仅仅设置双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;

 

是否闪烁:闪烁

刷新速度:帧/秒

 

 

以上测试结论:

  不闪烁的必须条件:在自定义控件中必须含有双缓冲设置2,窗体控件中不能含有双缓冲设置2既可;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值