在窗体边界处单击时获取鼠标光标的位置

时间:2011-04-03 08:39:34

标签: c# mouse-position

通过拖动鼠标可以很容易地将光标的位置放在窗体的边界之外,当位置发生变化时,它会向窗体发送许多值,形成下面的代码行。

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

MessageBox showing mouse position.

但是当用户点击表单边界时,我需要获取鼠标位置。 不仅仅是悬停鼠标。我使用以下代码行来执行此操作:

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

我将 MessageBox.Show(Cursor.Position.ToString()); 放入表单Deactivate事件中。当用户在表单外单击时,此事件肯定会发生。但是当用户没有点击外部但是使用 ALT + TAB 组合键更改程序时,它也会发送错误的值。 实际上我必须从第一次点击的位置开始捕捉该区域的屏幕截图。因此,当在表单外部单击时,我需要光标的位置。 喜欢: enter image description here

5 个答案:

答案 0 :(得分:8)

您应该使用Global Mouse Hook逻辑来执行此操作。

以下是一篇很有帮助的文章:Processing Global Mouse and Keyboard Hooks in C#

答案 1 :(得分:4)

这可能对某人有所帮助。 这里我使用Windows.Forms.Timer和两个文本框来显示[X和Y]光标位置。在计时器上调用API GetCursorPos并获取光标位置。

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)
    {
         Point pt = new Point();
        GetCursorPos(ref pt);
        textBox1.Text = pt.X.ToString();
        textBox2.Text = pt.Y.ToString();
    }


}

此致 兰吉特。

答案 2 :(得分:2)

这个问题的解决方案很简单。所有你需要的是一个System.Windows.Forms.Timer,并使用System.Runtime.InteropService中的DllImport来从user32.dll中取出方法GetKeyState。此函数具有任何类型整数的一个参数,并返回short(Int16)。此功能可以告诉您是否在每个时刻和任何地方按下了某些键,而不是取决于表单。当Timer启用时,您可以检查鼠标位置是否超出表单范围。有很多方法可以获得鼠标位置。一种方法是Cursor.Position,或Control.MousePosition,或者你可以使用bool GetCursorPos(ref Point lpPoint),一个extern方法,你可以从“user32.dll”DllImport它。 form.Bounds或form.ClientRectangle,或form.Location和form.Size或form.Left和form.Top和form.Width and form.Height,所有这些都为您带来了表单边界。在timer_Tick函数事件中,您编写以下代码,例如: {

   Point mp = Cursor.Position;
   Rectangle 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");
   }

} 如果按下至少1个键,然后使用MessageBox显示您的消息。你可以在互联网上阅读如何做我之前谈论的所有这些事情,如果你成功了,那就行了!

答案 3 :(得分:1)

计算区域而不是输入此代码

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

首先创建一个名为

的变量
Point pos1;

和另一个名为

的变量
Point pos2;

和一个名为

的布尔变量
Boolean b = true;

和两个双重名称

double diffx;

double diffy;

和名为

的区域的双精度数
double area;

所有变量都将在Form1类中 然后在Form1_Deactivate

中进行此操作
private void Form1_Deactivate(object sender, EventArgs e)
{
    if(b)
    {
         pos1 = Cursor.Position;
         b = 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;
        //now display it in the message box by this:
        MessageBox.Show(area.ToString());
    }
}

但是有一个问题是你必须在开始点点击它之后再次单击该程序,然后在结束点点击它以使程序正常工作

答案 4 :(得分:0)

停用事件会通知您的表单已不再有效。它可能因为很多原因而发生。

通常只有当鼠标悬停在此窗口上时,窗口才会获取鼠标事件。 SetCapture函数可以让你抓住所有鼠标事件(我不知道.NET对应物)。因为只有一个窗口可以捕获鼠标事件,所以在不需要它时不应捕获鼠标事件。问题没有足够详细说明您真正想做什么以及为何需要知道用户何时在表单外点击。