使用Mono和C#监听系统范围内的点击?
我想使用mono编写一个简单的CL工具,它可以注册系统中的每一次点击。我知道我可以从Windows窗体访问此文件?哪一个类似于内部Windows API的包装器使用Mono和C#监听系统范围内的点击?,c#,windows,mono,C#,Windows,Mono,我想使用mono编写一个简单的CL工具,它可以注册系统中的每一次点击。我知道我可以从Windows窗体访问此文件?哪一个类似于内部Windows API的包装器 抱歉,这是一个非常愚蠢的问题,但是来自JS背景,它只是一个AddEventListener,这有点让人困惑,或者文档记录不好。谢谢您要找的是 这里有一些关于它的链接: 第一个链接包含如何使用dll的示例。 您可以使用此dll执行多项操作。例如,你所追求的是 [DllImport("User32.dll")] private s
抱歉,这是一个非常愚蠢的问题,但是来自JS背景,它只是一个AddEventListener,这有点让人困惑,或者文档记录不好。谢谢您要找的是
这里有一些关于它的链接:
第一个链接包含如何使用dll的示例。 您可以使用此dll执行多项操作。例如,你所追求的是
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Int32 vKey);
为此,每次需要检查钥匙是否已按下时,都需要检查钥匙。您可以使用或使用键
类
如果您还想模拟鼠标事件,例如,向系统发送左键单击,那么下面的代码就是您想要的。(更多信息)
不久前,我做了一件类似的事情,但我用的是键盘而不是鼠标。这个过程是类似的,但是它更容易连接到一个特定的程序。下面是我如何解决问题的代码 在下面的代码中,我创建了一个事件,该事件在按下某个键时触发,并将键代码作为事件参数发送
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeyHook {
public class KeyHook {
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
LowLevelKeyboardProc _proc { get; set; }
IntPtr _hookID { get; set; }
public delegate void KeyHandler(Keys k);
public event KeyHandler OnKeyDown;
public event KeyHandler OnKeyUp;
public KeyHook() {
Initialize();
_hookID = SetHook(_proc);
}
void Initialize() {
this._proc = HookCallback;
this._hookID = IntPtr.Zero;
Application.ApplicationExit += Application_ApplicationExit;
}
void Application_ApplicationExit(object sender, EventArgs e) {
UnhookWindowsHookEx(_hookID);
}
IntPtr SetHook(LowLevelKeyboardProc proc) {
using (Process curProcess = Process.GetCurrentProcess()) {
using (ProcessModule curModule = curProcess.MainModule) {
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle
(curModule.ModuleName), 0);
}
}
}
IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
if (this.OnKeyDown != null) {
this.OnKeyDown((Keys)Marshal.ReadInt32(lParam));
}
} else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) {
if (this.OnKeyUp != null) {
this.OnKeyUp((Keys)Marshal.ReadInt32(lParam));
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
#region dll Imports
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion
}
}
在.NET Framework上,您可以使用PInvoke通过调用相关的Win32 API来实现这一点。Mono允许您执行完全相同的操作。关于调用哪个Win32 API,以及如何使用PInvoke,请使用Google。出于兴趣,既然您在Windows上,为什么要使用Mono而不是.NET framework?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeyHook {
public class KeyHook {
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
LowLevelKeyboardProc _proc { get; set; }
IntPtr _hookID { get; set; }
public delegate void KeyHandler(Keys k);
public event KeyHandler OnKeyDown;
public event KeyHandler OnKeyUp;
public KeyHook() {
Initialize();
_hookID = SetHook(_proc);
}
void Initialize() {
this._proc = HookCallback;
this._hookID = IntPtr.Zero;
Application.ApplicationExit += Application_ApplicationExit;
}
void Application_ApplicationExit(object sender, EventArgs e) {
UnhookWindowsHookEx(_hookID);
}
IntPtr SetHook(LowLevelKeyboardProc proc) {
using (Process curProcess = Process.GetCurrentProcess()) {
using (ProcessModule curModule = curProcess.MainModule) {
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle
(curModule.ModuleName), 0);
}
}
}
IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
if (this.OnKeyDown != null) {
this.OnKeyDown((Keys)Marshal.ReadInt32(lParam));
}
} else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) {
if (this.OnKeyUp != null) {
this.OnKeyUp((Keys)Marshal.ReadInt32(lParam));
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
#region dll Imports
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetModuleHandle(string lpModuleName);
#endregion
}
}