如何检测鼠标点击?

时间:2011-09-21 08:48:35

标签: c# .net mouse

如何在Windows上检测鼠标点击? (XP / Vista / 7的)。 例如,当我的应用程序运行时,它将检测用户是否点击某些内容(不在该应用程序UI上,而是在Windows UI上)。如果是,则执行另一个过程。

我不知道这是否可行,我希望有人可以给我一些指导。

谢谢!

4 个答案:

答案 0 :(得分:18)

如果要拦截任何鼠标点击,移动,鼠标滚轮点击等,您需要编写鼠标挂钩。

如果您想在自己的应用程序之外跟踪鼠标活动,这是AFAIK的唯一方法。如果要安装挂钩,则需要从User32.dll文件导入SetWindowsHookEx(...)函数。它涉及互操作(PInvoke),你必须导入(DllImport)一些函数。

以下是Microsoft关于如何在C#中实现此目的的官方文档:

How to set a Windows hook in Visual C# .NET

我会在这里总结一下,如果链接有一天消失,那就完成答案吧。

从SetWindowsHookEx函数开始:

[DllImport("user32.dll",CharSet=CharSet.Auto,
 CallingConvention=CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, 
IntPtr hInstance, int threadId);

现在你可以设置你的钩子了。例如:

public class Form1
{
    static int hHook = 0;
    public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    HookProc MouseHookProcedure;

    private void ActivateMouseHook_Click(object sender, System.EventArgs e)
    {
        if(hHook == 0)
        {
            MouseHookProcedure = new HookProc(Form1.MouseHookProc);
            hHook = SetWindowsHookEx(WH_MOUSE, 
                             MouseHookProcedure,
                             (IntPtr) 0,
                             AppDomain.GetCurrentThreadId());
        }
    }
}

不要忘记事后取消它。你需要另一个DllImport:

[DllImport("user32.dll",CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);

private void DeactivateMouseHook_Click(object sender, System.EventArgs e)
{
    bool ret = UnhookWindowsHookEx(hHook);
}    

您可以使用HookProc委托(MouseHookProcedure)捕获鼠标活动。这涉及一些编组以捕获数据。

[StructLayout(LayoutKind.Sequential)]
public class POINT 
{
    public int x;
    public int y;
}

[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct 
{
    public POINT pt;
    public int hwnd;
    public int wHitTestCode;
    public int dwExtraInfo;
}

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{          
    MouseHookStruct MyMouseHookStruct = (MouseHookStruct)
        Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

    // You can get the coördinates using the MyMouseHookStruct.
    // ...       
    return CallNextHookEx(hHook, nCode, wParam, lParam); 
}

不要忘记之后调用挂钩链中的下一个项目(CallNextHookEx)!

[DllImport("user32.dll",CharSet=CharSet.Auto,      
 CallingConvention=CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, 
IntPtr wParam, IntPtr lParam);

PS:你可以为键盘做同样的事情。

答案 1 :(得分:7)

Windows hooking mechanism是您需要使用的。看一下这篇文章:Processing Global Mouse and Keyboard Hooks in C#

答案 2 :(得分:6)

虽然Christophe Geers解决方案可帮助您捕获鼠标事件,但它并未提供完整的问题解决方案。 爱德华想知道如何获得点击事件。

要获得点击事件,请使用Christophe Geers提供的解决方案。 并添加/编辑以下内容:

enum MouseMessages
{
    WM_LBUTTONDOWN = 0x0201,
    WM_LBUTTONUP = 0x0202,
    WM_MOUSEMOVE = 0x0200,
    WM_MOUSEWHEEL = 0x020A,
    WM_RBUTTONDOWN = 0x0204,
    WM_RBUTTONUP = 0x0205
}

public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    //Marshall the data from the callback.
    MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

    if (nCode >= 0 &&
        MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
    {
        // Do something here
    }
    return CallNextHookEx(hookHandle, nCode, wParam, lParam);
}

答案 3 :(得分:0)

你需要的只是一个鼠标钩。它可以检测您的鼠标移动或点击。您可以在此处下载演示:C# mouse_hook_Demo
当您按下鼠标并将其释放时,您将在richtextbox上看到该事件。

private void mh_MouseDownEvent(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                richTextBox1.AppendText("Left Button Press\n");
            }
            if (e.Button == MouseButtons.Right)
            {
                richTextBox1.AppendText("Right Button Press\n");
            }
        }

        private void mh_MouseUpEvent(object sender, MouseEventArgs e)
        {

            if (e.Button == MouseButtons.Left)
            {
                richTextBox1.AppendText("Left Button Release\n");
            }
            if (e.Button == MouseButtons.Right)
            {
                richTextBox1.AppendText("Right Button Release\n");
            }

        }
        private void mh_MouseClickEvent(object sender, MouseEventArgs e)
        {
            //MessageBox.Show(e.X + "-" + e.Y);
            if (e.Button == MouseButtons.Left)
            {
                string sText = "(" + e.X.ToString() + "," + e.Y.ToString() + ")";
                label1.Text = sText;
            }
        }