I have written a "using the underlying keyboard hook shielding any button" and put it on my blog. The "shield" is changed to "interception" in the topic of this article, which is obviously stronger than the previous version. For the previously written DLL, there is a place that is not ideal, it can only be shielded. If you want to add some "little actions" before shield, you can only modify the DLL, add code to the LowlevelKeyboardProc function, implement new features. But this is obviously not flexible enough, and such a DLL does not have a generality. So I naturally thought of the callback, there's a lot of APIs that need a callback function in Windows, and we can certainly write such an API. The advantage of doing this is to leave enough interfaces to the DLL call program. At this time, the DLL is like a valve. We don't care about the button, just intercept the button message we care, and then further process, and these processing code writes in the callback function of the DLL call program. This is the most ideal.
Relative to the previous version, the modified DLL source code is as follows:
/ ************************************************** ****************** /
/ * File name: Maskkey.cpp * /
/ * * /
/ * Function: Standard DLL ---- Using the underlying keyboard hook to implement intercept keyboard any button * /
/ * * /
/ * Author: Lu Peipei (goodname008) Time: 2005.1.18 * /
/ * * /
/ * Blog: http://blog.9cbs.net/goodname008 * /
/ ************************************************** ****************** /
// Export function list
// StartmaskKey
// stopmaskkey
#define _win32_winnt 0x0500 // Set the system version, make sure you can use the underlying keyboard hook
#include "windows.h"
// Tune function pointer
Typedef Bool (Callback * lpfnkeyboardproc) (WPARAM, KBDLLHOOKSTRUCT *);
// Global variable
LPDWORD G_LPDWVIRTUALKEY = NULL; / / KeyCode array pointer
INT g_nlength = 0; // KeyCode array size
BOOL g_bdisablekeyboard = false; // Whether to block the entire keyboard
Hinstance g_hinstance = null; // module instance handle
HHOOK G_HHOOK = NULL; // Hook handle
LPFNKEYBOARDPROC G_LPFNKEYBOARDPROC; // Keyboard hook callback function pointer // DLL entry function
Bool Apientry Dllmain (Handle Hmodule, DWORD UL_REASON_FOR_CALL, LPVOID LPRESERVED)
{
/ / Save Module Instance Handle
G_HINSTANCE = (hinstance) hmodule;
/ / Unload hook at the end of the process or thread
Switch (ul_reason_for_call)
{
Case DLL_Process_attach:
Break;
Case DLL_THREAD_ATTACH:
Break;
Case DLL_PROCESS_DETACH:
Case DLL_THREAD_DETACH:
Free (g_lpdwvirtualkey);
IF (g_hhook! = null) UnHookWindowsHookex (g_hhook);
Break;
}
Return True;
}
// Bottom keyboard hook function
LResult Callback LowlevelKeyboardProc (int Ncode, WPARAM WPARAM, LPARAM LPARAM)
{
// Intercept some buttons of the keyboard, if g_bdisablekeyboard is true, intercept the entire keyboard button
IF (ncode> = hc_action)
{
KBDLLHOOKSTRUCT * PSTRUCT = (KBDLLHOKSTRUCT *) LPARAM;
IF (g_bdisableKeyboard)
IF (g_lpfnkeyboardproc (wparam, pstruct))
Return CallNexthookex (G_HHHOOK, NCODE, WPARAM, LPARAM);
Else
Return True;
LPDWORD TMPVIRTUALKEY = G_LPDWVIRTUALKEY;
For (int i = 0; i { IF (pstruct-> vkcode == * tmpvirtualkey ) IF (g_lpfnkeyboardproc (wparam, pstruct)) Return CallNexthookex (G_HHHOOK, NCODE, WPARAM, LPARAM); Else Return True; } } // Call the next hook in the system Return CallNexthookex (G_HHHOOK, NCODE, WPARAM, LPARAM); } / ************************************************** ****************** / / * Start blocking keyboard button * / / * * / / * Parameters: * / / * LPDWVIRTUALKEY KeyCode array pointer * / / * NLENGTH Keycode array size * / / * BDISABLEKEYBOARD is intercepted for the entire keyboard * / / * * // * Return value: true success, FALSE failed * / / ************************************************** ****************** / Bool WinApi StartmaskKey (LPDWORD LPDWVIRTUALKEY, INT NLENGTH, LPFNKEYBOARDPROC LPFNKEYBOARDPROC, BOOL BDISABLEKEYBOARD = FALSE { // Return False if the keyboard hook has been installed IF (g_hhook! = null || NLENGTH == 0) Return False; // Save the keycode array from the user in the global variable g_lpdwvirtualkey = (lpdword) Malloc (Sizeof (DWORD) * NLENGTH); LPDWORD TMPVIRTUALKEY = G_LPDWVIRTUALKEY; For (int i = 0; i { * TMPVIRTUALKEY = * LPDWVIRTUALKEY ; } g_nlength = NLENGTH; g_bdisableKeyboard = bdisableKeyboard; g_lpfnkeyboardproc = lpfnkeyboardproc; / / Install the underlying keyboard hook g_hook = setwindowshookex (wh_keyboard_ll, loewlerybookardproc, g_hinstance, null); IF (g_hhook == null) Return False; Return True; } / ************************************************** ****************** / / * Stop blocking keyboard button * / / * * / / * Parameters: (none) * / / * * / / * Return value: true success, False failed * / / ************************************************** ****************** / Bool WinApi StopmaskKey () { // Uninstall the hook IF (unhookwindowshookex (g_hhook) == 0) Return False; g_hook = NULL; Return True; } Of course, the maskkey.h header is also added: // Tune function pointer Typedef Bool (Callback * lpfnkeyboardproc) (WPARAM, KBDLLHOOKSTRUCT *); The following is an example in which the call is called: (two Dialog member functions, corresponding two buttons, plus a callback function) // Global keyboard hook callback function // Parameter: Action identifies the keyboard message (press, bounce), Keystruct contains button information Bool Callback KeyboardProc (WParam Action, KBDLLHOOKSTRUCT * PKEYSTRUCT) { // Judgment button action Switch (action) { Case WM_KeyDown: Break; Case WM_KEYUP: Break; Case WM_SYSKEYDOWN: Break; Case WM_SYSKEYUP: Break; } / / Return true to continue to pass the button message / / Return false indicates the end button message delivery Return False; } Void CMaskKeyAppdlg :: onstartmaskKey () { // Shield a, b, c, upper, lower left, left, right and two WIN keys DWORD DWVK [] = {'A', 'B', 'C', VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_LWIN, VK_RWIN}; INT NLENGTH = SIZEOF (DWVK) / SizeOf (DWORD); StartmaskKey (DWVK, NLENGTH, KeyboardProc); } Void CMaskKeyAppdlg :: onstopmaskKey () { STOPMASKKEY (); } Oh, is this exciting to see you here? ! StartmaskKey adds a parameter, a function pointer, which is our very familiar callback function. The StartmaskKey function in the DLL is saved in the G_LPFNKEYBOARDPROC variable, and once the button to be intercepted in LowlevelKeyboardProc, the callback function is transferred through the function pointer, and the control is completely returned to the DLL call program. Further processing by the callback function keyboardProc (play a small piece of music, or do something interesting program, or restart the shutdown. Hey, with you.: D), the Action parameter is used to identify keyboard messages (press) Or bounce down), the pkeystruct parameter contains rich buttons, in fact, the system is transmitted to LowlevelKeyboardProc, and I passed it to KeyboardProc, huh, huh. The most important thing is the return value of the callback function, which will determine the fate of this button. From the process of the LowlevelKeyboardProc function in the DLL, if the return value of the callback function KeyboardProc is true, the button message continues to pass to the next hook in the system; if false is the passage of the button message, this The effect of the interception button will be blocked. People with VB may be a bit impatient, don't worry, the last article gives the VB called routine, which certain cannot be lacking. Here is an example in which you call in VB: (2 CommandButton added on the form, and renamed cmdstartmask and cmdstopmask, respectively) Option expedition Private Declare Function StartMaskKey Lib "MaskKey" (lpdwVirtualKey As Long, ByVal nLength As Long, ByVal lpfnKeyboarProc As Long, Optional ByVal bDisableKeyboard As Boolean = False) As LongPrivate Declare Function StopMaskKey Lib "MaskKey" () As Long Private sub cmdstartmask_click () 'Shield a, b, c, upper, bottom, left, right and two WIN keys DIM Key (8) as long Key (0) = VBKEYA Key (1) = VBKEYB Key (2) = VBEYC Key (3) = VBEYLEFT Key (4) = VBEYRIGHT Key (5) = VBEYUP Key (6) = VBKEYDOWN Key (7) = & H5B 'left WIN button Key (8) = & h 5C 'WIN button on the right StartmaskKey Key (0), Ubound (Key) 1, Addressof KeyboardProc End Sub Private sub cmdstopmask_click () StopmaskKey End Sub The code of the form module is almost the same as the previous routine, just adding a parameter when calling the StartmaskKey function: Addressof keyboardproc. People who have used the callback function in VB will never be unfamiliar with this thing, and addressof is a one-dimensional operator, and then a function name, its function is a pointer to the specified function. However, it must be noted that the reconvection function (KEYBOARDPROC in this case) must be written in the standard module of the VB, as follows: Option expedition Private const wm_keydown = & h100 Private const wm_keyup = & h101 Private const wm_syskeydown = & h104 Private const wm_syskeyup = & h105 Public Type KBDLLHOOKSTRUCT Vkcode as long 'virtual button (1--254) Scancode as long 'hardware button scan code Flags as long 'Flags Time as long 'message timestamp DWEXTRAINFO AS long 'extra information End Type Public enum keyaction Action_keydown = WM_KeyDown Action_keyup = WM_Keyup Action_syskeydown = WM_SYSKEYDOWN Action_syskeyup = WM_SYSKEYUP END ENUM 'Global keyboard hook callback function 'Parameters: Action identifies the keyboard message (press, bounce up), Keystruct contains button information Public Function KeyboardProc (Byval Action As KeyAction, Keystruct As Kbdllhookstruct) AS Booleanselect Case Action Case action_keydown Debug.print Keystruct.vkcode, "Press the keyboard button" CASE ACTION_KEYUP Debug.print Keystruct.vkcode, "Bounce Keyboard Buttons" Case action_syskeydown Case action_syskeyup End SELECT 'Return true indicates that the button message continues to pass 'Return False indicates the end button message delivery KeyboardProc = FALSE END FUNCTION And the VC version of the call routine is similar, just translate syntax into VB, this VB standard module is the taste of the MFC message mapping function? ! : D To note that the VB's callback function must be written in a standard module. The careful person may also find that I made a small hand feet on the Action parameters, it was changed to an enumeration type, which is mainly for easy understanding. OK, it's going to write so much, about the content of the global keyboard hook, I also want to tell a paragraph. With VC written DLL, VB can also easily implement global keyboard hooks. Of course, this is not limited to the keyboard hook, which can achieve any type of hook using this method. Download address of DLL source code and VC and VB call routines: http://9cbsgoodname008.51.net/maskkeycb.zip * ------------------------------------------- * * Please inform the author and indicate the source, 9CBS welcomes you! * * Author: Lu Peipei (goodname008) * * Email: GoodName008@163.com * * Column: http://blog.9cbs.net/goodname008 * * ------------------------------------------- *