简体   繁体   English

如何检测鼠标点击?

[英]How to detect mouse clicks?

how can i detect mouse clicks on Windows ? 如何在Windows上检测鼠标点击? (XP/Vista/7). (XP / Vista / 7的)。 for example when my application is running , it will detect if user click on something (not on that application UI but on Windows UI). 例如,当我的应用程序运行时,它将检测用户是否点击某些内容(不在该应用程序UI上,而是在Windows UI上)。 if yes , execute another process. 如果是,则执行另一个进程。

I don't know if this is possible , i am hoping someone can give me some guidance. 我不知道这是否可能,我希望有人可以给我一些指导。

Thanks! 谢谢!

You need to write a mouse hook if you want to intercept any mouse clicks, movement, mouse wheel clicks...etc. 如果要拦截任何鼠标点击,移动,鼠标滚轮点击等,您需要编写鼠标挂钩。

This is the only way AFAIK if you want to track mouse activity outside of your own application. 如果您想在自己的应用程序之外跟踪鼠标活动,这是AFAIK的唯一方法。 You need to import the SetWindowsHookEx(...) function from the User32.dll file if you want to install a hook. 如果要安装挂钩,则需要从User32.dll文件导入SetWindowsHookEx(...)函数。 It involves interop (PInvoke) and you'll have to import (DllImport) some functions. 它涉及互操作(PInvoke),你必须导入(DllImport)一些函数。

Here's an official document by Microsoft on how to achieve this in C#: 以下是Microsoft关于如何在C#中实现此目的的官方文档:

How to set a Windows hook in Visual C# .NET 如何在Visual C#.NET中设置Windows挂钩

I'll summarize it here, just to be complete the answer should the link die one day. 我将在这里总结一下,如果链接有一天会死,那么答案就完整了。

Starting with the SetWindowsHookEx function: 从SetWindowsHookEx函数开始:

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

Now you can setup your hook. 现在你可以设置你的钩子了。 For example: 例如:

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());
        }
    }
}

Don't forget to unhook it afterwards. 不要忘记事后取消它。 You'll need another DllImport for this: 你需要另一个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);
}    

You can use the HookProc delegate (MouseHookProcedure) to capture the mouse activity. 您可以使用HookProc委托(MouseHookProcedure)捕获鼠标活动。 This involves some marshalling in order to capture the data. 这涉及一些编组以捕获数据。

[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); 
}

Don't forget to call the next item in the hook chain afterwards (CallNextHookEx)! 不要忘记之后调用钩子链中的下一个项目(CallNextHookEx)!

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

PS: You can do the same for the keyboard. PS:你可以为键盘做同样的事情。

Windows hooking mechanism is what you need to work with. Windows挂钩机制是您需要使用的。 Take a look at this article: Processing Global Mouse and Keyboard Hooks in C# 看一下这篇文章: 用C#处理全局鼠标和键盘钩子

While Christophe Geers solution helps you to capture the mouse event, it does not provide a complete solution to the issue. 虽然Christophe Geers解决方案可帮助您捕获鼠标事件,但它无法提供完整的问题解决方案。 Edward wanted to know how to get the click event. 爱德华想知道如何获得点击事件。

To get the click event, use the solution provided by Christophe Geers. 要获得点击事件,请使用Christophe Geers提供的解决方案。 And add/edit the following: 并添加/编辑以下内容:

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);
}

All you need is a mouse hook. 你只需要一个鼠标钩。 It can detect your mouse movement or clicks. 它可以检测您的鼠标移动或点击。 You can download the demo here: C# mouse_hook_Demo 您可以在此处下载演示: C#mouse_hook_Demo
When you press your mouse and release it, you will see the event on the richtextbox. 当您按下鼠标并将其释放时,您将在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;
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM