8

It is very easy to get the position of cursor out side the form's boundary by just dragaging the mouse it sends many values to the form when ever the position changes, form the following line of code.

MessageBox.Show(Cursor.Position.ToString());

MessageBox showing mouse position.

But I need to get the mouse position when user clicked out side the forms boundary. Not by just hovering the mouse. I used the following line of Code to do this:

private void Form1_Deactivate(object sender, EventArgs e)
{
    MessageBox.Show(Cursor.Position.ToString());
}

I placed MessageBox.Show(Cursor.Position.ToString()); into forms Deactivate event. When user click outside the form this event definitely occures. But it also sends wrong values when user does not click outside but changes the program by using ALT + TAB key combination.

Actually I have to capture screen shot of the area starting from the position of first click. Therefore I need the position of the cursor when it is clicked outside the form. like: enter image description here

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Farid-ur-Rahman
  • 1,809
  • 9
  • 31
  • 47

5 Answers5

12

This might help some one.

Here I am using Windows.Forms.Timer and two text boxes for displaying [X and Y] cursor positions. On timer tick calling the API GetCursorPos and getting the cursor position.

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    static extern bool GetCursorPos(ref Point lpPoint);

    public Form1()
    {
        InitializeComponent();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        var pt = new Point();

        GetCursorPos(ref pt);
        textBox1.Text = pt.X.ToString();
        textBox2.Text = pt.Y.ToString();
    }   
}

Regards, Ranjeet.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Ranjeet
  • 141
  • 1
  • 3
8

You should use Global Mouse Hook logic to do this.

Here is a good article that will help you: Processing Global Mouse and Keyboard Hooks in C#

HABJAN
  • 9,212
  • 3
  • 35
  • 59
1

The solution to this problem is simple. All what you need is a System.Windows.Forms.Timer, and use System.Runtime.InteropService.DllImport to extern the method GetKeyState from user32.dll.

This function has one parameter of any type of integer, and it returns short (Int16). This function can tell you if some keys were pressed or not at every moment and everywhere, not depending on the form. While the Timer is Enabled, you can check if the mouse position is out of the form bounds. There are many ways to get the mouse position.

One way is Cursor.Position, or Control.MousePosition, or you can use the bool GetCursorPos(ref Point lpPoint), an extern method, that you can DllImport it from "user32.dll". form.Bounds or form.ClientRectangle, or form.Location and form.Size or form.Left and form.Top and form.Width and form.Height, all these bring you the form bounds. In the timer_Tick function event, you write the following code for example:

var mp = Cursor.Position;
var fb = form.ClientRectangle; // Or form.Bounds

if (mp.X < fb.X || mp.Y < fb.Y || mp.X > fb.X + fb.Width || mp.Y > fb.Y + fb.Height)
{
    // Use GetKeyState from user32.dll to detect if at least 1 key is pressed
    // (look at internet how to do it exactly)
    // If yes MessageBox.Show("Clicked outside");
}

If at least 1 key was pressed, and then Show your message with the MessageBox. You can read on the Internet how to do all these stuff I was talking about before, and if you succeed, it will work!

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
1

Try this:

// Form1.cs

private Point pos1;
private Point pos2;

private bool b = true;
private double diffx;
private double diffy;
private double area;

private void Form1_Deactivate(object sender, EventArgs e)
{
    if (b) (pos1, b) = (Cursor.Position, false);
    else
    { 
        pos2 = Cursor.Position;

        if (pos1.x >= pos2.x) diffx = pos1.x - pos2.x;
        else diffx = pos2.x - pos1.x;

        if (pos1.y >= pos2.y) diffy = pos1.y - pos2.y;
        else diffy = pos2.y - pos1.y;

        area = diffx * diffy;

        MessageBox.Show(area.ToString());
    }
}

But you will have to click on the program again after clicking outside it in the start point and then click outside it in the end point to make the program work

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
kyay10
  • 855
  • 8
  • 16
  • 1
    Can you name the variable something better than `b`? Like goodness, I have no idea what it does exactly – AustinWBryan Apr 04 '20 at 23:34
  • @AustinWBryan Oh my God, my code is horrible lol. I wrote this like 5 years ago, and honestly it's terrible. I can't really remember how it worked, but I think b is a Boolean that holds whether or not the program has already got a Cursor position for pos1. This can definitely be changed to initializing pos1 to negative x and y values, then checking whether pos1 is negative in that if statement, and finally assigning pos1 to negative x and y values again at the end of the else branch. I'm gonna make an edit to the answer ASAP. Thanks btw for trying to make my horrendous code better. – kyay10 Apr 14 '20 at 06:59
0

Deactivate event notifies your form that it's not active any more. It could happen because of many reasons.

Usually a Window gets mouse events only when mouse is over this window. SetCapture function lets you grab all mouse events (I don't know .NET counterpart). Because only one window can capture mouse events, you should not capture mouse events when there's no need for it. The question does not have enough details on what you really want to do and why you need to know when user clicked outside your form.

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68