rodent1

copy append etc tool

1 post in this topic

#1 ·  Posted (edited)

If you need to generate text data, this tool is for you. If you are gathering data from multiple sources and filtering it, or sorting it, this tool is for you.
Generating text data manually can be time-consuming and mind-numbing. To ease my pain in this endeavour, I created this tool.
I allows you to:
  - Gather data from multiple sources without having to paste it again and again in some editor before anything can be done to it. A user-defined string separator is used to separate the appended clipboard entries into records.
  - Or take a single line of formatted data and multiplying it by hundreds, then  incrementing its lead field. Typical use: copy a line such as 
     2015/03/23 data 1 This is a test And this is a value
    where tabs separate data fields, for example.
    Then after generating a clipboard buffer where the line is repeated 10 times, and then incrementing it, the date at the start is detected and the day/month/year date value is correctly incremented
    This value is the output, and it is then placed into the clipboard:
     2015/03/23 data 1 This is a test And this is a value
     2015/03/24 data 1 This is a test And this is a value
     2015/03/25 data 1 This is a test And this is a value
     2015/03/26 data 1 This is a test And this is a value
     2015/03/27 data 1 This is a test And this is a value
     2015/03/28 data 1 This is a test And this is a value
     2015/03/29 data 1 This is a test And this is a value
     2015/03/30 data 1 This is a test And this is a value
     2015/03/31 data 1 This is a test And this is a value
     2015/04/01 data 1 This is a test And this is a value
 
  - Or if you are tring to filter records, enter a list of strings to find in the clipboard buffer and only keep the records that contain one of the find strings, or only keep the records that don't have one of the find strings
 

This tool runs in the background and allows copying information that is scattered in documents or web pages etc to the clipboard by appending to what is already in the clipboard. To make the updated clipboard buffer more usable and separate records, a separator is used. The default separator is CRLF, but it can be changed to any user text string including CR or LF. 

Using the clipboard separator, records can be sorted as text up and down before pasting them, or you can copy a list and sort it in the clipboard before pasting it back sorted.

Use hotkeys

ctrl-alt-c to copy-append,

ctrl-alt-x to cut-append,

ctrl-alt-f to parse the clipboard text contents, and only keep the records that contain a find string

ctrl alt d, prompt for find string, then find records in clipboard that contain the string and remove them only keeping other records in clipboard
ctrl alt h, prompt for a find and a replace string, replace and update the clipboard
ctrl-alt-r to run the current text selection as a command,

ctrl-alt-F1 to display the list of commands,

ctrl-alt-arrow up or down to sort up or down the entries,

ctrl-alt-s to bring up the setup dialog, to set the separator, and other values.

ctrl-alt-q to quit.

There are a few more commands that I use to easily generate large amounts of testing data. ctrl-alt-g copies what is selected and prompts the user for the number of times the selection should be repeated. Then if each record starts with a number, or a date with format yyyy/mm/dd, or time, ctrl-alt-i increments the numeric or date or time value for each record.

If these ctrl-alt keys are not convenient, you can change them in the first 8 HotKeySet statements of the code to fit what you need.

This works fine for me on my windows 7 64 bit machines. If you find that you have problems on a different platform, please share your fixes.

Enjoy, and please share your improvements.

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <Array.au3>
#include <Date.au3>

Local $sClipSeparator = @CRLF
; some apps at times misbehave and hog the clipboard for a while, they are supposed to release it and may take their time before they release it, if ever...
Local $dNumberOfRetries = 3 ; number of times to try again in case it's needed
Local $dWaitTimeMilliSec = 200  ; how long to wait between tries, in milliseconds
Local $IncrementValue = 1

Local $Version = "1.01"

; if you change the key assignments below, you may want to also modify the Help() function accordingly
HotKeySet("^!c", "CopyAppend")  ; ctrl alt c, copy append
HotKeySet("^!f", "FilterInClpRecords")  ; ctrl alt f, prompt for find string, then find records in clipboard that contain the string and remove other records from clipboard
HotKeySet("^!d", "FilterOutClpRecords") ; ctrl alt d, prompt for find string, then find records in clipboard that contain the string and remove them only keeping other records in clipboard
HotKeySet("^!h", "ReplaceInClpRecords") ; ctrl alt h, prompt for a find and a replace string, replace and update the clipboard
HotKeySet("^!x", "CutAppend")   ; ctrl alt x, cut append
HotKeySet("^!r", "RunSelection")    ; ctrl alt r, run selection as command line
HotKeySet("^!s", "ClipAppendSetup") ; ctrl alt s
HotKeySet("^!q", "QuitClipAppend")  ; ctrl alt q
HotKeySet("!^{UP}", "SortAscending")    ; ctrl alt up
HotKeySet("!^{DOWN}", "SortDescending") ; ctrl alt down
HotKeySet("!^{F1}", "Help") ; ctrl alt F1
; This reads the current text selection, then prompts for number of needed lines in output buffer.
HotKeySet("^!g", "GenerateListFromSelection")
; If the ctrl alt g list is numeric or date time or starts with a number or date time, ctrl alt i uses the setup increment or decrement value to increment or decrement each buffer entry
HotKeySet("^!i", "InOrDecrementSelection") ; ctrl alt i, looks at record starts, if it is date or numeric and of consistent length, updates that prefix to increase or decrease with each record

