c# 钩子 捕获键盘鼠标所有事件,可用于:判断鼠标键盘无操作时,关闭 winform 窗体
5分钟没有操作,自动关闭 form 窗体
钩子(hook)的作用主要体现在监视和拦截系统或进程中的各种事件消息,并进行自定义处理。钩子可以截获并处理相应的消息,例如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。钩子分为线程钩子和系统钩子,线程钩子监视指定线程的事件消息,而系统钩子监视系统中的所有线程的事件消息
钩子的具体应用场景和功能
键盘和鼠标输入监控:钩子可以截获键盘和鼠标的输入,用于记录用户的操作或进行自动化测试。
屏幕取词和日志监视:通过监控系统事件,钩子可以实现屏幕取词功能或记录系统的操作日志。
应用程序监控:外壳钩子可以截取、启动和关闭应用程序的消息,用于监控或管理应用程序的行为。
钩子的种类及其功能
键盘钩子:截获键盘消息,用于记录键盘输入或进行输入拦截。
鼠标钩子:截获鼠标事件,用于监控鼠标操作。
外壳钩子:截取、启动和关闭应用程序的消息,用于管理应用程序行为。
日志钩子:监控系统日志事件,用于记录系统操作日志。
钩子的工作原理
钩子是windows消息处理机制中的一个监视点,应用程序可以在这里安装一个监视子程序,从而在系统的消息流到达目的窗口的过程前监控它们。通过这种方式,钩子能够实现各种自定义的功能和处理逻辑
- globalhook
- keyboardhook
- mousehook
- keyboardsimulator
- mousesimulator
globalhook
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
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
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
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
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
}
}
测试类
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;
}
}
}
} 以上就是c#钩子hook监听键盘鼠标事件实现窗体自动关闭的详细内容,更多关于c#钩子hook监听键盘鼠标事件的资料请关注代码网其它相关文章!
发表评论