views:

242

answers:

1

How to highlight the system cursor? Like many screen recording applications do. Ideally, I'd like to display a halo around it. Thanks

+1  A: 

For a purely managed solution, the following code will draw an ellipse on the desktop at the current mouse cursor position.

Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates

using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{        
  g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20);
}

By using a timer you can update the mouse position every 20ms for example and draw the new hallow (ellipse).

There are other more efficient ways that I can think of, but they would require unamanged code using system hooks. Take a look at SetWindowsHookEx for more info on this.

Update: Here is a sample of the solution I described in my comments, this is just rough and ready for testing purposes.

  public partial class Form1 : Form
  {
    private HalloForm _hallo;
    private Timer _timer;

    public Form1()
    {
      InitializeComponent();
      _hallo = new HalloForm();
      _timer = new Timer() { Interval = 20, Enabled = true };
      _timer.Tick += new EventHandler(Timer_Tick);
    }

    void Timer_Tick(object sender, EventArgs e)
    {
      Point pt = Cursor.Position;
      pt.Offset(-(_hallo.Width / 2), -(_hallo.Height / 2));
      _hallo.Location = pt;

      if (!_hallo.Visible)
      {
        _hallo.Show();
      }
    }    
  }

  public class HalloForm : Form
  {        
    public HalloForm()
    {
      TopMost = true;
      ShowInTaskbar = false;
      FormBorderStyle = FormBorderStyle.None;
      BackColor = Color.LightGreen;
      TransparencyKey = Color.LightGreen;
      Width = 100;
      Height = 100;

      Paint += new PaintEventHandler(HalloForm_Paint);
    }

    void HalloForm_Paint(object sender, PaintEventArgs e)
    {      
      e.Graphics.DrawEllipse(Pens.Black, (Width - 25) / 2, (Height - 25) / 2, 25, 25);
    }
  }
Chris Taylor
Thanks Chris, I've managed to draw a semi-transparent halo using hooks and Graphics.FromHwnd. However, I'm having trouble erasing the previously painted circle. InvalidateRect doesn't seem to work correctly with IntPtr.Zero or GetDesktopWindow. Any ideas?
Sphynx
Hi John, so I was thinking about your problem of restoring the desktop and I had the following idea. Instead of drawing directly on the desktop as I initially suggested, why now use a form. So create a new Form, Hallow Form, set the FormBorderStyle=None, BackColor=LightGreen, TransparencyKey=LightGreen, TopMost=true, ShowInTaskBar=false, Width=100, Height=100. This gives you a Form that does not display, but anything you draw on the form in the PaintEvent will show. Then in the timer event from the initial answer update the window position to track the mouse. From a quick test it looked fine.
Chris Taylor
Only obvious problem I can think of is that another window might be top most after your window in which case this hallow would not show over that window.
Chris Taylor