ReadSettings()


; The loop that will go on and on while the app is running, between sleeps autoit checks to see if a hotkey from statements above was called from the keyboard
while 1
    Sleep(100)
WEnd

;=========Functions called by hot keys===============

Func ClipAppendSetup()  ; Run the clipAppend setup GUI
Local $listValue
Local $LocalSep
Local $boolSepIsLitt = False
    Local $frmSetup = GUICreate("Append to Clipboard, setup", 530, 220, 50, 5)
    GUISetBkColor(0x005555, $frmSetup)
    WinSetTrans($frmSetup, "", 230) ;set transparency level to 200 (0=invisible, 255=opaque)
    GUICtrlCreateGroup("Clipboard Separator", 5, 5, 520, 110)
    Local $rbLiteral = GUICtrlCreateRadio("Enter a custom separator string:",20, 20)
    Local $rbNonLiteral = GUICtrlCreateRadio("Select a non-literal separator string:",20, 40)
    Local $lbSeps = GUICtrlCreateList("", 210, 50,300, 60)
    Local $edit = GUICtrlCreateEdit("", 210, 20, 300, 25, $ES_AUTOHSCROLL)
    Local $CurrentListSelection
    Local $bSelectionIsCustom = False
    Switch($sClipSeparator)
        case @CR
            $CurrentListSelection = "CR"
            GUICtrlSetState($rbNonLiteral, $GUI_CHECKED)
        case @LF
            $CurrentListSelection = "LF"
            GUICtrlSetState($rbNonLiteral, $GUI_CHECKED)
        case @CRLF
            $CurrentListSelection = "CRLF"
            GUICtrlSetState($rbNonLiteral, $GUI_CHECKED)
        case Else
            $bSelectionIsCustom = True
            GUICtrlSetState($rbLiteral, $GUI_CHECKED)
    EndSwitch
    if $bSelectionIsCustom Then
        GUICtrlSetState($lbSeps, $GUI_DISABLE)
    Else
        GUICtrlSetState($edit, $GUI_DISABLE)
        GUICtrlSetData($lbSeps, "CR|LF|CRLF", $CurrentListSelection)
    EndIf

    Local $lblTries = GUICtrlCreateLabel("Number of tries:", 20, 125)

    Local $cboTries = GUICtrlCreateCombo($dNumberOfRetries, 110, 125, 50)
    GUICtrlSetData(-1,"1|2|3|4|5|6|7")
    Local $lblWait = GUICtrlCreateLabel("Delay between tries (ms):",260, 125)
    Local $cboDelay = GUICtrlCreateCombo($dWaitTimeMilliSec, 390, 125, 50)
    GUICtrlSetData(-1,"100|200|300|400|500|600|700|800|900|1000")

    Local $incVal = GUICtrlCreateLabel("Increment value:",20, 150)
    Local $cboInc = GUICtrlCreateCombo($IncrementValue, 110, 150, 50)
    Local $Data = "-20"
    for $i = -19 to 20
        $Data &= "|" & $i
    Next
    GUICtrlSetData(-1, $Data)

    Local $btnSave = GUICtrlCreateButton("Save Settings", 20, 180, 120, 25)
    Local $btnCancel = GUICtrlCreateButton("Cancel", 390, 180, 120, 25)

    GUICtrlSetState($btnSave, $GUI_DISABLE)

    GUISetState(@SW_SHOW)

    Local $idMsg
    while 1
        $idMsg = GUIGetMsg()
        Switch($idMsg)
            case $GUI_EVENT_CLOSE, $btnCancel
                GUIDelete($frmSetup)
                ;Exit   ;debug
                Return
            case $rbLiteral
                $boolSepIsLitt = True
                GUICtrlSetState($lbSeps, $GUI_DISABLE)
                GUICtrlSetState($edit, $GUI_ENABLE)
            case $rbNonLiteral
                $boolSepIsLitt = False
                GUICtrlSetState($lbSeps, $GUI_ENABLE)
                GUICtrlSetState($edit, $GUI_DISABLE)
            case $lbSeps
                $listValue = "@" & GUICtrlRead($lbSeps)
                GUICtrlSetState($btnSave, $GUI_ENABLE)
            case $cboInc
                GUICtrlSetState($btnSave, $GUI_ENABLE)
            case $btnSave
                if $boolSepIsLitt Then
                    $sClipSeparator = GUICtrlRead($edit)
                Else
                    $sClipSeparator = GetStringValue($listValue)
                EndIf
                $dNumberOfRetries = GUICtrlRead($cboTries)
                $dWaitTimeMilliSec = GUICtrlRead($cboDelay)
                $IncrementValue = GUICtrlRead($cboInc)
                GUIDelete($frmSetup)
                SaveSettings()  ; save the clipboard separator to the registry value HKCU\software\clipappend\$sClipSeparator
                Return
            case $edit, $cboTries, $cboDelay
                GUICtrlSetState($btnSave, $GUI_ENABLE)
        EndSwitch
    WEnd
