Jump to content

Recommended Posts

Posted (edited)

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
Posted

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.

Posted (edited)

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
Posted (edited)

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
Posted

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'

Posted (edited)

Yeah, I have a PS/2 port. Problem is that not everyone who will be using the program may have a PS/2 port as well. Why are we avoiding DLL/code injection?

Edited by MirnesC2
Posted

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

Posted

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

  • 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
  • Recently Browsing   0 members

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