Jump to content

Keyboard hook trying to send alternate keycode


Recommended Posts

I'm trying to write a script to emulate the numpad on my laptop using other keys.

I tried using _IsPressed and Send but most programs are too smart for that.

So I modified another script I had which used a keyboard hook to disable keys.

But so far I haven't had any luck returning the key I want.

I think the only problem is how I'm handling this line, I used to return 1 on this line to disable the key.

#cs ============================
    RETURN "NUMPAD0" FOR "A" KEY
#ce ============================
    If $vkCode = 0x41 Then Return 0x60
;   ============================

Here's what I have:

#include <WinAPI.au3>

Global  $sHexKeys, $sMouse, $sString, $hHookKeyboard, $pStub_KeyProc

HotKeySet("{F3}", "ExitNow");0x72

$pStub_KeyProc = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
$hHookKeyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), _WinAPI_GetModuleHandle(0), 0)

While 1
    Sleep(10)
WEnd

Func ExitNow()
    Exit
EndFunc
Func OnAutoITExit()
    DllCallbackFree($pStub_KeyProc)
    _WinAPI_UnhookWindowsHookEx($hHookKeyboard)
EndFunc

Func _KeyProc($nCode, $wParam, $lParam)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
    Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam)
    Local $vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode")
#cs ============================
    RETURN "NUMPAD0" FOR "A" KEY
#ce ============================
    If $vkCode = 0x41 Then Return 0x60
;   ============================
    _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
EndFunc

Thanks,

Kenny

Edited by ken82m

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

anyone have any ideas? :)

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

Well the problem is this code must be intercepting these things at another layer.

It's a hot key in the app and it won't take a Send().

I was hoping that since I can stop keycodes from getting through.

I could somehow change $vkCode to something else and then let windows process it as if it was coming from the keyboard.

Edited by ken82m

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

It seems like you can't since the lParam is a pointer which is valid only within the context of your process and nothing more or I'm wrong. Otherwise, you could do something like:

;...
$iScanCode = _MapVirtualKey(0x60, 0)
$iExtended = BitOR(DllStructGetData($KBDLLHOOKSTRUCT, 'flags'), 1) ; Numpad 0 is considered extended key.
$iExtended = BitAND($iExtended, BitNOT(0x10)) ; Not injected.
DllStructSetData($KBDLLHOOKSTRUCT, 'scanCode', $iScanCode)
DllStructSetData($KBDLLHOOKSTRUCT, 'vkCode', 0x60)
DllStructSetData($KBDLLHOOKSTRUCT, 'flags', $iExtended)
; $lParam = DllStructGetPtr($KBDLLHOOKSTRUCT) ; Not necessary.
; and pass it to the rest of the chain.

But ofcourse it's not correct or at least it seems so.

In my opinion, you should use Send or send a broadcast message WM_HOTKEY and return non-zero value instead of calling the rest of the chain. Also note that it seems like if another program register a hook procedure after you've registered yours, the system is gonna call the other procedure (not yours) first.

Link to comment
Share on other sites

See how it is done.

#include <WinAPI.au3>
#Include <WindowsConstants.au3>

Global $sHexKeys, $sMouse, $sString, $hHookKeyboard, $pStub_KeyProc

HotKeySet("{F3}", "ExitNow") ;0x72

$pStub_KeyProc = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
$hHookKeyboard = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pStub_KeyProc), _WinAPI_GetModuleHandle(0), 0)

While 1
    Sleep(10)
WEnd

Func ExitNow()
    Exit
EndFunc   ;==>ExitNow
Func OnAutoITExit()
    DllCallbackFree($pStub_KeyProc)
    _WinAPI_UnhookWindowsHookEx($hHookKeyboard)
EndFunc   ;==>OnAutoITExit

