[转]VSTO Office二次开发应用程序键盘鼠标钩子
可能在使用VSTO技術(shù)對(duì)Office的相關(guān)程序進(jìn)行操作時(shí),會(huì)碰到用程序去控制一些快捷鍵的操作,可以對(duì)鍵盤進(jìn)行掛鉤,此時(shí)使用P/Invoke函數(shù)實(shí)現(xiàn)。
原文鏈接:《VSTO應(yīng)用程序中加入鍵盤鉤子》 http://www.cnblogs.com/2018/archive/2010/12/01/1893891.html
原文如下:
在VSTO應(yīng)用程序中有時(shí)為了處理一些快捷按鍵操作等實(shí)現(xiàn)一些特殊的功能,此時(shí)需要對(duì)鍵盤進(jìn)行掛鉤,此時(shí)使用P/Invoke函數(shù)實(shí)現(xiàn),參考如下:
VSTO加載和卸載時(shí)進(jìn)行鉤子的初始化和卸載
注意對(duì)于命名空間的引入,在程序中Keys.Z,Keys.Alt可以改為你想要控制的按鍵鍵盤,可以是是單一按鍵也可以是組合鍵。當(dāng)然,也可以捕獲復(fù)制、粘貼、撤銷等等組合快捷鍵。
對(duì)于鍵盤、鼠標(biāo)鉤子的處理:《C#鼠標(biāo)鍵盤鉤子》http://blog.csdn.net/wangyong0921/article/details/8262631
對(duì)于鍵盤鉤子的另一種處理:
View Code using System;using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms;namespace ICS.Common {/// <summary> /// 這個(gè)類可以讓你得到一個(gè)在運(yùn)行中程序的所有鍵盤或鼠標(biāo)事件 /// 并且引發(fā)一個(gè)帶KeyEventArgs參數(shù)的.NET事件以便你很容易使用這些信息 /// </summary>public class KeyBordHook{private const int WM_KEYDOWN = 0x100;private const int WM_KEYUP = 0x101;private const int WM_SYSKEYDOWN = 0x104;private const int WM_SYSKEYUP = 0x105;//全局的事件 public event KeyEventHandler OnKeyDownEvent;public event KeyEventHandler OnKeyUpEvent;public event KeyPressEventHandler OnKeyPressEvent;static int hKeyboardHook = 0; //鍵盤鉤子句柄 //鼠標(biāo)常量 public const int WH_KEYBOARD_LL = 13; //keyboard hook constant HookProc KeyboardHookProcedure; //聲明鍵盤鉤子事件類型. //聲明鍵盤鉤子的封送結(jié)構(gòu)類型 [StructLayout(LayoutKind.Sequential)]public class KeyboardHookStruct{public int vkCode; //表示一個(gè)在1到254間的虛似鍵盤碼 public int scanCode; //表示硬件掃描碼 public int flags;public int time;public int dwExtraInfo;}//裝置鉤子的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);//卸下鉤子的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook);//下一個(gè)鉤掛的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);[DllImport("user32 ")]public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);[DllImport("user32 ")]public static extern int GetKeyboardState(byte[] pbKeyState);public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);/// <summary> /// 墨認(rèn)的構(gòu)造函數(shù)構(gòu)造當(dāng)前類的實(shí)例并自動(dòng)的運(yùn)行起來. /// </summary> public KeyBordHook(){Start();}//析構(gòu)函數(shù). ~KeyBordHook(){Stop();}public void Start(){//安裝鍵盤鉤子 if (hKeyboardHook == 0){KeyboardHookProcedure = new HookProc(KeyboardHookProc);hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().ManifestModule), 0);if (hKeyboardHook == 0){Stop();throw new Exception("SetWindowsHookEx ist failed. ");}}}public void Stop(){bool retKeyboard = true;if (hKeyboardHook != 0){retKeyboard = UnhookWindowsHookEx(hKeyboardHook);hKeyboardHook = 0;}//如果卸下鉤子失敗 if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed. ");}private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam){if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null)){KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));//引發(fā)OnKeyDownEvent if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);OnKeyDownEvent(this, e);}//引發(fā)OnKeyPressEvent if (OnKeyPressEvent != null && wParam == WM_KEYDOWN){byte[] keyState = new byte[256];GetKeyboardState(keyState);byte[] inBuffer = new byte[2];if (ToAscii(MyKeyboardHookStruct.vkCode,MyKeyboardHookStruct.scanCode,keyState,inBuffer,MyKeyboardHookStruct.flags) == 1){KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);OnKeyPressEvent(this, e);}}//引發(fā)OnKeyUpEvent if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);OnKeyUpEvent(this, e);}}return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);}}對(duì)于鼠標(biāo)鉤子的處理:
using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms;namespace PowerPointTest {/// <summary> /// 這個(gè)類可以讓你得到一個(gè)在運(yùn)行中程序的所有鼠標(biāo)事件 /// 并且引發(fā)一個(gè)帶MouseEventArgs參數(shù)的.NET鼠標(biāo)事件以便你很容易使用這些信息 /// </summary> public class MouseHook{private const int WM_MOUSEMOVE = 0x200;private const int WM_LBUTTONDOWN = 0x201;private const int WM_RBUTTONDOWN = 0x204;private const int WM_MBUTTONDOWN = 0x207;private const int WM_LBUTTONUP = 0x202;private const int WM_RBUTTONUP = 0x205;private const int WM_MBUTTONUP = 0x208;private const int WM_LBUTTONDBLCLK = 0x203;private const int WM_RBUTTONDBLCLK = 0x206;private const int WM_MBUTTONDBLCLK = 0x209;//全局的事件 public event MouseEventHandler OnMouseActivity;static int hMouseHook = 0; //鼠標(biāo)鉤子句柄 //鼠標(biāo)常量 public const int WH_MOUSE_LL = 14; //mouse hook constant HookProc MouseHookProcedure; //聲明鼠標(biāo)鉤子事件類型. //聲明一個(gè)Point的封送類型 [StructLayout(LayoutKind.Sequential)]public class POINT{public int x;public int y;}//聲明鼠標(biāo)鉤子的封送結(jié)構(gòu)類型 [StructLayout(LayoutKind.Sequential)]public class MouseHookStruct{public POINT pt;public int hWnd;public int wHitTestCode;public int dwExtraInfo;}//裝置鉤子的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);//卸下鉤子的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern bool UnhookWindowsHookEx(int idHook); //下一個(gè)鉤掛的函數(shù) [DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);/// <summary> /// 墨認(rèn)的構(gòu)造函數(shù)構(gòu)造當(dāng)前類的實(shí)例. /// </summary> public MouseHook(){//Start(); }//析構(gòu)函數(shù). ~MouseHook(){Stop();}public void Start(){//安裝鼠標(biāo)鉤子 if (hMouseHook == 0){//生成一個(gè)HookProc的實(shí)例. MouseHookProcedure = new HookProc(MouseHookProc);hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);//如果裝置失敗停止鉤子 if (hMouseHook == 0){Stop();throw new Exception("SetWindowsHookEx failed. ");}}}public void Stop(){bool retMouse = true;if (hMouseHook != 0){retMouse = UnhookWindowsHookEx(hMouseHook);hMouseHook = 0;}//如果卸下鉤子失敗 if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed. ");}private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam){//如果正常運(yùn)行并且用戶要監(jiān)聽鼠標(biāo)的消息 if ((nCode >= 0) && (OnMouseActivity != null)){MouseButtons button = MouseButtons.None;int clickCount = 0;switch (wParam){case WM_LBUTTONDOWN: button = MouseButtons.Left; clickCount = 1; break;case WM_LBUTTONUP: button = MouseButtons.Left; clickCount = 1; break;case WM_LBUTTONDBLCLK: button = MouseButtons.Left; clickCount = 2; break;case WM_RBUTTONDOWN: button = MouseButtons.Right; clickCount = 1; break;case WM_RBUTTONUP: button = MouseButtons.Right; clickCount = 1; break;case WM_RBUTTONDBLCLK: button = MouseButtons.Right; clickCount = 2; break;}//從回調(diào)函數(shù)中得到鼠標(biāo)的信息 MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);OnMouseActivity(this, e);}return CallNextHookEx(hMouseHook, nCode, wParam, lParam);}} }?
轉(zhuǎn)載于:https://www.cnblogs.com/SanMaoSpace/archive/2013/02/20/2919337.html
總結(jié)
以上是生活随笔為你收集整理的[转]VSTO Office二次开发应用程序键盘鼠标钩子的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库和实例
- 下一篇: ligerui layout拖动中间分隔