• GDI+ 绘制经验


      现有一种场景,鼠标移动时,假设鼠标坐标为 X , Y , 需实时在 坐标 (X , 0) , (0 , Y) 两处更新内容。

    方案一:
    增加两个label ,或其它控件,鼠标移动时,实时更新 label 坐标区域 , 及内容。

    MouseMove 事件代码:

    lblX.Location = new Point(e.X, 0);
    lblY.Location = new Point(0, e.Y);
    lblX.Text = e.X.ToString();
    lblY.Text = e.Y.ToString();

    经过检单测式,鼠标移动时,CPU 升到 10 %  - 50% 。

    方案二:

    GDI Drawing 绘制相关信息.

    MouseMove 事件代码 , 记录鼠标位置

    //记录当前绘制坐标
    curPoint = e.Location;
    //重绘区包括当前需绘制区域,和需擦除区域 ,使用自身合并函数
    
    if (isFirst)
    {
        isFirst = false;
    }
    
    //当前绘制区
    Rectangle cur = new Rectangle(0, 0, curPoint.X + 50, curPoint.Y + 25);
    
    if (isFirst)
    {
        isFirst = false;
    }
    else
    {
        //将上一次更新区域添加到更新列表
        pictureBox1.Invalidate(lstRec);
    }
    
    //更新绘制区域
    pictureBox1.Invalidate(cur);
    
    lstRec = cur;

    Paint 重绘代码

    e.Graphics.DrawString(curPoint.X.ToString(), font, brush, curPoint.X, 0);
    e.Graphics.DrawString(curPoint.Y.ToString(), font, brush, 0, curPoint.Y);
    Console.WriteLine("{0} , height:{1}", e.ClipRectangle.Width, e.ClipRectangle.Height);


    经过简单测式,鼠标移动时,CPU 升到 10 %  - 40% 。
    由于重绘区域随着X, Y 值增大而增加,Invalidate方法会将重绘区域合并新矩形, 虽然更新很小部份,但重绘面积仍很大。后期,经过优化,重绘面积可不超过全屏四分之一。但CPU 占用仍然很高。

    方案三:
    采用 gdi32 绘制 , gdi32因绘制区域无合并,重绘机制存在,在局部更新时 默认只更新修改部份。CPU 占用2% - 5%

    MouseMove 事件代码:

    if (isFirst)
    {
        isFirst = false;
    }
    else { 
        //擦除背景色 , 区域描述参数为 左,上,右,下。
        GDIDrawText.FillRgn(hdc, GDIDrawText.CreateRectRgn(rectX.Left, rectX.Top, rectX.Right, rectX.Bottom), brushWin32);
        GDIDrawText.FillRgn(hdc, GDIDrawText.CreateRectRgn(rectY.Left, rectY.Top, rectY.Right, rectY.Bottom), brushWin32);
    }
    
    GDIDrawString(rectX = new Rectangle(e.X, 0, 50, 20), e.X.ToString());
    GDIDrawString(rectY = new Rectangle(0, e.Y , 50, 20), e.Y.ToString());

    绘制方法

    private void GDIDrawString(Rectangle rec , string value) {
        int flags = GDIDrawText.DT_CENTER | GDIDrawText.DT_VCENTER | GDIDrawText.DT_SINGLELINE;
        Rect bounds = new Rect(rec);
        GDIDrawText.DrawText(hdc, value , value.Length, ref bounds, flags);
    }
  • 相关阅读:
    C#中double转int时需要注意的地方
    OracleHelper类
    POJ2570, ZOJ1967
    ZOJ3088
    POJ3259(spfa判负环)
    POJ3268
    ZOJ1092 POJ2240
    ZOJ1298 POJ1135
    SRM587 div2
    POJ1679判断最小生成树是否唯一
  • 原文地址:https://www.cnblogs.com/a_bu/p/5563924.html
Copyright © 2020-2023  润新知