C#实现可捕获几乎所有键盘鼠标事件的钩子类完整实例
程序员文章站
2023-11-18 12:48:40
本文实例讲述了c#实现可捕获几乎所有键盘鼠标事件的钩子类。分享给大家供大家参考,具体如下:
using system;
using system.text;...
本文实例讲述了c#实现可捕获几乎所有键盘鼠标事件的钩子类。分享给大家供大家参考,具体如下:
using system; using system.text; using system.runtime.interopservices; using system.reflection; using system.windows.forms; namespace mousekeyboardlibrary { /// <summary> /// abstract base class for mouse and keyboard hooks /// </summary> public abstract class globalhook { #region windows api code [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; } [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; protected const int wh_keyboard_ll = 13; protected const int wh_mouse = 7; protected const int wh_keyboard = 2; 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 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); intptr.zero; // were we able to sucessfully start hook? if (_handletohook != 0) { _isstarted = true; } } } 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 } }
using system; using system.text; using system.windows.forms; using system.runtime.interopservices; namespace mousekeyboardlibrary { /// <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 } }
using system; using system.text; using system.runtime.interopservices; using system.windows.forms; namespace mousekeyboardlibrary { /// <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 } }
using system; using system.text; using system.windows.forms; using system.runtime.interopservices; namespace mousekeyboardlibrary { /// <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 } }
using system; using system.text; using system.runtime.interopservices; using system.drawing; using system.windows.forms; namespace mousekeyboardlibrary { /// <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 { mousehook mousehook = new mousehook(); keyboardhook keyboardhook = new keyboardhook(); public hooktestform() { initializecomponent(); } private void testform_load(object sender, eventargs e) { 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, mousesimulator.y); } 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, e.y); } void setxylabel(int x, int y) { curxylabel.text = string.format("current mouse point: x={0}, y={1}", x, y); } void addmouseevent(string eventtype, string button, string x, string y, string delta) { listview1.items.insert(0, new listviewitem( new string[]{ eventtype, button, x, y, delta })); } void addkeyboardevent(string eventtype, string keycode, string keychar, string shift, string alt, string control) { listview2.items.insert(0, new listviewitem( new string[]{ eventtype, keycode, keychar, shift, alt, control })); } private void testform_formclosed(object sender, formclosedeventargs e) { // not necessary anymore, will stop when application exits //mousehook.stop(); //keyboardhook.stop(); } } }
更多关于c#相关内容感兴趣的读者可查看本站专题:《c#常见控件用法教程》、《winform控件用法总结》、《c#数据结构与算法教程》、《c#面向对象程序设计入门教程》及《c#程序设计之线程使用技巧总结》
希望本文所述对大家c#程序设计有所帮助。