简体   繁体   English

获取鼠标点击坐标

[英]Getting Mouse Click Coordinates

I am working on a Project in c# and need to get Mouse Click Coordinates in the textbox.我正在 c# 中处理一个项目,需要在文本框中获取鼠标单击坐标。 Clicking can be made outside the Screen.单击可以在屏幕外进行。 I have found a code in the internet but can't make the coordinates bring out in the textbox.我在互联网上找到了一个代码,但无法在文本框中显示坐标。 Here is the code.. I was trying to write "hookStruct.pt.x" in HookCallBack but it didn't work as well.这是代码.. 我试图在 HookCallBack 中编写“hookStruct.pt.x”,但效果不佳。 Does anyone have any idea how to do this?有谁知道如何做到这一点?

namespace Mouse_Hook
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static LowLevelMouseProc _proc = HookCallback;

        private const int WH_MOUSE_LL = 14;
        private static IntPtr _hookID = IntPtr.Zero;

        private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 &&
            MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {

                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y); 
                Console.Read();
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
            }
        }

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

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

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

        private void Form1_Load(object sender, EventArgs e)
        {
            _hookID = SetHook(_proc);
            Application.Run();
            UnhookWindowsHookEx(_hookID);
        }

    }
}

If I understand correctly, the best for your needs would be to put the hook functionality inside a static (global) class and expose a static event.如果我理解正确,最适合您的需求是将钩子功能放在静态(全局)类中并公开静态事件。 In your case, the form will subscribe on that event when opened (and should unsubscribe when closed).在您的情况下,表单将在打开时订阅该事件(并在关闭时取消订阅)。 Something like this像这样的东西

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Samples
{
    public static class MouseHook
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
                    LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        private const int WH_MOUSE_LL = 14;

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

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

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

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

        private static IntPtr _hookID = IntPtr.Zero;

        public static void Register()
        {
            if (_hookID != IntPtr.Zero) return;
            _hookID = SetHook(HookCallback);
        }

        public static void Unregister()
        {
            if (_hookID == IntPtr.Zero) return;
            UnhookWindowsHookEx(_hookID);
            _hookID = IntPtr.Zero;
        }

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                var handler = LButtonDown;
                if (handler != null) handler(null, EventArgs.Empty);
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        public static event EventHandler LButtonDown;
    }
    // Test
    class TestForm : Form
    {
        Label label;
        protected override void OnLoad(EventArgs e)
        {
            Controls.Add(label = new Label());
            MouseHook.LButtonDown += OnHookLButtonDown;
            base.OnLoad(e);
        }
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            MouseHook.LButtonDown -= OnHookLButtonDown;
        }
        private void OnHookLButtonDown(object sender, EventArgs e)
        {
            var pt = Control.MousePosition;
            label.Text = "{" + pt.X + ", " + pt.Y + "}";
        }
    }
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            MouseHook.Register();
            try { Application.Run(new TestForm()); }
            finally { MouseHook.Unregister(); }
        }
    }
}

Please note that this is just an example.请注意,这只是一个例子。 A production code would extract the information from the hook parameters and expose a global events similar to the standard MoseMove , MouseDown etc.生产代码将从钩子参数中提取信息并公开类似于标准MoseMoveMouseDown等的全局事件。

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

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