Func _KeyProc($nCode, $wParam, $lParam)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
    Local $KBDLLHOOKSTRUCT = DllStructCreate("dword vkCode;dword scanCode;dword flags;dword time;ptr dwExtraInfo", $lParam)
    Local $vkCode = DllStructGetData($KBDLLHOOKSTRUCT, "vkCode")
    Switch $wParam
        Case $WM_KEYDOWN, $WM_SYSKEYDOWN
            If $vkCode = 0x41 Then
                _keybd_event(0x60, 0)
                Return -1
            EndIf
    EndSwitch
    Return _WinAPI_CallNextHookEx($hHookKeyboard, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func _keybd_event($vkCode, $Flag)
    DllCall('user32.dll', 'int', 'keybd_event', 'int', $vkCode, 'int', 0, 'int', $Flag, 'ptr', 0)
EndFunc; _keybd_event
Link to comment
Share on other sites

nice, works perfect

Thanks guys :)

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

hmm that could get complicated. 7, 8 and 9 are numpad 7, 8 and 9 when my num lock is on.

It seems to work fine this way anyway, the app picks it up no problem.

What I was doing was mapping the standard 0-9 keys to numpad 0-9 keys.

I can't count how many times this would have helped me.

Posted it in examples, gave you full credit of course :)

http://www.autoitscript.com/forum/index.php?showtopic=95106

Thanks again

Kenny

Edited by ken82m

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

One more thing, a little bonus, I think it's an easy one. Well for you anyway lol :)

How can I detect the ALT key I know it's in one of the other parameters but I don't remember which one or how to read it exactly.

I figure if I can read ALT+1 and return NUMPAD1 instead then I can have the full use of my keys and still enable the emulation.

As it is I can't access the Shift functions on my keys while it's running.

Thanks,

Kenny

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

#include <WinAPI.au3>
#include <WindowsConstants.au3>
HotKeySet('{F3}', '_EXIT')

Dim $hHook, $hFunc
Dim $pFunc

$hFunc = DllCallbackRegister('_KeyboardHook', 'long', 'int;wparam;lparam')
$pFunc = DllCallbackGetPtr($hFunc)

$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, $pFunc, _WinAPI_GetModuleHandle(0))

While 1
    Sleep(15)
WEnd


Func _EXIT()
    Exit
EndFunc

Func OnAutoItExit()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hFunc)
EndFunc

Func _KeyboardHook($iCode, $iwParam, $ilParam)
    Local $tKHS = DllStructCreate($tagKBDLLHOOKSTRUCT, $ilParam)
    Local $vkCode, $iScanCode
    
    If $iCode > -1 Then
        $vkCode = DllStructGetData($tKHS, 'vkCode')
        If $iwParam = $WM_SYSKEYUP Then
            Switch $vkCode
                Case 0x30 To 0x39
                    ConsoleWrite($vkCode & @LF)
                    _keybd_event(0x12, 2)  ; 2 = KEYEVENTF_KEYUP
                    _keybd_event($vkCode+0x30, 0)
                    Return 1
            EndSwitch
        EndIf
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc


Func _keybd_event($bvkCode, $Flag)
    DllCall('user32.dll', 'int', 'keybd_event', 'byte', $bvkCode, 'byte', 0, 'uint', $Flag, 'ptr', 0)
EndFunc; _keybd_event

Edited by Authenticity
Link to comment
Share on other sites

Beautiful Thanks :)

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

  • 1 month later...

Hi im trying to get @ and other SC special character combinations plz help me to slove

#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $hHook, $hStub_KeyProc

    $hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
    $hmod = _WinAPI_GetModuleHandle(0)
    $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)


While 1
    Sleep(250)
WEnd



Func _KeyProc($nCode, $wParam, $lParam)
    Local $tKEYHOOKS
    $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    If $nCode < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndIf
    Local $vkCode = DllStructGetData($tKEYHOOKS, "vkCode")


    If $wParam = $WM_KEYDOWN Then

If $vkCode = 0xA1 AND $vkCode = 0x32 Then ConsoleWrite('@')
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc  ;==>_KeyProc




Func OnAutoItExit()

    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_KeyProc)
    MsgBox(0, "Exit", "Bye!")
EndFunc  ;==>_OnExit
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...