Gianni Posted September 22, 2014 Share Posted September 22, 2014 Running the script provided in the help file related to the "_WinAPI_SetWindowsHookEx" function, It seems that the keystrokes are retained(?) by the _KeyProc() function during the elaboration, and displayed into the InputBox only after(?) the returning from that function. I was wondering if could be possible in some way, neutralize some keys and throw them away before that them are showed in the InputBox. The purpose of this, is the possibility to use some InputBox allowing only the entering of certain chars and disallow some others. For example if I have an InputBox where must be entered an HEX number, I would allow only keystrokes from 0 to 9 and from A to F, neutralizing all others (but Tab anf CR). Thanks in advance for any suggestion here a little modified version of the script provided in the help file, that use an InputBox instead of Notepad. expandcollapse popup#include <MsgBoxConstants.au3> #include <StructureConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> Global $g_hHook, $g_hStub_KeyProc, $g_sBuffer = "" Example() Func Example() OnAutoItExitRegister("Cleanup") Local $hMod $g_hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam") $hMod = _WinAPI_GetModuleHandle(0) $g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hStub_KeyProc), $hMod) GUICreate('Test ') $Input1 = GUICtrlCreateInput("", 8, 8, 105, 21) GUISetState(@SW_SHOW) While 1 Sleep(10) WEnd EndFunc ;==>Example Func EvaluateKey($iKeycode) If (($iKeycode > 64) And ($iKeycode < 91)) _ ; a - z Or (($iKeycode > 96) And ($iKeycode < 123)) _ ; A - Z Or (($iKeycode > 47) And ($iKeycode < 58)) Then ; 0 - 9 $g_sBuffer &= Chr($iKeycode) Switch $g_sBuffer Case "Jon" ToolTip("What can you say?") Case "AutoIt" ToolTip("AutoIt Rocks") EndSwitch ElseIf ($iKeycode > 159) And ($iKeycode < 164) Then Return ElseIf ($iKeycode = 27) Then ; esc key Exit Else $g_sBuffer = "" EndIf EndFunc ;==>EvaluateKey ; =========================================================== ; callback function ; =========================================================== Func _KeyProc($nCode, $wParam, $lParam) Local $tKEYHOOKS $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) EndIf If $wParam = $WM_KEYDOWN Then EvaluateKey(DllStructGetData($tKEYHOOKS, "vkCode")) Else Local $iFlags = DllStructGetData($tKEYHOOKS, "flags") Switch $iFlags Case $LLKHF_ALTDOWN ConsoleWrite("$LLKHF_ALTDOWN" & @CRLF) Case $LLKHF_EXTENDED ConsoleWrite("$LLKHF_EXTENDED" & @CRLF) Case $LLKHF_INJECTED ConsoleWrite("$LLKHF_INJECTED" & @CRLF) Case $LLKHF_UP ConsoleWrite("$LLKHF_UP: scanCode - " & DllStructGetData($tKEYHOOKS, "scanCode") & @TAB & "vkCode - " & DllStructGetData($tKEYHOOKS, "vkCode") & @CRLF) EndSwitch EndIf Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) EndFunc ;==>_KeyProc Func Cleanup() _WinAPI_UnhookWindowsHookEx($g_hHook) DllCallbackFree($g_hStub_KeyProc) EndFunc ;==>Cleanup Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
funkey Posted September 23, 2014 Share Posted September 23, 2014 What about this: Gianni 1 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
KaFu Posted September 23, 2014 Share Posted September 23, 2014 (edited) http://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx "If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure." If $wParam = $WM_KEYDOWN Then If DllStructGetData($tKEYHOOKS, "vkCode") = 65 Then ; "a" ConsoleWrite("+ ""a"" was pressed and not passed to the program" & @CRLF) Return 1 endif Else Edited September 23, 2014 by KaFu Gianni 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Gianni Posted September 23, 2014 Author Share Posted September 23, 2014 (edited) What about this: Thanks funkey, that's an interesting link. very nice way. http://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx "If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure." If $wParam = $WM_KEYDOWN Then If DllStructGetData($tKEYHOOKS, "vkCode") = 65 Then ; "a" ConsoleWrite("+ ""a"" was pressed and not passed to the program" & @CRLF) Return 1 endif Else Tanks KaFu, after reading around, I have found that the way to "neutralize" the already typed "key" is to Return 1 instead of Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) as clearly visible also in your example. thanks again Here are also 2 more links where I got some interesting info: http://www.codeproject.com/Articles/14485/Low-level-Windows-API-hooks-from-C-to-stop-unwante '?do=embed' frameborder='0' data-embedContent>> here a working example on which I was playing. It's just a draft for experiments. (it let you select which InputBox to restrict input). expandcollapse popup#include <GUIConstantsEx.au3> ; #include <MsgBoxConstants.au3> #include <StructureConstants.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> Global $sAllowedKeys = "0123456789ABCDEF" ; <-- Allowed keys in $Input1 (for hex input) Global $g_hHook, $g_hStub_KeyProc Example() Func Example() OnAutoItExitRegister("Cleanup") Local $hMod $g_hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam") $hMod = _WinAPI_GetModuleHandle(0) $g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hStub_KeyProc), $hMod) GUICreate('Test Trap & Block keys') Global $Input1 = GUICtrlCreateInput("", 8, 8, 105, 21) $Label1 = GUICtrlCreateLabel('<--- only "0123456789ABCDEF" keys allowed here', 120, 8, 300, 21) $Input2 = GUICtrlCreateInput("", 8, 40, 105, 21) $Label2 = GUICtrlCreateLabel("<--- free input allowed here", 120, 40, 300, 21) GUISetState(@SW_SHOW) While 1 $Msg = GUIGetMsg() Switch $Msg Case $GUI_EVENT_CLOSE _Bye() EndSwitch Sleep(10) WEnd EndFunc ;==>Example Func _GuiCtrlGetFocus($hGui = "") ; Retrieves the internal handle of the control with the focus Local $InputID = ControlGetHandle($hGui, "", ControlGetFocus($hGui)) Return _ControlGetGuiID($InputID) EndFunc ;==>_GuiCtrlGetFocus Func _ControlGetGuiID($hCtrl) ; Transforms from Handle to ID Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl) If @error = 0 Then Return $Result[0] Return SetError(1, 0, '') EndFunc ;==>_ControlGetGuiID ; =========================================================== ; callback function ; =========================================================== Func _KeyProc($nCode, $wParam, $lParam) Local $tKEYHOOKS $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam) If $nCode < 0 Then ; ?? Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) ; EndIf If _GuiCtrlGetFocus() = $Input1 Then ; Check if focus is in target control If $wParam = $WM_KEYDOWN Then If StringInStr($sAllowedKeys, Chr(DllStructGetData($tKEYHOOKS, "vkCode"))) Then Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) ; key processed as usual Else Return 1 ; block that key (NEUTRALIZE THAT KEY) EndIf EndIf Else Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) EndIf EndFunc ;==>_KeyProc Func _Bye() Exit EndFunc ;==>_Bye Func Cleanup() _WinAPI_UnhookWindowsHookEx($g_hHook) DllCallbackFree($g_hStub_KeyProc) ConsoleWrite("bye bye" & @CRLF) EndFunc ;==>Cleanup Edited September 23, 2014 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now