2

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:

enter image description here 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.

Community
  • 1
  • 1
TijsDelvaux
  • 43
  • 1
  • 4
  • 2
    You need to create your own borderless transparent window, splattering pixels to the desktop isn't going to work. A low-level mouse hook to move the window when the cursor moves and to animate clicks. Not a "very new to C#" kind of project, leave it on the shelf. – Hans Passant Jul 24 '15 at 13:53

3 Answers3

2

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();
    }
}
Community
  • 1
  • 1
Andre
  • 1,228
  • 11
  • 24
  • So far I tried the Method 1 in your suggested link, but that gives me the same result. The problem is that once a circle is drawn, I need the previous one to disappear. And I can't seem to find a way to do that. – TijsDelvaux Jul 24 '15 at 13:52
  • Please have a look to my edit, in this way you'll need a form, but it is transparent, so that could help. – Andre Jul 24 '15 at 13:53
  • I haven't looked into Method 2 that deep yet, but I still need to be able to click (actually use Windows normally). Am I right to say that that won't be possible in the borderless form approach? – TijsDelvaux Jul 24 '15 at 13:54
  • Events are going through actually, so it is possible to use Windows normally. – Andre Jul 24 '15 at 13:55
  • Finally got around to try it. Does pretty much exactly what I need. Thank you very much! – TijsDelvaux Jul 27 '15 at 11:49
0

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?

ibis48
  • 11
  • 4
0

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.

Graffito
  • 1,658
  • 1
  • 11
  • 10