C# 钩子 捕获键盘鼠标所有事件,可用于:判断鼠标键盘无操作时,关闭 Winform 窗体
5分钟没有操作,自动关闭 Form 窗体
钩子(Hook)的作用主要体现在监视和拦截系统或进程中的各种事件消息,并进行自定义处理。钩子可以截获并处理相应的消息,例如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。钩子分为线程钩子和系统钩子,线程钩子监视指定线程的事件消息,而系统钩子监视系统中的所有线程的事件消息
钩子的具体应用场景和功能
- 键盘和鼠标输入监控:钩子可以截获键盘和鼠标的输入,用于记录用户的操作或进行自动化测试。
- 屏幕取词和日志监视:通过监控系统事件,钩子可以实现屏幕取词功能或记录系统的操作日志。
- 应用程序监控:外壳钩子可以截取、启动和关闭应用程序的消息,用于监控或管理应用程序的行为。
钩子的种类及其功能
- 键盘钩子:截获键盘消息,用于记录键盘输入或进行输入拦截。
- 鼠标钩子:截获鼠标事件,用于监控鼠标操作。
- 外壳钩子:截取、启动和关闭应用程序的消息,用于管理应用程序行为。
- 日志钩子:监控系统日志事件,用于记录系统操作日志。
钩子的工作原理
钩子是Windows消息处理机制中的一个监视点,应用程序可以在这里安装一个监视子程序,从而在系统的消息流到达目的窗口的过程前监控它们。通过这种方式,钩子能够实现各种自定义的功能和处理逻辑
-
GlobalHook
-
KeyboardHook
-
MouseHook
-
KeyboardSimulator
-
MouseSimulator
GlobalHook
c#
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Forms;
namespace VipSoft.BaseClass.Hook
{
/// <summary>
/// Abstract base class for Mouse and Keyboard hooks
/// </summary>
public abstract class GlobalHook
{
#region Windows API Code
/// <summary>
/// 用于控制结构体或类的字段在内存中的布局方式
/// 具体来说,LayoutKind.Sequential 表示字段将按照它们在源代码中声明的顺序排列
/// 结构体字段将按照 x、y 的顺序在内存中排列
/// - Sequential:字段按声明顺序排列,不插入填充字节。
/// - Explicit:允许开发者精确控制每个字段的存储位置,使用 FieldOffset 属性指定偏移量。
/// - Auto:由编译器选择最优布局方式,通常不推荐用于与非托管代码交互的场景
/// </summary>
[StructLayout(LayoutKind.Sequential)]
protected class POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
protected class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
protected class MouseLLHookStruct
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public int dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
protected class KeyboardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
/// <summary>
/// CallingConvention属性指定调用约定,它定义了函数如何接收参数和返回值。常见的调用约定包括:
/// - CallingConvention.Cdecl:调用者清理堆栈,多用于C/C++库。
/// - CallingConvention.StdCall:被调用者清理堆栈,Windows API常用。
/// - CallingConvention.ThisCall:用于C++类方法。
/// - CallingConvention.FastCall:用于快速调用,较少使用。
/// CharSet属性用于指定字符串的字符集,影响字符串的处理和传递方式。主要选项有:
/// - CharSet.Ansi:将字符串作为ANSI编码传递。
/// - CharSet.Unicode:将字符串作为Unicode编码传递。
/// - CharSet.Auto:根据平台自动选择ANSI或Unicode。
/// SetLastError属性指定是否在调用非托管函数后调用GetLastError。设置为true时,可以使用Marshal.GetLastWin32Error获取错误代码。
///
/// idHook, 指示欲被安装的挂钩处理过程之类型
/// lpfn, 指向相应的挂钩处理过程.若参数dwThreadId为0或者指示了一个其他进程创建的线程之标识符,则参数lpfn必须指向一个动态链接中的挂钩处理过程.否则,参数lpfn可以指向一个与当前进程相关的代码中定义的挂钩处理过程
/// hMod 指示了一个动态链接的句柄,该动态连接库包含了参数lpfn 所指向的挂钩处理过程.若参数dwThreadId指示的线程由当前进程创建,并且相应的挂钩处理过程定义于当前进程相关的代码中,则参数hMod必须被设置为NULL(0)。
/// dwThreadId 指示了一个线程标识符,挂钩处理过程与线程相关.若此参数值为0,则该挂钩处理过程与所有现存的线程相关。
///
/// </summary>
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
protected static extern int SetWindowsHookEx(
int idHook,
HookProc lpfn,
IntPtr hMod,
int dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
protected static extern int UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]
protected static extern int CallNextHookEx(
int idHook,
int nCode,
int wParam,
IntPtr lParam);
[DllImport("user32")]
protected static extern int ToAscii(
int uVirtKey,
int uScanCode,
byte[] lpbKeyState,
byte[] lpwTransKey,
int fuState);
[DllImport("user32")]
protected static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern short GetKeyState(int vKey);
protected delegate int HookProc(int nCode, int wParam, IntPtr lParam);
protected const int WH_MOUSE_LL = 14; //此挂钩只能在Windows NT中被安装,用来对底层的鼠标输入事件进行监视.详情参见LowLevelMouseProc挂钩处理过程.
protected const int WH_KEYBOARD_LL = 13; //此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视.详情参见LowLevelKeyboardProc挂钩处理过程.
protected const int WH_MOUSE = 7; //安装一个挂钩处理过程,对鼠标消息进行监视. 详情参见 MouseProc挂钩处理过程.
protected const int WH_KEYBOARD = 2; //安装一个挂钩处理过程对击键消息进行监视. 详情参见KeyboardProc挂钩处理过程.
protected const int WM_MOUSEMOVE = 0x200; //鼠标移动
protected const int WM_LBUTTONDOWN = 0x201; //鼠标左健按下
protected const int WM_RBUTTONDOWN = 0x204; //鼠标右健按下
protected const int WM_MBUTTONDOWN = 0x207; //鼠标滚轮按下
protected const int WM_LBUTTONUP = 0x202;
protected const int WM_RBUTTONUP = 0x205;
protected const int WM_MBUTTONUP = 0x208;
protected const int WM_LBUTTONDBLCLK = 0x203;
protected const int WM_RBUTTONDBLCLK = 0x206;
protected const int WM_MBUTTONDBLCLK = 0x209;
protected const int WM_MOUSEWHEEL = 0x020A;
protected const int WM_KEYDOWN = 0x100;
protected const int WM_KEYUP = 0x101;
protected const int WM_SYSKEYDOWN = 0x104;
protected const int WM_SYSKEYUP = 0x105;
protected const byte VK_SHIFT = 0x10;
protected const byte VK_CAPITAL = 0x14;
protected const byte VK_NUMLOCK = 0x90;
protected const byte VK_LSHIFT = 0xA0;
protected const byte VK_RSHIFT = 0xA1;
protected const byte VK_LCONTROL = 0xA2;
protected const byte VK_RCONTROL = 0x3;
protected const byte VK_LALT = 0xA4;
protected const byte VK_RALT = 0xA5;
protected const byte LLKHF_ALTDOWN = 0x20;
#endregion
#region Private Variables
protected int _hookType;
protected int _handleToHook;
protected bool _isStarted;
protected HookProc _hookCallback;
#endregion
#region Properties
public bool IsStarted
{
get
{
return _isStarted;
}
}
#endregion
#region Constructor
public GlobalHook()
{
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
}
#endregion
#region Methods
/// <summary>
/// 启用钩子
/// </summary>
public void Start()
{
if (!_isStarted &&
_hookType != 0)
{
// Make sure we keep a reference to this delegate!
// If not, GC randomly collects it, and a NullReference exception is thrown
_hookCallback = new HookProc(HookCallbackProcedure);
_handleToHook = SetWindowsHookEx(
_hookType,
_hookCallback,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
0);
// Were we able to sucessfully start hook?
if (_handleToHook != 0)
{
_isStarted = true;
}
}
}
/// <summary>
/// 停止钩子
/// </summary>
public void Stop()
{
if (_isStarted)
{
UnhookWindowsHookEx(_handleToHook);
_isStarted = false;
}
}
protected virtual int HookCallbackProcedure(int nCode, Int32 wParam, IntPtr lParam)
{
// This method must be overriden by each extending hook
return 0;
}
protected void Application_ApplicationExit(object sender, EventArgs e)
{
if (_isStarted)
{
Stop();
}
}
#endregion
}
}
KeyboardHook
C#
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VipSoft.BaseClass.Hook
{
/// <summary>
/// Captures global keyboard events
/// </summary>
public class KeyboardHook : GlobalHook
{
#region Events
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
public event KeyPressEventHandler KeyPress;
#endregion
#region Constructor
public KeyboardHook()
{
_hookType = WH_KEYBOARD_LL;
}
#endregion
#region Methods
protected override int HookCallbackProcedure(int nCode, int wParam, IntPtr lParam)
{
bool handled = false;
if (nCode > -1 && (KeyDown != null || KeyUp != null || KeyPress != null))
{
KeyboardHookStruct keyboardHookStruct =
(KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// Is Control being held down?
bool control = ((GetKeyState(VK_LCONTROL) & 0x80) != 0) ||
((GetKeyState(VK_RCONTROL) & 0x80) != 0);
// Is Shift being held down?
bool shift = ((GetKeyState(VK_LSHIFT) & 0x80) != 0) ||
((GetKeyState(VK_RSHIFT) & 0x80) != 0);
// Is Alt being held down?
bool alt = ((GetKeyState(VK_LALT) & 0x80) != 0) ||
((GetKeyState(VK_RALT) & 0x80) != 0);
// Is CapsLock on?
bool capslock = (GetKeyState(VK_CAPITAL) != 0);
// Create event using keycode and control/shift/alt values found above
KeyEventArgs e = new KeyEventArgs(
(Keys)(
keyboardHookStruct.vkCode |
(control ? (int)Keys.Control : 0) |
(shift ? (int)Keys.Shift : 0) |
(alt ? (int)Keys.Alt : 0)
));
// Handle KeyDown and KeyUp events
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (KeyDown != null)
{
KeyDown(this, e);
handled = handled || e.Handled;
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
if (KeyUp != null)
{
KeyUp(this, e);
handled = handled || e.Handled;
}
break;
}
// Handle KeyPress event
if (wParam == WM_KEYDOWN &&
!handled &&
!e.SuppressKeyPress &&
KeyPress != null)
{
byte[] keyState = new byte[256];
byte[] inBuffer = new byte[2];
GetKeyboardState(keyState);
if (ToAscii(keyboardHookStruct.vkCode,
keyboardHookStruct.scanCode,
keyState,
inBuffer,
keyboardHookStruct.flags) == 1)
{
char key = (char)inBuffer[0];
if ((capslock ^ shift) && Char.IsLetter(key))
key = Char.ToUpper(key);
KeyPressEventArgs e2 = new KeyPressEventArgs(key);
KeyPress(this, e2);
handled = handled || e.Handled;
}
}
}
if (handled)
{
return 1;
}
else
{
return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
}
}
#endregion
}
}
MouseHook
c#
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VipSoft.BaseClass.Hook
{
/// <summary>
/// Captures global mouse events
/// </summary>
public class MouseHook : GlobalHook
{
#region MouseEventType Enum
private enum MouseEventType
{
None,
MouseDown,
MouseUp,
DoubleClick,
MouseWheel,
MouseMove
}
#endregion
#region Events
public event MouseEventHandler MouseDown;
public event MouseEventHandler MouseUp;
public event MouseEventHandler MouseMove;
public event MouseEventHandler MouseWheel;
public event EventHandler Click;
public event EventHandler DoubleClick;
#endregion
#region Constructor
public MouseHook()
{
_hookType = WH_MOUSE_LL;
}
#endregion
#region Methods
protected override int HookCallbackProcedure(int nCode, int wParam, IntPtr lParam)
{
if (nCode > -1 && (MouseDown != null || MouseUp != null || MouseMove != null))
{
MouseLLHookStruct mouseHookStruct =
(MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));
MouseButtons button = GetButton(wParam);
MouseEventType eventType = GetEventType(wParam);
MouseEventArgs e = new MouseEventArgs(
button,
(eventType == MouseEventType.DoubleClick ? 2 : 1),
mouseHookStruct.pt.x,
mouseHookStruct.pt.y,
(eventType == MouseEventType.MouseWheel ? (short)((mouseHookStruct.mouseData >> 16) & 0xffff) : 0));
// Prevent multiple Right Click events (this probably happens for popup menus)
if (button == MouseButtons.Right && mouseHookStruct.flags != 0)
{
eventType = MouseEventType.None;
}
switch (eventType)
{
case MouseEventType.MouseDown:
if (MouseDown != null)
{
MouseDown(this, e);
}
break;
case MouseEventType.MouseUp:
if (Click != null)
{
Click(this, new EventArgs());
}
if (MouseUp != null)
{
MouseUp(this, e);
}
break;
case MouseEventType.DoubleClick:
if (DoubleClick != null)
{
DoubleClick(this, new EventArgs());
}
break;
case MouseEventType.MouseWheel:
if (MouseWheel != null)
{
MouseWheel(this, e);
}
break;
case MouseEventType.MouseMove:
if (MouseMove != null)
{
MouseMove(this, e);
}
break;
default:
break;
}
}
return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
}
private MouseButtons GetButton(Int32 wParam)
{
switch (wParam)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
return MouseButtons.Left;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_RBUTTONDBLCLK:
return MouseButtons.Right;
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MBUTTONDBLCLK:
return MouseButtons.Middle;
default:
return MouseButtons.None;
}
}
private MouseEventType GetEventType(Int32 wParam)
{
switch (wParam)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
return MouseEventType.MouseDown;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
return MouseEventType.MouseUp;
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
return MouseEventType.DoubleClick;
case WM_MOUSEWHEEL:
return MouseEventType.MouseWheel;
case WM_MOUSEMOVE:
return MouseEventType.MouseMove;
default:
return MouseEventType.None;
}
}
#endregion
}
}
KeyboardSimulator
c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace VipSoft.BaseClass.Hook
{
/// <summary>
/// Standard Keyboard Shortcuts used by most applications
/// </summary>
public enum StandardShortcut
{
Copy,
Cut,
Paste,
SelectAll,
Save,
Open,
New,
Close,
Print
}
/// <summary>
/// Simulate keyboard key presses
/// </summary>
public static class KeyboardSimulator
{
#region Windows API Code
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;
[DllImport("user32.dll")]
static extern void keybd_event(byte key, byte scan, int flags, int extraInfo);
#endregion
#region Methods
public static void KeyDown(Keys key)
{
keybd_event(ParseKey(key), 0, 0, 0);
}
public static void KeyUp(Keys key)
{
keybd_event(ParseKey(key), 0, KEYEVENTF_KEYUP, 0);
}
public static void KeyPress(Keys key)
{
KeyDown(key);
KeyUp(key);
}
public static void SimulateStandardShortcut(StandardShortcut shortcut)
{
switch (shortcut)
{
case StandardShortcut.Copy:
KeyDown(Keys.Control);
KeyPress(Keys.C);
KeyUp(Keys.Control);
break;
case StandardShortcut.Cut:
KeyDown(Keys.Control);
KeyPress(Keys.X);
KeyUp(Keys.Control);
break;
case StandardShortcut.Paste:
KeyDown(Keys.Control);
KeyPress(Keys.V);
KeyUp(Keys.Control);
break;
case StandardShortcut.SelectAll:
KeyDown(Keys.Control);
KeyPress(Keys.A);
KeyUp(Keys.Control);
break;
case StandardShortcut.Save:
KeyDown(Keys.Control);
KeyPress(Keys.S);
KeyUp(Keys.Control);
break;
case StandardShortcut.Open:
KeyDown(Keys.Control);
KeyPress(Keys.O);
KeyUp(Keys.Control);
break;
case StandardShortcut.New:
KeyDown(Keys.Control);
KeyPress(Keys.N);
KeyUp(Keys.Control);
break;
case StandardShortcut.Close:
KeyDown(Keys.Alt);
KeyPress(Keys.F4);
KeyUp(Keys.Alt);
break;
case StandardShortcut.Print:
KeyDown(Keys.Control);
KeyPress(Keys.P);
KeyUp(Keys.Control);
break;
}
}
static byte ParseKey(Keys key)
{
// Alt, Shift, and Control need to be changed for API function to work with them
switch (key)
{
case Keys.Alt:
return (byte)18;
case Keys.Control:
return (byte)17;
case Keys.Shift:
return (byte)16;
default:
return (byte)key;
}
}
#endregion
}
}
MouseSimulator
c#
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace VipSoft.BaseClass.Hook
{
/// <summary>
/// And X, Y point on the screen
/// </summary>
public struct MousePoint
{
public MousePoint(Point p)
{
X = p.X;
Y = p.Y;
}
public int X;
public int Y;
public static implicit operator Point(MousePoint p)
{
return new Point(p.X, p.Y);
}
}
/// <summary>
/// Mouse buttons that can be pressed
/// </summary>
public enum MouseButton
{
Left = 0x2,
Right = 0x8,
Middle = 0x20
}
/// <summary>
/// Operations that simulate mouse events
/// </summary>
public static class MouseSimulator
{
#region Windows API Code
[DllImport("user32.dll")]
static extern int ShowCursor(bool show);
[DllImport("user32.dll")]
static extern void mouse_event(int flags, int dX, int dY, int buttons, int extraInfo);
const int MOUSEEVENTF_MOVE = 0x1;
const int MOUSEEVENTF_LEFTDOWN = 0x2;
const int MOUSEEVENTF_LEFTUP = 0x4;
const int MOUSEEVENTF_RIGHTDOWN = 0x8;
const int MOUSEEVENTF_RIGHTUP = 0x10;
const int MOUSEEVENTF_MIDDLEDOWN = 0x20;
const int MOUSEEVENTF_MIDDLEUP = 0x40;
const int MOUSEEVENTF_WHEEL = 0x800;
const int MOUSEEVENTF_ABSOLUTE = 0x8000;
#endregion
#region Properties
/// <summary>
/// Gets or sets a structure that represents both X and Y mouse coordinates
/// </summary>
public static MousePoint Position
{
get
{
return new MousePoint(Cursor.Position);
}
set
{
Cursor.Position = value;
}
}
/// <summary>
/// Gets or sets only the mouse's x coordinate
/// </summary>
public static int X
{
get
{
return Cursor.Position.X;
}
set
{
Cursor.Position = new Point(value, Y);
}
}
/// <summary>
/// Gets or sets only the mouse's y coordinate
/// </summary>
public static int Y
{
get
{
return Cursor.Position.Y;
}
set
{
Cursor.Position = new Point(X, value);
}
}
#endregion
#region Methods
/// <summary>
/// Press a mouse button down
/// </summary>
/// <param name="button"></param>
public static void MouseDown(MouseButton button)
{
mouse_event(((int)button), 0, 0, 0, 0);
}
public static void MouseDown(MouseButtons button)
{
switch (button)
{
case MouseButtons.Left:
MouseDown(MouseButton.Left);
break;
case MouseButtons.Middle:
MouseDown(MouseButton.Middle);
break;
case MouseButtons.Right:
MouseDown(MouseButton.Right);
break;
}
}
/// <summary>
/// Let a mouse button up
/// </summary>
/// <param name="button"></param>
public static void MouseUp(MouseButton button)
{
mouse_event(((int)button) * 2, 0, 0, 0, 0);
}
public static void MouseUp(MouseButtons button)
{
switch (button)
{
case MouseButtons.Left:
MouseUp(MouseButton.Left);
break;
case MouseButtons.Middle:
MouseUp(MouseButton.Middle);
break;
case MouseButtons.Right:
MouseUp(MouseButton.Right);
break;
}
}
/// <summary>
/// Click a mouse button (down then up)
/// </summary>
/// <param name="button"></param>
public static void Click(MouseButton button)
{
MouseDown(button);
MouseUp(button);
}
public static void Click(MouseButtons button)
{
switch (button)
{
case MouseButtons.Left:
Click(MouseButton.Left);
break;
case MouseButtons.Middle:
Click(MouseButton.Middle);
break;
case MouseButtons.Right:
Click(MouseButton.Right);
break;
}
}
/// <summary>
/// Double click a mouse button (down then up twice)
/// </summary>
/// <param name="button"></param>
public static void DoubleClick(MouseButton button)
{
Click(button);
Click(button);
}
public static void DoubleClick(MouseButtons button)
{
switch (button)
{
case MouseButtons.Left:
DoubleClick(MouseButton.Left);
break;
case MouseButtons.Middle:
DoubleClick(MouseButton.Middle);
break;
case MouseButtons.Right:
DoubleClick(MouseButton.Right);
break;
}
}
/// <summary>
/// Show a hidden current on currently application
/// </summary>
public static void Show()
{
ShowCursor(true);
}
/// <summary>
/// Hide mouse cursor only on current application's forms
/// </summary>
public static void Hide()
{
ShowCursor(false);
}
#endregion
}
}
测试类:
c#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MouseKeyboardLibrary;
namespace SampleApplication
{
/*
上面的5个类编译成Dll引用,使用例子
*/
public partial class HookTestForm : Form
{
//用于判断,窗休是否自动关闭
System.Windows.Forms.Timer mTimer = new System.Windows.Forms.Timer();
//记录鼠标键盘操作时间,用于判断 Form 窗体自动关闭
private DateTime mRecordTime = DateTime.Now;
MouseHook mouseHook = new MouseHook();
KeyboardHook keyboardHook = new KeyboardHook();
public HookTestForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
mTimer.Tick += mTimer_Tick;
mTimer.Interval = 2000;
mTimer.Start(); //开启定时器
mouseHook.MouseMove += new MouseEventHandler(mouseHook_MouseMove);
mouseHook.MouseDown += new MouseEventHandler(mouseHook_MouseDown);
mouseHook.MouseUp += new MouseEventHandler(mouseHook_MouseUp);
mouseHook.MouseWheel += new MouseEventHandler(mouseHook_MouseWheel);
keyboardHook.KeyDown += new KeyEventHandler(keyboardHook_KeyDown);
keyboardHook.KeyUp += new KeyEventHandler(keyboardHook_KeyUp);
keyboardHook.KeyPress += new KeyPressEventHandler(keyboardHook_KeyPress);
mouseHook.Start();
keyboardHook.Start();
SetXYLabel("", MouseSimulator.X.ToString(), MouseSimulator.Y.ToString());
}
void keyboardHook_KeyPress(object sender, KeyPressEventArgs e)
{
AddKeyboardEvent(
"KeyPress",
"",
e.KeyChar.ToString(),
"",
"",
""
);
}
void keyboardHook_KeyUp(object sender, KeyEventArgs e)
{
AddKeyboardEvent(
"KeyUp",
e.KeyCode.ToString(),
"",
e.Shift.ToString(),
e.Alt.ToString(),
e.Control.ToString()
);
}
void keyboardHook_KeyDown(object sender, KeyEventArgs e)
{
AddKeyboardEvent(
"KeyDown",
e.KeyCode.ToString(),
"",
e.Shift.ToString(),
e.Alt.ToString(),
e.Control.ToString()
);
}
void mouseHook_MouseWheel(object sender, MouseEventArgs e)
{
AddMouseEvent(
"MouseWheel",
"",
"",
"",
e.Delta.ToString()
);
}
void mouseHook_MouseUp(object sender, MouseEventArgs e)
{
AddMouseEvent(
"MouseUp",
e.Button.ToString(),
e.X.ToString(),
e.Y.ToString(),
""
);
}
void mouseHook_MouseDown(object sender, MouseEventArgs e)
{
AddMouseEvent(
"MouseDown",
e.Button.ToString(),
e.X.ToString(),
e.Y.ToString(),
""
);
}
void mouseHook_MouseMove(object sender, MouseEventArgs e)
{
SetXYLabel("", e.X.ToString(), e.Y.ToString());
}
void SetXYLabel(string keyName, string x, string y)
{
this.Text = $"Current keyName={keyName} Point: X={x}, y={y} {DateTime.Now.ToString("HH:mm:ss")}";
mRecordTime = DateTime.Now;
}
void AddMouseEvent(string eventType, string button, string x, string y, string delta)
{
//this.Text = $"Current Mouse eventType ={eventType} button ={button} delta ={delta} X ={x}, y ={y}";
SetXYLabel(button, x, y);
}
void AddKeyboardEvent(string eventType, string keyCode, string keyChar, string shift, string alt, string control)
{
//this.Text = $"Current Mouse eventType ={eventType} keyCode ={keyCode} keyChar ={keyChar} shift ={shift}, alt ={alt} control={control}";
SetXYLabel(button, x, y);
}
private void TestForm_FormClosed(object sender, FormClosedEventArgs e)
{
// Not necessary anymore, will stop when application exits
//mouseHook.Stop();
//keyboardHook.Stop();
}
private bool stopForm = false;
//定时器
private void mTimer_Tick(object sender, EventArgs e)
{
if (stopForm)
{
return;
}
if ((DateTime.Now - mRecordTime).TotalMinutes >= 5) //记录时间大于5分钟
{
stopForm = true;
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
Form item = Application.OpenForms[i];
if (item.Name != this.Name && item.Name != "UserLogin") //关闭不是主窗体的打开窗体
{
item.Close();
}
}
this.WindowState = FormWindowState.Maximized;
stopForm = false;
}
}
}
}