Как стереть рисовать прямоугольник на экране? - PullRequest
0 голосов
/ 26 сентября 2018

Я использую этот код для рисования прямоугольника, который будет перерисован снова через 500 мс в положении мыши.

Все хорошо, рисование прямоугольника работает отлично, но с этим кодом старые прямоугольники, которыеуже были нарисованы на экране, оставайтесь на экране навсегда, они не будут стерты.

Мне нужно стереть старые прямоугольники после создания нового.Новый прямоугольник сделан с помощью цикла while.

int i = 0;
while (i != 1)
{
    int x = Cursor.Position.X;
    int y = Cursor.Position.Y;
    Graphics g = Graphics.FromHwnd(IntPtr.Zero);
    Rectangle mouseNewRect = new Rectangle(new Point(x, y), new Size(30, 30));
    g.DrawRectangle(new Pen(Brushes.Chocolate), mouseNewRect);
    Wait(500);
}

РЕДАКТИРОВАТЬ: мне нужно стереть прямоугольники, которые находятся как внутри, так и за пределами формы.Идеи?

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Вы можете вызвать метод Invalidate(), который будет запрашивать перерисовку региона, повторно вызвав метод рисования.

См. Control.Invalidate () в MSDN

В вашем сценарии что-то вроде этого?

int i = 0;
while (i != 1)
{
    int x = Cursor.Position.X;
    int y = Cursor.Position.Y;
    Graphics g = Graphics.FromHwnd(IntPtr.Zero);
    Rectangle mouseNewRect = new Rectangle(new Point(x, y), new Size(30, 30));
    g.DrawRectangle(new Pen(Brushes.Chocolate), mouseNewRect);
    Wait(500);
    Invalidate();
}

Что касается обновления всего экрана, вы можете использовать этот p / invoke.https://www.pinvoke.net/default.aspx/user32.invalidaterect

[DllImport("user32.dll")]
static extern bool InvalidateRect(IntPtr hWnd, RECT lpRect, bool bErase);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
   public int Left, Top, Right, Bottom;

   public RECT(int left, int top, int right, int bottom)
   {
     Left = left;
     Top = top;
     Right = right;
     Bottom = bottom;
   }

   public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }

   public int X
   {
     get { return Left; }
     set { Right -= (Left - value); Left = value; }
   }

   public int Y
   {
     get { return Top; }
     set { Bottom -= (Top - value); Top = value; }
   }

   public int Height
   {
     get { return Bottom - Top; }
     set { Bottom = value + Top; }
   }

   public int Width
   {
     get { return Right - Left; }
     set { Right = value + Left; }
   }

   public System.Drawing.Point Location
   {
     get { return new System.Drawing.Point(Left, Top); }
     set { X = value.X; Y = value.Y; }
   }

   public System.Drawing.Size Size
   {
     get { return new System.Drawing.Size(Width, Height); }
     set { Width = value.Width; Height = value.Height; }
   }

   public static implicit operator System.Drawing.Rectangle(RECT r)
   {
     return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
   }

   public static implicit operator RECT(System.Drawing.Rectangle r)
   {
     return new RECT(r);
   }

   public static bool operator ==(RECT r1, RECT r2)
   {
     return r1.Equals(r2);
   }

   public static bool operator !=(RECT r1, RECT r2)
   {
     return !r1.Equals(r2);
   }

   public bool Equals(RECT r)
   {
     return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
   }

   public override bool Equals(object obj)
   {
     if (obj is RECT)
       return Equals((RECT)obj);
     else if (obj is System.Drawing.Rectangle)
       return Equals(new RECT((System.Drawing.Rectangle)obj));
     return false;
   }

   public override int GetHashCode()
   {
     return ((System.Drawing.Rectangle)this).GetHashCode();
   }

   public override string ToString()
   {
     return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
   }
}

Затем используйте его, вызвав

InvalidateRect(IntPtr.Zero, null, true);

Передав значение NULL и true в качестве второго и третьего параметра, вы должны перерисовать весь экран.

0 голосов
/ 27 сентября 2018

Решение, опубликованное @Emcrank, работает.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Load += async delegate
        {
            var g = Graphics.FromHwnd(IntPtr.Zero);
            var mouseNewRect = new Rectangle(Point.Empty, new Size(30, 30));
            var pen = new Pen(Brushes.Chocolate);
            while (true)
            {
                mouseNewRect.Location = Cursor.Position;
                g.DrawRectangle(pen, mouseNewRect);
                await Task.Delay(500);
                InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
            }
        };
    }

    [DllImport("user32.dll")]
    static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
}

В любом случае, если вы хотите нарисовать положение мыши внутри формы, есть гораздо лучшее решение.

public partial class Form1 : Form
{
    private Rectangle _rect = new Rectangle(0, 0, 30, 30);
    private readonly Pen _pen = new Pen(Brushes.Chocolate);
    public Form1()
    {
        InitializeComponent();
        SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        _rect.Location = e.Location;
        Invalidate(ClientRectangle);
        base.OnMouseMove(e);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        //--improve graphics quality
        var g = e.Graphics;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.SmoothingMode = SmoothingMode.AntiAlias;

        _rect.Offset(-15, -15); //--center rect

        e.Graphics.DrawRectangle(_pen, _rect);

        base.OnPaint(e);
    }
}

Надеюсь, это поможет.

0 голосов
/ 26 сентября 2018

Вам нужно заставить окно, в которое вы рисуете, перерисовывать себя между вашими итерациями.Альтернативное решение - захватить окно с изображением в памяти;нарисуйте прямоугольник на копии этого изображения, затем нарисуйте изображение в окне.Повторяя этот процесс каждый раз, чтобы в целевом окне не было артефактов от предыдущих итераций.

...