EndFunc

Func CopyAppend()
    SetError(0)
    Local $CurrentClipString = GetTextClipboard()
    Switch(@error)
        case 0
            send ("^c")
            Local $NewClp = ClipGet()
            PutToClp($CurrentClipString & $sClipSeparator & $NewClp)
        case 1  ; The data in the clipboard is NOT text
            Send ("^c") ; the clipboard is empty, no separator
        case 2
            MsgBox(0, "Error!", "Unable to append to non-string clipboard contents")
        case 3, 4
            MsgBox(0, "Error!", "Unable to access the clipboard")
    EndSwitch
EndFunc

func CutAppend()
    SetError(0)
    Local $CurrentClipString = GetTextClipboard()
    Switch(@error)
        case 0
            send ("^x")
            Local $NewClp = GetTextClipboard()
            PutToClp($CurrentClipString & $sClipSeparator & $NewClp)
        case 1
            Send ("^x") ; the clipboard is empty, no separator
        case 2
            MsgBox(0, "Error!", "Unable to append to non-string clipboard contents")
        case 3, 4
            MsgBox(0, "Error!", "Unable to access the clipboard")
    EndSwitch
EndFunc

Func FilterInClpRecords()
    FilterClpRecords(True)
EndFunc

Func FilterOutClpRecords()
    FilterClpRecords(False)
EndFunc

Func GenerateListFromSelection()
    send("^c")  ; get the selection
    Sleep(100)
    Local $CurrentClipString = GetTextClipboard()
    Local $RepeatNumber = int(InputBox("Repeat Number", "Please enter a number between 0 and 36767:"))
    if $RepeatNumber > 0 Then
        Local $OutBuf = $CurrentClipString
        for $i = 1 to $RepeatNumber-1
            $OutBuf = $OutBuf & $sClipSeparator & $CurrentClipString
        Next
        PutToClp($OutBuf)
    EndIf
EndFunc

Func Help()
    Local $sHelpBuffer = "ClipAppend list of commands" & @LF & "====================" & @LF
    $sHelpBuffer &= "Ctl-alt-S to set up the clipboard delimitor" & @LF
    $sHelpBuffer &= "Ctrl-alt-c to copy and append the current selection (if it can be copied)" & @LF
    $sHelpBuffer &= "Ctrl-alt-x to cut and append the current selection (if it can be cut)" & @LF
    $sHelpBuffer &= "Ctrl-alt-r to run the current selection as a command line" & @LF
    $sHelpBuffer &= "Ctrl-alt-f to only keep clipboard records that contain user find strings" & @LF
    $sHelpBuffer &= "Ctrl-alt-d to only keep clipboard records that DO NOT contain user find strings" & @LF
    $sHelpBuffer &= "Ctrl-alt-up/down to sort the clipboard contents up or down" & @LF
    $sHelpBuffer &= "Ctrl-alt-g to repeat a selected line in current document n times, where the user is prompted for n" & @LF
    $sHelpBuffer &= "Ctrl-alt-i to autoincrement numerically or date wise the clipboard buffer from command above" & @LF
    $sHelpBuffer &= "Ctrl-alt-q to quit" & @LF
    $sHelpBuffer &= "Ctrl-alt-F1 to bring up this message"
    MsgBox(32,"ClipAppend " & $Version & " Help",$sHelpBuffer)
EndFunc

