Jump to content

GetKeyboardState


 Share

Recommended Posts

Hi,

The program I am trying to build an autoit script for blocks both ControlSend and Send functions. Someone recommended I look up GetKeyboardState, so I did. It looks like I need to use some dll controls which I am not too familiar with.

Is there any examples out there for GetKeyboardState + autoit used to send keystrokes? Or if anyone could make a short little example for me to learn off. TY!

Edit: Added more info.

In my Autoit script, when you press a button on the gui it will perform a task. Like for example it well send the letter L, then wait 3 seconds, then send the letter T. Problem is that the software I am trying to make easier to use is blocking them for some reason. So is there any alternative to ControlSend and Send? A DLL method or anything..?

Edited by MirnesC2
Link to comment
Share on other sites

That function gets the current state of all keys - and even then it is only sometimes right since it is affected by message queues.

For blocking, what you probably want is something like Yashied's Problem with that UDF is that it will be removed from the callback chain during a lock-workstation screen prompt (Ctrl-Alt-Del), at least in Windows 7. Its why I've had to remove it from my own code.

Link to comment
Share on other sites

The UDF contains errors.

ERROR: Opt() called with illegal argument 1: "OnExitFunc"

Global $OnHotKeyExit = Opt('OnExitFunc', 'OnHotKeyExit')

The function OnExitFunc doesn't exist in the UDF so I removed it. However, I still get an error message from the first example in his UDF comments when I press CTRL+ESC. Still same error. Also I don't really understand how this could help? I need an alternative to ControlSend and Send, I don't have any issues with the HostKeySet function.

In my Autoit script, when you press a button on the gui it will perform a task. Like for example it well send the letter L, then wait 3 seconds, then send the letter T. Problem is that the software I am trying to make easier to use is blocking them for some reason. So is there any alternative to ControlSend and Send? A DLL method or anything..?

Edited by MirnesC2
Link to comment
Share on other sites

Here is an example I found of the GetKeyboardState function on google. It's similar to the UDF you showed me. But I still don't see how either one could help me solve my problem. =(

; #EXAMPLE 1# =======================================================================================
; Description   :       Creates GUI which will be displayed until any key is pressed.
; ===================================================================================================
$hGui = GUICreate("Example 1 - Press any key to exit...", 400, 100)
GUISetState()
$sKeyboardState = _WinAPI_GetKeyboardState(1)
While _WinAPI_GetKeyboardState(1) = $sKeyboardState
    Sleep(100)
WEnd
GUIDelete($hGui)
Sleep(500)
; #EXAMPLE 2# =======================================================================================
; Description   :       Creates GUI which will be displayed until the "A" key is pressed.
; ===================================================================================================
$hGui = GUICreate('Example 2 - Press "A" to exit...', 400, 200)
GUISetState()
$aKeyboardStateOld = _WinAPI_GetKeyboardState()
While 1
    $aKeyboardState = _WinAPI_GetKeyboardState()
    If $aKeyboardState[65] <> $aKeyboardStateOld[65] Then ExitLoop
    Sleep(100)
WEnd
GUIDelete($hGui)
Sleep(500)
; #EXAMPLE 3# =======================================================================================
; Description   :       Creates GUI which will display the [state] and [toggle] of keys A-Z.
; ===================================================================================================
$hGui   = GUICreate('Example 3 - Type...', 400, 400)
$hLabel = GUICtrlCreateLabel("", 2, 2, 396, 396)
GUISetState()
While GUIGetMsg() <> -3
    $aKeyboardState = _WinAPI_GetKeyboardState()
    $sKeys = "I" & @TAB & "CHR" & @TAB & "State" & @TAB & "Toogle" & @LF
    For $i = 65 To 90
        $sKeys &= $i & @TAB & Chr($i) & @TAB & BitAND($aKeyboardState[$i], 0xF0) & @TAB & BitAND($aKeyboardState[$i], 0x0F) & @LF
    Next
    GUICtrlSetData($hLabel, $sKeys)
    Sleep(100)
WEnd
; #FUNCTION# =======================================================================================
; Function Name :       _WinAPI_GetKeyboardState
; Description   :       Returns the status of the 256 virtual keys
; Syntax        :       _WinAPI_GetKeyboardState($iFlag=0)
; Parameters    :       Return Type:
;                           0 - Returns an array[256]
;                           1 - Returns a string
; Return values :       Return Type:
;                           Success  - Array[256] or String containing status of 256 virtual keys
;                           Failure  - False
; ===================================================================================================
Func _WinAPI_GetKeyboardState($iFlag = 0)
    Local $aDllRet, $lpKeyState = DllStructCreate("byte[256]")
    $aDllRet = DllCall("User32.dll", "int", "GetKeyboardState", "ptr", DllStructGetPtr($lpKeyState))

    If @error Then Return SetError(@error, 0, 0)
    If $aDllRet[0] = 0 Then
        Return SetError(1, 0, 0)
    Else
        Switch $iFlag
            Case 0
                Local $aReturn[256]
                For $i = 1 To 256
                    $aReturn[$i - 1] = DllStructGetData($lpKeyState, 1, $i)
                Next
                Return $aReturn
            Case Else
                Return DllStructGetData($lpKeyState, 1)
        EndSwitch
    EndIf
EndFunc   ;==>_WinAPI_GetKeyboardState
Edited by MirnesC2
Link to comment
Share on other sites

Ahh, I misread your original post.. thought you wanted to block input while your script does whatever.

Anyway, you'll have to give us more info.. what program is it that isn't receiving the keystrokes? What does the AutoIt Window Info Tool report?

AutoIt uses keyb_event to send keystrokes, which is about the lowest you can get with keystroke sending. If you have a PS/2 Keyboard port, you could use my even lower-level I/O functions to inject keystrokes, although that is a bit limited in what you can send. There's also DLL/code injection techniques, but you want to make sure you have exhausted all other methods first.

Also, very important - check that your process is working at the same elevation as the program you are sending keystrokes to.

Put #RequireAdmin at the top of your script, or if running from within SciTE or compiling, add '#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator'

Link to comment
Share on other sites

I suggest you reread my post. I told you to try changing the elevation and also asked for more info

Link to comment
Share on other sites

It's not an issue with elevation. The program receiving the keystrokes specifically blocks it, as I said before.

Goal: Send keystrokes to program.

Problem: Program blocks keystrokes from AutoIt.

You mentioned AutoIt uses keyb_event to send keystrokes. I looked up keyb_event and its a windows function. Is there any other ones I could try? Also, not sure what you mean by "lowest you can get with keystroke sending".

Link to comment
Share on other sites

  • 3 weeks later...

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...