A keyboard hook is an instruction that can monitor keyboard operation.
See this sentence is not feel actually keyboard hooks can do a lot of things.
Scene
When your program needs a global shortcut key, you can consider using keyboard hooks, such as the use of QQ shortcut keys, then how to achieve in WPF?
Of course not directly in the window form to register MouseLeftButtonDown, MouseLeftButtonUp, so that only when the program is the focus of the case to trigger,
What we have to do here is to be more powerful, that is, to get to the keyboard events in the non-focus (to secretly record the roll of the girlfriend Keylogger, of course I was joking, program Ape where have girlfriend, we only have boyfriend (⊙0⊙))
Realize
First of all, we need to use a few winapi.
//functions for installing hooks[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern intSetWindowsHookEx (intIdhook, HookProc lpfn, IntPtr hinstance,intthreadId); //function to remove hooks[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern BOOLUnhookWindowsHookEx (intIdhook); //the next hook-and-peg function[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern intCallNextHookEx (intIdhook,intNCode, Int32 WParam, IntPtr lParam);
The approximate logic is:
Install a keyboard hook and then handle the obtained keyboard message through a delegate
Organize for two classes (Winapi[win32api.class] classes and keyboard hooks [Keyboardhook] classes) as follows
Public classwin32api{ Public Const intWm_keydown =0x100; Public Const intWm_keyup =0x101; Public Const intWm_syskeydown =0x104; Public Const intWm_syskeyup =0x105; Public Const intWh_keyboard_ll = -; [StructLayout (layoutkind.sequential)]//declaring the type of marshaling structure for a keyboard hook Public classkeyboardhookstruct { Public intVkcode;//represents a virtual-like keyboard code between 1 and 254 Public intScancode;//indicates a hardware scan code Public intflags; Public intTime ; Public intdwExtraInfo; } Public Delegate intHookProc (intNCode, Int32 WParam, IntPtr lParam); //functions for installing hooks[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern intSetWindowsHookEx (intIdhook, HookProc lpfn, IntPtr hinstance,intthreadId); //function to remove hooks[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern BOOLUnhookWindowsHookEx (intIdhook); //the next hook-and-peg function[DllImport ("user32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static extern intCallNextHookEx (intIdhook,intNCode, Int32 WParam, IntPtr lParam); [DllImport ("Kernel32.dll", CharSet = CharSet.Auto, callingconvention =Callingconvention.stdcall)] Public Static externIntPtr GetModuleHandle (stringlpmodulename);}
Public classKeyboardhook {intHhook; Win32api.hookproc keyboardhookdelegate;/// <summary> ///Installing the keyboard hooks/// </summary> Public voidsethook () {keyboardhookdelegate=NewWin32api.hookproc (KEYBOARDHOOKPROC); Processmodule Cmodule=process.getcurrentprocess (). Mainmodule; varMH =Win32api.getmodulehandle (cmodule.modulename); Hhook= Win32api.setwindowshookex (Win32api.wh_keyboard_ll, Keyboardhookdelegate, MH,0); } /// <summary> ///uninstalling the keyboard hooks/// </summary> Public voidunhook () {Win32api.unhookwindowshookex (hhook); } /// <summary> ///get keyboard Messages/// </summary> /// <param name= "NCode" ></param> /// <param name= "WParam" ></param> /// <param name= "LParam" ></param> /// <returns></returns> Private intKeyboardhookproc (intNCode, Int32 WParam, IntPtr LParam) { //if the message is discarded (ncode<0 if(NCode >=0) {win32api.keyboardhookstruct Keydatafromhook= (win32api.keyboardhookstruct) marshal.ptrtostructure (LParam,typeof(win32api.keyboardhookstruct)); intKeyData =Keydatafromhook.vkcode; //Wm_keydown and WM_SYSKEYDOWN messages that will raise the Onkeydownevent event if(Onkeydownevent! =NULL&& (WParam = = Win32api.wm_keydown | | wParam = =Win32api.wm_syskeydown)) { //trigger the keyboard press event here//Keydata is the value of the keyboard, corresponding to the virtual code } //Wm_keyup and WM_SYSKEYUP messages that will raise the Onkeyupevent event if(Onkeyupevent! =NULL&& (WParam = = Win32api.wm_keyup | | wParam = =Win32api.wm_syskeyup)) { //trigger Keyboard Lift event here } } returnWin32api.callnexthookex (Hhook, NCode, WParam, LParam); }}
At that time to take in the virtual code when I actually refused, because in the next I do not know what to do with these virtual code to do, it is necessary to a conversion in WPF further to determine what key is pressed?
Finally through the blog Park <Launcher> told, in the System.Windows.Input namespace has actually encapsulated the method of conversion
namespacesystem.windows.input{//Summary://provides a static method for converting between Win32 virtual keys and WPFSystem.Windows.Input.Key enumerations. Public Static classKeyinterop {//Summary://converts the Win32 virtual key to WPFSystem.Windows.Input.Key. // //Parameters://Virtualkey://the virtual key to convert. // //return Result://The WPF key. Public StaticKey Keyfromvirtualkey (intVirtualkey); // //Summary://convert WPFSystem.Windows.Input.Key to Win32 virtual key. // //Parameters://Key://the WPF to convert. // //return Result://Win32 Virtual key. Public Static intVirtualkeyfromkey (key key); }}
Results
So we have a happy heart to get the keyboard operation record of the base friend
Keyinterop.keyfromvirtualkey (KeyData)
Nono, I just made a piano keyboard.
The code has been posted and will not provide the demo to the base friend separately
WPF uses keyboard hooks to capture the keyboard and do something that's not known ... Full instance