Jump to content
Sign in to follow this  
iCode

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

Recommended Posts

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.
 
LAST UPDATED: 21-SEP-2014

#include-once
; #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
    EndIf
    $sRet = __ReleaseKeys($aReleaseKeys, $iTimeout, $hUser32Dll)
    If Not @error Then
        Send($sSendKeys)
        Sleep($iDelay)
        $sRet = __ReleaseKeys($aReleaseKeys, $iTimeout, $hUser32Dll)
    EndIf
    If $bCloseDll Then DllClose("user32.dll")
    If $sRet Then Return SetError(1, 0, $sRet)
    Return 1
EndFunc

; #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
            Do
                Sleep(100)
                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
        EndIf
    Next
EndFunc

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

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

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

_SendEx("{A}")

Would just send the key a?

Edited by Srex

Share this post


Link to post
Share on other sites

the format is the same as Send()


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

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.


UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_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: 22/04/2018

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  

  • Similar Content

    • By XinYoung
      Hello all!   I'm stuck at a seemingly simple part of my script. Using IE, I'm filling out a web form that involves clicking a "Browse" button and selecting a file. Once the file explorer dialog opens, however, I am unable to control it.
      I have a string, which is the name of the file I want, and I'm trying to insert it into the 'File name:' text box in the dialog (which already has focus), but it doesn't get inserted. I've tried ClipPut and Send. 

      What's even more concerning is, when I close the dialog, the string is then pasted into the very next window that has focus, which is often SciTE. It's like that Browse's file open dialog halts all processes. Once it's closed, the script continues.
      ;~ Open a IE window and navigate to the login page. Global $oIE = _IECreate($urlBBLogin) _IELoadWait($oIE) ;~ Recognize the form on this page (login input boxes). Local $oForm = _IEFormGetObjByName($oIE, "login") Local $oTextLogin = _IEFormElementGetObjByName($oForm, "user_id") Local $oTextPass = _IEFormElementGetObjByName($oForm, "password") ;~ Enter the Automation user credentials into the form. _IEFormElementSetValue($oTextLogin, $bbUsername) _IEFormElementSetValue($oTextPass, $bbPassword) ;~ Click the Login button. _IEFormSubmit($oForm) _IELoadWait($oIE) ;~ Navigate to the feedfile upload page. _IENavigate($oIE, $urlUpload) _IELoadWait($oIE) ;~ Click the Browse button Local $Browse = _IEGetObjById($oIE, "feedFile_chooseLocalFile") _IEAction($Browse, "Click") Local $Browse = WinWait("Choose File to Upload") ;~ Open the file we created. WinActivate($Browse) Send($finalFile) Has anyone else experienced this problem? Any ideas to get around it? Am I approaching this the wrong way?
      Any support is greatly appreciated.
      Thank you.
    • By Rhidlor
      I was wondering if there was a library or something which provides the capability to Send() to inactive windows, and I know what you're thinking, I could just use ControlSend(); the reason I can't use that in this situation is because I need to hold down keys for specific prolonged periods of time. Also activating the window, Send()ing then de-activating the window isn't really an option here, I need the target window to always be in the background. I've looked around the forums for an adequate amount of time and didn't find anything useful, perhaps because the threads were all 10 years old, nevertheless, if anyone has any suggestions they would be greatly appreciated.
      Thanks!
    • By ternal
      Hi,
      The FAQ proposed as a solution to keys getting stuck  to do this command
      ControlSend("", "", "", "text", 0) However this sends "text" to the last active control if I am not mistaken.I have tried this with
      controlsend("", "", "", "{altup}{shiftup}{ctrlup}", 0) This is already a lot better but still fails 1/10
      I cannot allow the script to send "text" to the last active control, and its a bit silly to let it send to somewhere where its harmless no?
      Are there any other methods of unstucking keys?
    • By Fortitude
      Hello!
      I have made a program, that opens a folder, and then store the path ("C:\programFiles\etc") in a variable.
      Then i need to open the command panel as administrator, and write  in the stored path, and some other text.

      Can i somehow instantly copypaste the text i needed, instead of writing in the command panel with the Send commands?
       
      #RequireAdmin #include <MsgBoxConstants.au3> Global Const $sMessage = "Select a folder" ; Display an open dialog to select a file. Global $sFileSelectFolder = FileSelectFolder($sMessage, "") If @error Then MsgBox($MB_SYSTEMMODAL, "", "Nem választottál ki mappát!") Exit EndIf Global $Tiff_path = $sFileSelectFolder & "\TiffChecker_2_32" FileCopy( "C:\TiffChecker_2_32.exe" , $sFileSelectFolder) $CMD = $Tiff_path & " " & $sFileSelectFolder & " /s/d" Run("C:\WINDOWS\system32\cmd.exe") WinWaitActive("C:\WINDOWS\system32\cmd.exe") Send($CMD) Sleep(1000) Send("{ENTER}") sleep(1000) MsgBox(0,"Press OK", "Press OK to continue") FileCopy("C:\Tiffchecker.txt", $sFileSelectFolder) Also, how do i close the command panel, when the program is finished? (usually its under 1 second, so after the send i just put a Sleep function there)
    • By Docfxit
      I would like to know if there is a way to make the send cmd send characters when using
      Graphical AutoIt Debugger By Stumpii,
      If Not WinActive("Setup - UltraVNC","Setup is preparing to install") Then WinActivate("Setup - UltraVNC","Setup is preparing to install") WinWaitActive("Setup - UltraVNC","Setup is preparing to install") Send("{ALTDOWN}f{ALTUP}") ;Finish The debugger when using step mode will execute the Send cmd line but the window doesn't receive the input.
      Thanks,
      Docfxit
×
×
  • Create New...