Func InOrDecrementSelection()
    ; check if the buffer starts with a number on each item after splitting around the separator
    Local $CurrentClipString = GetTextClipboard()
    if StringInStr($CurrentClipString, $sClipSeparator)>0 Then
        Local $NumericStringStart = GetNumericStringStart($CurrentClipString)
        if stringlen($NumericStringStart)>0 Then
            ; since this starts with a number, it could be the start of a time, date, or date time substring
            Local $DateTimeStringStart = GetDateTimeStringStart($CurrentClipString)
            if $DateTimeStringStart <> -1 Then
                Local $IncValue = $DateTimeStringStart
                if StringInStr($IncValue, ":")>0 Then
                    ; includes time
                    Local $arTimeInfo = StringSplit($IncValue, ":")
                    Switch($arTimeInfo[0])
                        case 1
                            ;we increment minutes
                            Local $OutBuf = IncDate($CurrentClipString, "n", $IncValue)
                            $IncValue = _DateAdd("n", $IncValue, $IncrementValue)
                        case 2
                            ; we increment seconds
                            Local $OutBuf = IncDate($CurrentClipString, "s", $IncValue)
                            $IncValue = _DateAdd("s", $IncValue, $IncrementValue)
                    EndSwitch
                Else
                    ; does not include time, we increment days
                    Local $OutBuf = IncDate($CurrentClipString, "D", $IncValue)
                    $IncValue = _DateAdd("D", $IncValue, $IncrementValue)
                EndIf
                PutToClp($OutBuf)
            Else
                Local $IncValue = $NumericStringStart
                Local $iLen = stringlen($NumericStringStart)
                Local $arClip = StringSplit($CurrentClipString, $sClipSeparator, 1)
                for $i = 1 to $arClip[0]
                    $arClip[$i] = $IncValue & StringRight($arClip[$i], stringlen($arClip[$i]) - stringlen($NumericStringStart))
                    $IncValue = IncStringNumber($IncValue, $iLen)
                Next
                Local $OutBuf = _ArrayToString($arClip, $sClipSeparator, 1, $arClip[0], $sClipSeparator)
                PutToClp($OutBuf)
            EndIf
        EndIf
    EndIf
EndFunc

Func QuitClipAppend()
    Exit
EndFunc

Func ReplaceInClpRecords()
    Local $CurrentClipString = GetTextClipboard()
    if StringLen($CurrentClipString)>0 Then
        Local $FindString = InputBox("ClipAppend", "Please enter the find string:")
        if StringLen($FindString)>0 Then
            Local $ReplaceString = InputBox("ClipAppend", "Please enter the replace string:")
            if StringInStr($CurrentClipString, $sClipSeparator)>0 Then
                Local $arClip = StringSplit($CurrentClipString, $sClipSeparator)

                for $i = 1 to $arClip[0]
                    if StringInStr($arClip[$i], $FindString)>0 Then
                        $arClip[$i] = StringReplace($arClip[$i], $FindString, $ReplaceString)
                    EndIf
                Next
                Local $sOut = _ArrayToString($arClip, $sClipSeparator, 1, 0, $sClipSeparator)
                PutToClp($sOut)
            Else
                if StringInStr($CurrentClipString, $FindString)>0 Then
                    PutToClp(StringReplace($CurrentClipString, $FindString, $ReplaceString))
                EndIf
            EndIf
        EndIf
    Else
        MsgBox(0, "Warning!", "No clipboard text!")
    EndIf
EndFunc

func RunSelection()
    SetError(0)
    Local $CurrentClipString = GetTextClipboard()
    Switch(@error)
        case 0
;           PutToClp("")    commented because it often causes the next command to fail
            send ("^c")
            SetError(0)
            Local $RunSelection = ClipGet()

            if StringLen($RunSelection)=0 Then
                Switch(@error)
                    case 1
                        MsgBox(0,"Error!", "Failed to copy the selection to the clipboard")
                    case 2
                        MsgBox(0,"Error!", "The selection is not text")
                    case Else
                        MsgBox(0,"Error!", "Failed to access the clipboard, @error = " & @error)
                EndSwitch
                Return
            Else
;               PutToClp("")    commented because it often causes the next command to fail
                PutToClp($CurrentClipString)
                Local $Result = ShellExecute($RunSelection) ; better than using the run cmd, since it can also interpret a link, an exe, a txt
                if $Result = 0 Then
                    MsgBox(0,"Error!", "Failed to run the command '" & $RunSelection & "'")
                EndIf
            EndIf
        case 1
            Send ("^x") ; the clipboard is empty, no separator
        case 2
            MsgBox(0, "Error!", "Unable to append to non-string clipboard contents")
        case 3, 4
            MsgBox(0, "Error!", "Unable to access the clipboard")
    EndSwitch
EndFunc

Func SortAscending()
    SetError(0)
    Local $clp = ClipGet()
    Switch(@error)
        case 0
            Local $arClip = StringSplit($clp, $sClipSeparator, 1)
            _ArraySort($arClip,0, 1)
            PutToClp(_ArrayToString($arClip, $sClipSeparator, 1, 0, $sClipSeparator))
        case 1
            MsgBox(0,"Warning!", "There is nothing to sort, the clipboard is empty")
        case 2
            MsgBox(0,"Warning!", "There is nothing to sort, the clipboard contents are not alphanumeric")
        case 3, 4
            MsgBox(0, "Error!", "Unable to access the clipboard")
    EndSwitch
EndFunc

Func SortDescending()
    SetError(0)
    Local $clp = ClipGet()
    Switch(@error)
        case 0
            Local $arClip = StringSplit($clp, $sClipSeparator, 1)
            _ArraySort($arClip,1, 1)
            PutToClp(_ArrayToString($arClip, $sClipSeparator, 1, 0, $sClipSeparator))
        case 1
            MsgBox(0,"Warning!", "There is nothing to sort, the clipboard is empty")
        case 2
            MsgBox(0,"Warning!", "There is nothing to sort, the clipboard contents are not alphanumeric")
        case 3, 4
            MsgBox(0, "Error!", "Unable to access the clipboard")
    EndSwitch
