c#做的全局鼠标/键盘钩子
时间: 2023-06-15 11:02:14 浏览: 85
对于C语言,作为一种高效的程序设计语言,它被广泛应用于嵌入式系统的开发和底层编程。同时,C语言也是其他编程语言的基础。在学习过程中,我们需要掌握的知识包括语法、指针、结构体、库函数等。C语言的语法简单规范,易于学习,同时它的指针概念也很重要,可以实现动态内存分配、数组操作等,但也容易出现指针误用等问题。C语言使用结构体可以将多个数据类型封装在一起,方便程序员对数据类型的选择和操作。C标准库函数提供了大量的功能,比如字符串处理、数学计算等,可以大大简化编程工作。总的来说,学习C语言可以使我们更深入地了解计算机底层工作原理,提高编程能力,并为未来学习其他编程语言打下坚实的基础。
相关问题
C#全局鼠标钩子完整源码
以下是C#全局鼠标钩子的完整源码:
首先,创建一个名为MouseHook的类,实现IMouseHook接口:
```csharp
using System;
using System.Runtime.InteropServices;
namespace MouseHookExample
{
public class MouseHook : IMouseHook
{
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_RBUTTONDOWN = 0x0204;
private LowLevelMouseProc _proc;
private IntPtr _hookId = IntPtr.Zero;
public event EventHandler<MouseEventArgs> LeftButtonDown;
public event EventHandler<MouseEventArgs> RightButtonDown;
public void Start()
{
_proc = HookCallback;
_hookId = SetHook(_proc);
}
public void Stop()
{
UnhookWindowsHookEx(_hookId);
_hookId = IntPtr.Zero;
}
private IntPtr SetHook(LowLevelMouseProc proc)
{
using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (wParam == (IntPtr)WM_LBUTTONDOWN || wParam == (IntPtr)WM_RBUTTONDOWN))
{
var hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var args = new MouseEventArgs(hookStruct.pt.x, hookStruct.pt.y);
if (wParam == (IntPtr)WM_LBUTTONDOWN)
{
LeftButtonDown?.Invoke(this, args);
}
else if (wParam == (IntPtr)WM_RBUTTONDOWN)
{
RightButtonDown?.Invoke(this, args);
}
}
return CallNextHookEx(_hookId, nCode, wParam, lParam);
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
[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);
[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;
}
}
}
```
接下来,定义一个名为MouseEventArgs的类,用于传递鼠标事件的参数:
```csharp
using System;
namespace MouseHookExample
{
public class MouseEventArgs : EventArgs
{
public int X { get; }
public int Y { get; }
public MouseEventArgs(int x, int y)
{
X = x;
Y = y;
}
}
}
```
最后,定义一个名为IMouseHook的接口,用于规范MouseHook类的实现:
```csharp
using System;
namespace MouseHookExample
{
public interface IMouseHook
{
event EventHandler<MouseEventArgs> LeftButtonDown;
event EventHandler<MouseEventArgs> RightButtonDown;
void Start();
void Stop();
}
}
```
现在,我们可以在其他类中使用该鼠标钩子:
```csharp
using System;
namespace MouseHookExample
{
class Program
{
static void Main(string[] args)
{
var mouseHook = new MouseHook();
mouseHook.LeftButtonDown += (sender, e) => Console.WriteLine($"Left button down at ({e.X}, {e.Y})");
mouseHook.RightButtonDown += (sender, e) => Console.WriteLine($"Right button down at ({e.X}, {e.Y})");
mouseHook.Start();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
mouseHook.Stop();
}
}
}
```
现在,当用户按下鼠标左键或右键时,程序将在控制台中输出相应的信息。
C# 用全局钩子使鼠标按键左右键互换,鼠标移动反向相反
实现这个需求需要使用 C# 中的钩子函数来实现全局鼠标事件监听。具体步骤如下:
1. 引入 System.Runtime.InteropServices 命名空间。
2. 定义鼠标事件枚举类型:
```csharp
public enum MouseEventFlags
{
LEFTDOWN = 0x00000002,
LEFTUP = 0x00000004,
MIDDLEDOWN = 0x00000020,
MIDDLEUP = 0x00000040,
MOVE = 0x00000001,
ABSOLUTE = 0x00008000,
RIGHTDOWN = 0x00000008,
RIGHTUP = 0x00000010,
WHEEL = 0x00000800,
XDOWN = 0x00000080,
XUP = 0x00000100
}
```
3. 定义 MouseHookStruct 结构体:
```csharp
[StructLayout(LayoutKind.Sequential)]
public struct MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
```
4. 定义全局鼠标事件委托类型:
```csharp
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
```
5. 定义全局变量和函数:
```csharp
private static int hHook = 0;
private static HookProc HookProcedure;
[DllImport("user32.dll")]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll")]
public static extern int CallNextHookEx(int hHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern int UnhookWindowsHookEx(int hHook);
```
6. 实现钩子函数:
```csharp
private static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
MouseHookStruct mhs = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
if (wParam == (IntPtr)MouseEventFlags.LEFTDOWN)
{
MouseEventFlags button = MouseEventFlags.LEFTDOWN;
MouseEventFlags swappedButton = MouseEventFlags.RIGHTDOWN;
SwapMouseButton(button, swappedButton);
}
else if (wParam == (IntPtr)MouseEventFlags.RIGHTDOWN)
{
MouseEventFlags button = MouseEventFlags.RIGHTDOWN;
MouseEventFlags swappedButton = MouseEventFlags.LEFTDOWN;
SwapMouseButton(button, swappedButton);
}
else if (wParam == (IntPtr)MouseEventFlags.MOVE)
{
int x = mhs.pt.X;
int y = mhs.pt.Y;
SwapMouseMovement(ref x, ref y);
mhs.pt.X = x;
mhs.pt.Y = y;
Marshal.StructureToPtr(mhs, lParam, true);
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
```
7. 实现鼠标按键互换和鼠标移动反向相反的方法:
```csharp
private static void SwapMouseButton(MouseEventFlags button, MouseEventFlags swappedButton)
{
int flags = GetSystemMetrics(0x0010);
if ((flags & 0x0001) != 0)
{
// Primary mouse button is currently left button
if ((button == MouseEventFlags.LEFTDOWN) || (button == MouseEventFlags.LEFTUP))
{
mouse_event((int)swappedButton, 0, 0, 0, 0);
}
else if ((button == MouseEventFlags.RIGHTDOWN) || (button == MouseEventFlags.RIGHTUP))
{
mouse_event((int)MouseEventFlags.LEFTDOWN, 0, 0, 0, 0);
mouse_event((int)MouseEventFlags.LEFTUP, 0, 0, 0, 0);
}
}
else
{
// Primary mouse button is currently right button
if ((button == MouseEventFlags.RIGHTDOWN) || (button == MouseEventFlags.RIGHTUP))
{
mouse_event((int)swappedButton, 0, 0, 0, 0);
}
else if ((button == MouseEventFlags.LEFTDOWN) || (button == MouseEventFlags.LEFTUP))
{
mouse_event((int)MouseEventFlags.RIGHTDOWN, 0, 0, 0, 0);
mouse_event((int)MouseEventFlags.RIGHTUP, 0, 0, 0, 0);
}
}
}
private static void SwapMouseMovement(ref int x, ref int y)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
x = width - x;
y = height - y;
}
```
8. 注册全局钩子并启动:
```csharp
HookProcedure = new HookProc(MouseHookProc);
hHook = SetWindowsHookEx(14, HookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
```
需要注意的是,这里使用了 user32.dll 中的一些函数,需要在代码中进行引用。同时,这里使用了 SetWindowsHookEx 函数注册了一个全局鼠标钩子,需要在程序关闭时调用 UnhookWindowsHookEx 函数取消注册。