Sign in to follow this  
Followers 0

SendEx - yet another alternative to the built-in Send function

5 posts in this topic

#1 ·  Posted (edited)

As many are aware, the standard AutoIt Send() function can leave modifier keys (usually Shift, Alt, Ctrl) in a pressed-like state. While there are at least a few alternatives that can be found on this forum, as well as one in the Wiki (which i can't find at the moment), they have all failed me at some point, leaving a modifier key "stuck". So far i have had no issues with this function however.

; #FUNCTION# ====================================================================================================================
; Name ..........: _SendEx
; Description ...: alternative to built-in Send() function which prevents modifier keys from being left in a pressed state
; Syntax ........: _SendEx($sSendKeys[, $iTimeout[, $sReleaseKeys[, $hUser32Dll]]])
; Parameters ....: $sSendKeys           - string of keys to send in Send() format
;                  $hUser32Dll          - [optional] handle to user32.dll
;                  $iTimeout            - [optional] maximum time in ms to attempt to release pressed keys (minimum = 250)
;                  $sReleaseKeys        - [optional] comma seperated string of keys to release before issuing Send() (no spaces).
;                      defaults to: Shift, Ctrl, Alt, L Win, R Win
; Return values .: Success returns 1, else sets @error to 1 and returns an error message string
; Release date ..: 25-May-2014
; Modify date ...: 21-Sep-2014
; Author ........: iCode
; Modified by ...:
; Remarks .......:
; Related .......: Send()
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _SendEx($sSendKeys, $hUser32Dll = "", $iTimeout = 2000, $sReleaseKeys = "0x10,0x11,0x12,0x5B,0x5C")
    Local $bCloseDll, $sRet
    Local $iDelay = Opt("SendKeyDelay") + Opt("SendKeyDownDelay")
    If $iDelay < 50 Then $iDelay = 50
    Local $aReleaseKeys = StringSplit($sReleaseKeys, ",")
    If @error Then Return SetError(1, 0, "Failed to create release key array")
    If $hUser32Dll <> "user32.dll" Then
        $hUser32Dll = DllOpen("user32.dll")
        If @error Then Return SetError(1, 0, "Failed to open handle to user32.dll")
        $bCloseDll = True
    $sRet = __ReleaseKeys($aReleaseKeys, $iTimeout, $hUser32Dll)
    If Not @error Then
        $sRet = __ReleaseKeys($aReleaseKeys, $iTimeout, $hUser32Dll)
    If $bCloseDll Then DllClose("user32.dll")
    If $sRet Then Return SetError(1, 0, $sRet)
    Return 1

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: __ReleaseKeys
; Description ...: release pressed keys
; Syntax ........: __ReleaseKeys(Byref $aReleaseKeys, $iTimeout, $hUser32Dll)
; Parameters ....: $aReleaseKeys        - [in/out] An array of unknowns.
;                  $iTimeout            - An integer value.
;                  $hUser32Dll          - A handle value.
; Return values .: None
; Author ........: iCode
; Modified ......: 25-May-2014
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func __ReleaseKeys(ByRef $aReleaseKeys, $iTimeout, $hUser32Dll)
    If $iTimeout < 50 Then $iTimeout = 250
    Local $aRet, $hTimer = TimerInit()
    For $i = 0 To UBound($aReleaseKeys) - 1
        $aRet = DllCall($hUser32Dll, "short", "GetAsyncKeyState", "int", $aReleaseKeys[$i])
        If @error Then Return SetError(1, 0, "Dll call GetAsyncKeyState failed with key: " & $aReleaseKeys[$i])
        If BitAND($aRet[0], 0x8000) <> 0 Then
                DllCall($hUser32Dll, "int", "keybd_event", "int", $aReleaseKeys[$i], "int", 0, "long", 2, "long", 0)
                If @error Then Return SetError(1, 0, "Dll call keybd_event failed with key: " & $aReleaseKeys[$i])
                $aRet = DllCall($hUser32Dll, "short", "GetAsyncKeyState", "int", $aReleaseKeys[$i])
                If TimerDiff($hTimer) >= $iTimeout Then Return SetError(1, 0, "Time out limit reached")
            Until BitAND($aRet[0], 0x8000) = 0

Change log...

29-JUN-2014 - changed the order of the parameters for _SendEx, moving $sReleaseKeys to the last position

21-SEP-2014 - in the interest of efficiency, i removed the StringStripWS() function - $sReleaseKeys can no longer have spaces in the string

Edited by iCode
3 people like this

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Share this post

Link to post
Share on other sites

#2 ·  Posted (edited)

Would you mind throwing a simple example?
This could be usefull :)