EndFunc


;==============End of Functions called by hot keys===============






;====================Support Functions ==========================

Func FilterClpRecords($boolInclude)
    Local $CurrentClipString = GetTextClipboard()
    if StringLen($CurrentClipString)>0 Then
        ; There is a clipboard text to search and filter
        Local $arFindStrings = InputBoxWCheckBox("ClipAppend", "Please enter the find string:", "Please uncheck to stop entering data")
        if $arFindStrings <> -1 Then
            ; The user entered at least one find string
            Local $sOutClip ; output string that will be written to the clipboard when populated below
            if StringInStr($CurrentClipString, $sClipSeparator)>0 Then
                ; the clipboard text has multiple records
                Local $arClip[0], $arFound[0]
                _ArrayAdd($arClip, $CurrentClipString, 0, $sClipSeparator) ;populate the array of current clipboard records $arClip
                ; for each user find string,
                for $i = 0 to UBound($arFindStrings) - 1
                    Local $arNewFound[0]
                    ; populate an array of indexes where the current find string was found, $arNewFound
                    $arNewFound = _ArrayFindAll($arClip, $arFindStrings[$i], 0, 0, 0, 1)
                    ; append the contents of array $arNewFound to already found array $arFound
                    _ArrayConcatenate($arFound, $arNewFound)
                Next
                _ArrayUnique($arFound)  ; remove duplicates (different user find strings may be found in the same record)
                _ArraySort($arFound)    ; sort so looping through array items points to increasing indexes of array $arClip

                if $boolInclude Then    ; $boolInclude is the instruction to filter in strings where find strings are found
                    Local $arOutClip[UBound($arFound)]  ; declare output clipboard record array with same size as array of found records
                    ; populate output clipboard array
                    for $i = 0 to UBound($arOutClip) - 1
                        $arOutClip[$i] = $arClip[$arFound[$i]]
                    Next
                    if UBound($arOutClip)>0 then
                        $sOutClip = _ArrayToString($arOutClip,$sClipSeparator)  ; serialize the array into a string for output
                    EndIf
                ElseIf Ubound($arClip) > UBound($arFound) Then  ; if not all clipboard records contain one of the find strings,
                    if UBound($arFound) = 0 Then
                        Return  ; nothing was found, keep the clipboard as is
                    Else
                        Local $arOutClip[UBound($arClip) - UBound($arFound)]
                        Local $iFound = 0
                        Local $FoundIndex = $arFound[$iFound]
                        Local $OutClipIndex = 0
                        for $i = 0 to UBound($arClip) - 1
                            if $FoundIndex < $i Then
                                ; the current clipboard record does not contain any of the find strings,
                                $arOutClip[$OutClipIndex] = $arClip[$i]
                                $OutClipIndex += 1  ; increment output clipboard array index for (possible) use in later loop
                            Else
                                $iFound += 1
                                $FoundIndex = $arFound[$iFound]
                            EndIf
                        Next
                        $sOutClip = _ArrayToString($arOutClip,$sClipSeparator)
                    EndIf
                ;Else   ; all records have found strings, the clipboard contents should be emptied, leave $sOutClip as is, which is empty
                EndIf
                PutToClp($sOutClip)
            Else    ; clipboard contents has only one record,
                msgbox(0,@ScriptLineNumber, "clipboard contents has only one record")
                for $i = 0 to UBound($arFindStrings) - 1
                    MsgBox(0,@ScriptLineNumber, "checking out " & $arFindStrings[$i])
                    if  StringInStr($CurrentClipString, $arFindStrings[$i])>0 Then
                        If $boolInclude Then
                            Return
                        Else
                            PutToClp("")
                        EndIf
                    EndIf
                Next
            EndIf
        EndIf
    Else
        MsgBox(0, "Warning!", "No clipboard text!")
    EndIf
EndFunc

Func GetDateTimeStringStart($Buf)
    local $arClip = StringSplit($Buf, $sClipSeparator, 1)
    ; don't want to check all entries if there are thousands, limit it to 30
    Local $scope = $arClip[0]
    if $scope > 30 then $scope = 30
    Local $SubString = ""
    for $i = 1 to $scope
        if  $SubString = "" Then
            $SubString = GetNumSubstring($arClip[$i], "/:")
        Else
            if stringlen($arClip[$i])>0 Then
                Local $NewSubString = GetNumSubstring($arClip[$i], "/:")
                if $NewSubString <> $SubString Then
                    MsgBox(0, "Error!", "Buffer line " & $i & " is different from buffer line " & $i - 1 & "!")
                    Return -1
                EndIf
            EndIf
        EndIf
    Next
    Return $SubString
