2

I am getting X and Y coordinates from an external controller through its own SDK.

So, I want to transform this coordinates in an circle translucent and simulate a mouse cursor.

I have the following code, but I only get draw translucent circles, and I cannot "erase" previous circles.

I would like draw translucent circles and erase them when I draw the next circle. I should draw some kind of transition between a coordinates and the following coordinates for simulating "movement". Another issues I have found, I cannot draw circle over standard components as buttons, text box, etc…

//...
System.Drawing.Graphics g = this.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

System.Drawing.Color translucentYellow = System.Drawing.Color.FromArgb(128, Color.Yellow);
System.Drawing.SolidBrush aBrush = new System.Drawing.SolidBrush(translucenYellow);

g.CompositingQuality = system.Drawing.Drawing2D.CompositingQuality.GammaCorrected;

g.FillEllipse(aBrush, X, Y, width, height);
//.….
leppie
  • 115,091
  • 17
  • 196
  • 297
mzurita
  • 690
  • 1
  • 14
  • 33
  • 1
    Maybe it would be easier to change the actual mouse cursor to show that image? As for the other question: Whatever you draw should be drawn in or triggered from the Paint event; that will take care of the 'old' paixels. But drawing on the Form will not draw on the Controls.. So, back to my first advice.. – TaW Oct 08 '14 at 10:10
  • @TaW So, you recommend to me to move the cursor to this coordinate and change its appearance, isn't? – mzurita Oct 08 '14 at 10:24
  • 2
    Well, it really depends on your use case. Should it still act as a cursor or is it only moved externally? In the latter case go for usr's answer: Move a Panel on top of the Form or possible another Form..! – TaW Oct 08 '14 at 10:26
  • Really, these coordinates are gotten from a gaze controller, and the idea is to replace mouse cursor with the gaze, so, this should act as a cursor. – mzurita Oct 08 '14 at 10:30
  • 1
    In that case I guess I would set the cursor to an icon and move it by code.. – TaW Oct 08 '14 at 10:33

2 Answers2

1

Draw a static ellipse to a simple control such as a Panel. Move that panel over the screen. That way you can control overlapping other windows and controls. You also don't have to redraw the ellipse all the time.

If you want to overlap other windows or applications you need to draw this ellipse into a Form with TopMost = true. You can remove the borders from the form.

You can set transparency for a Form as well.

usr
  • 168,620
  • 35
  • 240
  • 369
1

Don't paint a cursor, when the system does it so much better for you.

Ideally all you'd need to do is:

Cursor = new Cursor("D:\\circle1.cur");

Unfortunately this will not work with many versions of cur files. To be precise anything over 32x32 pixels and with colors.

So you will want to use a more flexible routine, which I found on this post, see below..!

Use it like this

Cursor = CreateCursorNoResize(bmp, 16, 16);

And set the cursor position like this:

Cursor.Position = new Point(yourX, yourY);

whenever the controller comes up with a change..

Here is the ever so slightly modified routine:

using System.Runtime.InteropServices;
// ..

public struct IconInfo
{
    public bool fIcon;
    public int xHotspot;
    public int yHotspot;
    public IntPtr hbmMask;
    public IntPtr hbmColor;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);

public static Cursor CreateCursorNoResize(Bitmap bmp, int xHotSpot, int yHotSpot)
{
    IntPtr ptr = bmp.GetHicon();
    IconInfo tmp = new IconInfo();
    GetIconInfo(ptr, ref tmp);
    tmp.xHotspot = xHotSpot;
    tmp.yHotspot = yHotSpot;
    tmp.fIcon = false;
    ptr = CreateIconIndirect(ref tmp);
    return new Cursor(ptr);
}

Notes:

  • The full code has a bit more options
  • The cursor will turn to a diferent one over controls that have their own Cursors, like textboxes..

Cursor found on rw-designer:

A_Circle

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
  • `Cursor = new Cursor("…");` is not working this time(invalid image). So I want to try with the second option, but I don't know where I have to put the code… outside of my form? In the same namespace? Thanks in advance. – mzurita Oct 08 '14 at 11:57
  • 1
    Anywhere in the form. The using clause at the top, with the others, the rest with your functions, I'd say.. To clrify: The included Cursor is not a cursor but a png file and as such is not supposed to work with the Cursor's constructor. I have saved the original .cur file from that link in Greenfish Icon editor (recommend) as png.. – TaW Oct 08 '14 at 12:44
  • Doesn't this mean that the user can't use the mouse while the animation is in progress? – usr Oct 08 '14 at 13:28
  • The mouse can be __used__, but if both try to move it at the same time, yes, that will be a conflict; which is why I asked about it in my first comment.. How often will the updates happen? And how often will the user intervene? If one event is rare one could try to protect the user movement from the controll's intervention with a timer.. – TaW Oct 08 '14 at 13:30
  • @TaW I downloaded original .cur file from the link you posted, so I previously need to convert this .cur file into a bitmap object `Cursor = CreateCursorNoResize(bmp, 16, 16);`, but it throws an ArgumentException, "This is a not valid parameter" from `Bitmap bmp = new Bitmap("V:\\Circle.cur");`(The location of the file is right). What can I do? Thanks in advance. – mzurita Oct 08 '14 at 15:39
  • 1
    You need to convert it to a png file. many tools to do so. I used the free Greenfish Icon editor.. – TaW Oct 08 '14 at 15:46
  • Yeah! Using .cur file didn't work for me, but with .ico or .png it does. Thank you very much! – mzurita Oct 09 '14 at 09:34