问题
using C#;
I'm trying to make an application using a Leap Motion sensor to map finger movements to cursor movement. On the screen, I would like to draw a circle around the cursor.
After some searching I found someone trying to do the same thing (Leap Motion excluded) Want a drawn circle to follow my mouse in C#. The code presented there:
private void drawCircle(int x, int y)
{
Pen skyBluePen = new Pen(Brushes.DeepSkyBlue);
Graphics graphics = CreateGraphics();
graphics.DrawEllipse(
skyBluePen, x - 150, y - 150, 300, 300);
graphics.Dispose();
this.Invalidate();
}
I Made some changed to make it work for my application:
private void drawCircle(int x, int y, int size)
{
Pen skyBluePen = new Pen(Brushes.DeepSkyBlue);
Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
graphics.DrawEllipse(
skyBluePen, x - size / 2, y - size / 2, size, size);
graphics.Dispose();
}
The reason I had to make some changes is because my application runs from the console and does not use forms. Meaning that I can't use the solutions presented in the other question.
The code above does draw circles , but they don't disappear as you can see in this image:
Something else to notice is that my application needs to runs even when it's console is not the active window (this works right now).
Now, I am very new to C# so it could be that the solution is very easy, but I can't find it.
So in short: I would like it to be such that only the last drawn circle is visible.
回答1:
Either you need a Panel, a Form or something that inherits from Control. Then you either override OnPaint or bind to the Paint Event.
Based the the answer from here: draw on screen without form
This works and you'll only see your circle on the screen, you cannot ALT + TAB out of it, since it's top most.
Also Events are going through, which means Windows is usable as allways.
One Exception to this is, it currently only uses the primary screen to display the circle.
If the Timer is too slow, you could call Invalidate();
after Drawing, but I'm not sure if that could be a performance issue.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
BackColor = Color.White;
FormBorderStyle = FormBorderStyle.None;
Bounds = Screen.PrimaryScreen.Bounds;
TopMost = true;
TransparencyKey = BackColor;
timer1.Tick += timer1_Tick;
}
Timer timer1 = new Timer() { Interval = 15, Enabled = true};
protected override void OnPaint(PaintEventArgs e)
{
DrawTest(e.Graphics);
base.OnPaint(e);
}
private void DrawTest(Graphics g)
{
var p = PointToClient(Cursor.Position);
g.DrawEllipse(Pens.DeepSkyBlue, p.X - 150, p.Y - 150, 300, 300);
}
private void timer1_Tick(object sender, EventArgs e)
{
Invalidate();
}
}
回答2:
i try to help you.... Maybe you can Use a timer to show the circle, and then, 1 sec, for example, hide it. Could be a solution?
回答3:
Every time you want to draw a circle:
- Restore the image a it was before the previous drawing,
- Save the rectangle where you will draw the circle,
- draw the circle.
This procedure saves the image of surrounding rectangle :
Bitmap saveBitmap = null ;
Rectangle saveRect ;
private void SaveCircleRect(Graphics graphics,int x, int y, int size)
{
saveBitmap = new Bitmap(2*size,2*size,graphics);
saveRect = new Rectangle(x-size/2, y-Size/2, Width, Height);
}
This procedure restores the screen image using saved rectangle :
private void RestoreCircleRect(Graphics graphics)
{
if (saveBitmap!=null) graphics.DrawImage(saveBitmap,saveRect);
}
However, you will face a lot of problems when the focused application will change or be resized/redrawn.
An alternative solution can be to display 4 thin topmost forms representing the 4 sides of a square and change their location when cursor moves.
来源:https://stackoverflow.com/questions/31610878/draw-a-circle-around-cursor-c