Would just send the key a?

Edited by Srex

Share this post

Link to post
Share on other sites

It's quite clear it's an extension of Send(). I therefore see no reason to have an example if people are familiar with Send(). If not then they can look in the help file.

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post

Link to post
Share on other sites

Thanks for the 2 yeses :D
It works very well must say great work :)!

Share this post

Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • badcoder123
      By badcoder123
      Anyone know how to access the information circled in the photo?

    • AndreyS
      By AndreyS
      Dear developers and creators of the language, please explain to me why when pressing the combination Crtl + Shift + C from the 5th or the 10th time "sticks / sinks" Ctrl or Shift? And then you need to press Ctrl or Shift again to reset their triggering. I only need to use hot keys like in the example!
      The code is a small example. Its essence is that when a user in the editor selects any number and presses a combination, then it increases by 1. 
      Dim $x HotKeySet("+^c","Calc") While 1 Sleep(10000) WEnd Func Calc() Send("^c") Sleep(50) $x=ClipGet()+1 ClipPut($x) Send("^v") EndFunc I thought that in my program some kind of glitch was searching for a reason for a long time. And it turned out that apparently somehow the work of some functions used in the example is not compatible. 
      Tell me, please, what is the problem?
    • ur
      By ur
      If you observe in below code.
      Func _WinWaitActivate($title,$text,$timeout=$time_out) Logging("Waiting for "&$title&":"&$text) $dHandle = WinWait($title,$text,$timeout) if not ($dHandle = 0) then If Not WinActive($title,$text) Then WinActivate($title,$text) WinWaitActive($title,$text,$timeout) Else Logging("Timeout occured while waiting for the window...") Exit EndIf EndFunc WinActivate("Untitled - Notepad") $p = "Notallowed1!!" Send("{ENTER}{ENTER}{ENTER}{ENTER}"& $p &"{ENTER}create{SPACE}database{SPACE}"& $p &";{ENTER}") In the notepad if you observe, ! is missing in the text got.
      Is there way to get that also printed.
    • rawkhopper
      By rawkhopper
      Hello everyone,
      I have a script that is automating a piece of sluggish software.  I want to automate it with a bit of caution and I am not sure the best way to do it.  ControlSend works great most of the time.  If I have it enter 10 into a text box every once in a while it will enter 1 or 11 and then hit enter.
      To overcome this I use MouseClick to select the text I just entered and then see if it matches the string it was supposed to put in before it hits enter.  This seems to work but what I love about ControlSend is there is less room for human interaction messing it up.  
      Yes I could block input but I prefer not to do that (permissions).
      Is there a better way of doing this?  Any Help would be much appreciated.
      Anyway here is the snippet of the script in question:
      Func KVSend () WinActivate ( "Window", "" ) Local $WindowPos = WinGetPos("Window", "") If $kV < 30 Then WinActivate ( "Window", "" ) ControlClick ("Window", "", 1001) ;Click in Accel Voltage box Sleep (100) ControlSend ("Window", "", 1001, $kV) ; \ kV Sleep (100) MouseMove($WindowPos[0]+130,$WindowPos[1]+75,1) MouseClick($MOUSE_CLICK_LEFT) MouseClick($MOUSE_CLICK_LEFT) Send ("^c") Local $clip = ClipGet () If $clip = $kV Then ControlSend ("Window", "", 1001, "{ENTER}") ;Hit ENTER if value is correct Sleep (100) ControlClick ("Window", "", 1518) ;Lens Clear Else Send ("{BACKSPACE}") KVSend() ; If value is incorrect try again EndIf EndIf  
    • spuuunit
      By spuuunit
      This is what I'm trying to do: In Firefox, if you hold down CTRL + C for about 200ms, then press CTRL + T. This is my code:
      While WinActive(" - Mozilla Firefox") If _IsPressed("A2", $hDLL) And _IsPressed("43", $hDLL) Then $timer = TimerInit() While _IsPressed("A2", $hDLL) And _IsPressed("43", $hDLL) Sleep(10) $diff = TimerDiff($timer) If $diff > 200 Then Send("^{T}") While _IsPressed("A2", $hDLL) And _IsPressed("43", $hDLL) Sleep(10) WEnd EndIf WEnd EndIf WEnd The problem is that the CTRL key gets stuck down after Send("^{T}"). I found this, but what I understand that happens when I release, and that is not what I want. The "General unstuck method" did nothing.