EndFunc

Func GetNumericStringStart($Buf)
    local $arClip = StringSplit($Buf, $sClipSeparator, 1)
    ; don't want to check all entries if there are thousands, limit it to 30
    Local $scope = $arClip[0]
    if $scope > 30 then $scope = 30
    Local $LeftNumeric, $boolDifferent = False
    for $i = 1 to $scope
        if  $i = 1 Then
            $LeftNumeric = GetNumSubstring($arClip[$i])
        Else
            Local $NewLeftNumeric = GetNumSubstring($arClip[$i])
            if $NewLeftNumeric <> $LeftNumeric Then
                MsgBox(0, "Error!", "Buffer line " & $i & " is different from buffer line " & $i - 1 & "!")
                Return -1
            EndIf
        EndIf
        if StringLen($LeftNumeric) = 0 then
            MsgBox(0, "Error!", "Buffer line 1 does not start with a number")
            Return -1
        EndIf
    Next
    Return $LeftNumeric
EndFunc

Func GetNumSubstring($sIn, $NonNumAcceptableChars = "")
    Local $Char, $Ret
    for $i = 1 to stringlen($sIn)
        $Char = StringMid($sIn, $i, 1)
        if  Asc($Char)>47 and Asc($Char)<58 Then
            $Ret &= $Char
        ElseIf StringInStr($NonNumAcceptableChars, $Char)>0 Then
            $Ret &= $Char
        Else
            ExitLoop
        EndIf
    Next
    if StringLen($NonNumAcceptableChars)>0 Then
        ; check if it's a date, time, or date time
        if _DateIsValid($Ret)=0 Then
            $Ret = ""   ; date time is not valid
        EndIf
    EndIf
    Return $Ret
EndFunc

func GetStringValue($Value)
    if StringLeft($Value, 1) = "@" Then
        Switch($Value)
            case "@CR"
                Return @CR
            case "@LF"
                Return @LF
            case "@CRLF"
                return @CRLF
            case Else
                Return $Value
        EndSwitch
    Else
        Return $Value
    EndIf
EndFunc

Func GetTextClipboard($dFailedNum = 0)
    Local $ClipText = ClipGet() ; first try to get the text clipboard value
    Switch(@error)
        case 0
            Return $ClipText
        case 1
            SetError(0)
            Return ""
        case 2
            Return ""
        case 3,4
            if $dFailedNum = -1 then    ; -1 flags that if it fails, we return an empty string and the error set in the ClipGet() call
                Return ""
            EndIf
            ; it failed once, try again till the set number of tries is reached
            While ++$dFailedNum < $dNumberOfRetries
                Sleep($dWaitTimeMilliSec)
                SetError(0)
                $ClipText = GetTextClipboard(-1)    ; use -1 to flag not to keep going recursively forever
                if @error = 0 Then  ; no error, this means that the call succeeded, the function job is complete
                    Return $ClipText
                EndIf
            WEnd
            MsgBox(0, "Error!", "The clipboard seems to be locked, it failed to respond after " & $dNumberOfRetries & " attempts, with " & $dWaitTimeMilliSec & " between tries.")
    EndSwitch
EndFunc

Func IncDate($Buf, $Type, $IncValue)
    Local $arClip = StringSplit($Buf, $sClipSeparator, 1)
    Local $iLen = stringlen($IncValue)
    for $i = 1 to $arClip[0]
        $arClip[$i] = $IncValue & StringRight($arClip[$i], stringlen($arClip[$i]) - $iLen)
        $IncValue = _DateAdd($Type, $IncrementValue, $IncValue)
    Next
    Return _ArrayToString($arClip,$sClipSeparator, 1, $arClip[0], $sClipSeparator)
EndFunc

Func IncStringNumber($sIn, $iLen)
    Local $sFormat = "%0" & $iLen & "d" ; build the format string, see PrintFormat in help for the syntax
    $sIn = $sIn*1 + $IncrementValue ; multyplying by one internally converts the string that contains characters between 0 and 9 to a numeric value
    Return StringFormat($sFormat, $sIn)
EndFunc

