-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVirtualMouse.cs
96 lines (88 loc) · 3.97 KB
/
VirtualMouse.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
namespace VirtualInput
{
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
/// <summary>Enables applications to intercept mouse activity</summary>
public static class VirtualMouse
{
private static int hHook = 0;
private static NativeMethods.HookProc hookProc;
/// <summary>Fires when the mouse is moved/clicked/scrolled</summary>
public static event MouseEventHandler MouseActivity;
/// <summary>Starts intercepting keystrokes</summary>
public static void StartInterceptor()
{
if (hHook == 0)
{
hookProc = new NativeMethods.HookProc(MouseHookProc);
IntPtr moduleHandle = NativeMethods.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
hHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, hookProc, moduleHandle, 0);
if (hHook == 0)
{
int errorCode = Marshal.GetLastWin32Error();
StopInterceptor();
throw new Win32Exception(errorCode);
}
}
}
/// <summary>Stops intercepting keystrokes</summary>
public static void StopInterceptor()
{
if (hHook != 0)
{
int result = NativeMethods.UnhookWindowsHookEx(hHook);
hHook = 0;
if (result == 0)
{
int errorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(errorCode);
}
}
}
/// <summary>Called by the Win32 functions when a mouse event occurs</summary>
/// <param name="nCode">A code that the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.</param>
/// <param name="wParam">The identifier of the mouse message.</param>
/// <param name="lParam">A pointer to a MOUSEHOOKSTRUCT structure.</param>
/// <returns>1 if the event was handled, otherwise the return value of CallNextHookEx.</returns>
private static int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
if ((nCode >= 0) && (MouseActivity != null))
{
NativeMethods.MouseLLHookStruct mouseHookStruct = (NativeMethods.MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(NativeMethods.MouseLLHookStruct));
MouseButtons button = MouseButtons.None;
short mouseDelta = 0;
switch (wParam)
{
case NativeMethods.WM_LBUTTONDOWN:
button = MouseButtons.Left;
break;
case NativeMethods.WM_RBUTTONDOWN:
button = MouseButtons.Right;
break;
case NativeMethods.WM_MOUSEWHEEL:
mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);
break;
}
int clickCount = 0;
if (button != MouseButtons.None)
{
if (wParam == NativeMethods.WM_LBUTTONDBLCLK || wParam == NativeMethods.WM_RBUTTONDBLCLK)
{
clickCount = 2;
}
else
{
clickCount = 1;
}
}
MouseEventArgs e = new MouseEventArgs(button, clickCount, mouseHookStruct.pt.x, mouseHookStruct.pt.y, mouseDelta);
MouseActivity(null, e);
}
return NativeMethods.CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}