; returns an array of user strings, user enters till the checkbox is unchecked
Func InputBoxWCheckBox($Title, $Prompt, $CheckBoxLabel)
    Local $boolChecked = True
    Local $boolClearEdit = True
    Local $arUE[1]
    Local $GuiID = GUICreate($Title, 415, 120)
    Local $PromptID = GUICtrlCreateLabel($Prompt, 5, 10, 200)
    Local $UserInputID = GUICtrlCreateInput("",210, 10, 200)
    Local $cbDoneID = GUICtrlCreateCheckbox($CheckBoxLabel, 5, 35)
    GUICtrlSetState(-1, $GUI_CHECKED)
    Local $cbEmptyEditOnOK = GUICtrlCreateCheckbox("Delete Find string on OK press", 200, 35)
    GUICtrlSetState(-1, $GUI_CHECKED)
    Local $btnCancel = GUICtrlCreateButton("Cancel", 5, 60, 70)
    Local $btnOK = GUICtrlCreateButton("OK", 340, 60, 70)
    GUICtrlSetState(-1, $GUI_DEFBUTTON)
    GUISetState(@SW_SHOW, $GuiID)
    While 1
        local $msg = GUIGetMsg()
        Switch($msg)
            Case $GUI_EVENT_CLOSE
                GUIDelete($GuiID)
                ExitLoop
            case $cbDoneID
                $boolChecked = BitAND(GUICtrlRead($cbDoneID), $GUI_CHECKED) = $GUI_CHECKED
            case $cbEmptyEditOnOK
                $boolClearEdit = BitAND(GUICtrlRead($cbEmptyEditOnOK), $GUI_CHECKED) = $GUI_CHECKED
            case $btnCancel
                GUIDelete($GuiID)
                Return -1
            case $btnOK
                Local $UserEntry = GUICtrlRead($UserInputID)
                if stringlen($UserEntry)>0 Then
                    if StringLen($arUE[0]) = 0 Then
                        $arUE[0] = $UserEntry
                    Else
                        _ArrayAdd($arUE, $UserEntry)
                    EndIf
                    if $boolClearEdit Then
                        GUICtrlSetData($UserInputID, "")
                    EndIf
                EndIf
                if $arUE = 0 And Not $boolChecked Then
                    GUIDelete($GuiID)
                    return -1
                ElseIf $arUE <> 0 And Not $boolChecked Then
                    GUIDelete($GuiID)
                    Return $arUE
                EndIf
        EndSwitch
    WEnd
EndFunc

Func PutToClp($sClp)
    Local $Res = ClipPut($sClp)
    Local $Attempts = 1
    while $res = 0 and $Attempts < $dNumberOfRetries    ; while failure
        Sleep($dWaitTimeMilliSec)
        $Res = ClipPut($sClp)
        $Attempts += 1
    WEnd
    if $Res = 0 Then    ; failed
        MsgBox(0,"Error!", "Failed to write to the clipboard!")
    EndIf
EndFunc

Func ReadRegSetting($Setting, $Type)
    Local $RetVal
    SetError(0)
    $RetVal = RegRead("HKCU\software\ClipAppend", $Setting)
    Switch(@error)
        case 0
            if StringLen($RetVal)>0 Then
                Return $RetVal
            Else
                Return -1
            EndIf
        case -1 ; in case the ClipAppend key is there, but not the $Setting value
            Return -1
        case 1  ; expected on first use, there is no ClipAppend key, create it
            RegWrite("HKCU\software\ClipAppend")
            Return -1
        case 2
            Return -1
        case else   ; should never get here
            MsgBox(0,"Error!", "Failed to write to the registry, @error = " & @error)
            Return -1
    EndSwitch
EndFunc

Func ReadSettings()
    Local $RetVal
    $RetVal = ReadRegSetting("ClipSeparator", "REG_MULTI_SZ")
    if $RetVal <> -1 Then
        $sClipSeparator = $RetVal
    EndIf
    $RetVal = ReadRegSetting("CopyCutRetries", "REG_SZ")
    if $RetVal <> -1 Then
        $dNumberOfRetries = $RetVal
    EndIf
    $RetVal = ReadRegSetting("RetryDelay", "REG_SZ")
    if $RetVal <> -1 Then
        $dWaitTimeMilliSec = $RetVal
    EndIf
    $RetVal = ReadRegSetting("IncrementValue", "REG_SZ")
    if $RetVal <> -1 Then
        $IncrementValue = $RetVal
    EndIf
EndFunc

Func SaveSettings()
    SetError(0)
    Local $Result = RegWrite("HKCU\SOFTWARE\ClipAppend", "ClipSeparator", "REG_MULTI_SZ", $sClipSeparator)
    if $Result = 0 Then
        MsgBox(0,"Error!", "Failed to write the separator value to the registry, error = " & @error)
    EndIf
    SetError(0)
    Local $Result = RegWrite("HKCU\SOFTWARE\ClipAppend", "CopyCutRetries", "REG_SZ", $dNumberOfRetries)
    if $Result = 0 Then
        MsgBox(0,"Error!", "Failed to write the number of copy retries to the registry, error = " & @error)
    EndIf
    SetError(0)
    Local $Result = RegWrite("HKCU\SOFTWARE\ClipAppend", "RetryDelay", "REG_SZ", $dWaitTimeMilliSec)
    if $Result = 0 Then
        MsgBox(0,"Error!", "Failed to write the retry delay to the registry, error = " & @error)
    EndIf
    SetError(0)
    Local $Result = RegWrite("HKCU\SOFTWARE\ClipAppend", "IncrementValue", "REG_SZ", $IncrementValue)
    if $Result = 0 Then
        MsgBox(0,"Error!", "Failed to write the increment value to the registry, error = " & @error)
    EndIf
EndFunc


;====================End Support Functions ==========================
Edited by rodent1

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

  • Similar Content

    • AndreyS
      By AndreyS
      Hello to you, dear developers!
      Could you please tell me if there is an easy way to determine if the information was pasted from the clipboard?
      Without any variation of the insertion via Ctrl+V, or through the context menu.
      I revised the Help and many forum topics, but found nothing suitable.
      Can there be any WinAPI system events that determine this event?
    • Nareshm
      By Nareshm
      Its possible to past previously copied text to somewhere with autoit script ?
      If yes, How it ?
      example : Before I copied ABCD and then copied the PQRS, how to past the previously copied ABCD ?
    • mmoalem
      By mmoalem
      I seem to have an issue with clipget() - the following bit of code copy URL from chrome address bar - than using clipget() i try to grab the URL into a variable and input it into a spreadsheet. the script did not put anything into the sheet 
      originally I though it was an issue with  OOo/LibO Calc UDF and posted it there :
       
      than I tried writing $NewURL into a text file and than just a msgbox but it comes blank. (the URL is in the clipboard as i can paste it)
       
      send ("!d") ;select URL in browser send ("^c") ;copy selected URL Local $NewURL = ClipGet() MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, $sTitle, $NewURL ) am I doing something wrong? is there an issue with a URL characters?
    • tcurran
      By tcurran
      Here's a short UDF that will, at least in most cases, detect whether a window can be copied from or pasted to programmatically--for example, by Send()ing ctl-c, ctl-v. This is often disabled when programs (like your AutoIt script) run at a lower UAC integrity level than the application they are trying to operate on.
      #include <WinAPI.au3> Func _WindowIsPasteable($handle) ;accepts window handle; returns true or false whether a window will accept Ctl-C, Ctl-V Local $bCanPaste = True Local $hTestWindowPID = 0 Local $hTestWindowTID = _WinAPI_GetWindowThreadProcessId($handle, $hTestWindowPID) _WinAPI_AttachThreadInput(_WinAPI_GetCurrentThreadId(), $hTestWindowTID, True);attach to window we want to paste into $bCanPaste = _WinAPI_GetFocus() ;Test whether window is paste-able--returns False if it is not _WinAPI_AttachThreadInput(_WinAPI_GetCurrentThreadId, $hTestWindowTID, False);detach from window thread Return $bCanPaste EndFunc Pass it a window handle; it returns true or false whether a window will accept programmatic pasting. The function may not work on the CMD window, since it handles the clipboard uniquely.
      This function works by attaching to the program thread of the window whose handle it receives, then attempting to perform a GetFocus on that thread. In most cases, the attempt will fail if the window will not accept programmatic copy-paste.
    • caramen
      By caramen
      Hello Guys,
      I am trying to make a screenshoot copy it to clipboard and paste it into a word document i want to do that to simplify my procedures création. 
       
      I am trying to use the way of sending Keys "^c" & "^v" i tryed also CTRLDOWN and c but no one of these is working. 
       
      First question :
      Why that's not working? 
      Is there anyother way i can work with ?
       
      I watched the help file for FileCopy but it s only moving Files and not copy them. 
       
      Maybe you can see somthing going wrong in my script but i guess it s not a syntax problem. 
      #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.2 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <ScreenCapture.au3> #include <MsgBoxConstants.au3> HotKeySet("{F2}", "Capture") HotKeySet("{F3}", "Windows") HotKeySet("{F4}", "Copy") Global $Numero = 0 Attendre () Capture() Func Capture() ; Capture full screen $Numero = $Numero+1 _ScreenCapture_Capture (@DesktopDir & "\ScreenCapture\Image"&$Numero&".jpg") ShellExecute( @DesktopDir &"\ScreenCapture\Image"&$Numero&".jpg") Sleep (500) Run("C:\WINDOWS\EXPLORER.EXE /Select, /n,/e," & @DesktopDir & "\ScreenCapture\Image"&$Numero&".jpg" ) WinWaitActive("ScreenCapture") Sleep(1500) Send("^c") ;~ Send ("{CTRLDOWN}") ;~ Sleep(10) ;~ Send ("C") ;~ Sleep(10) ;~ Send ("{CTRLUP}") EndFunc ;==>Example Func Windows () Global $Windows = WinGetTitle("[active]") MsgBox($MB_SYSTEMMODAL, "Windows", "Windows selected for copy is : "&@CRLF&$Windows) EndFunc Func Copy () WinActivate (""&$Windows) Sleep (100) Send("^v") ;~ Send ("{CTRLDOWN}") ;~ Sleep(10) ;~ Send ("V") ;~ Sleep(10) ;~ Send ("{CTRLUP}") EndFunc Func Attendre () While 1 Sleep (10) ;~ GUICreate ("Help",100,100) WEnd EndFunc