Probleme mit meinem Text Template Tool

  • Hallo Members,

    habe schon viele nützliche Tipps im Forum gefunden aber zu einem aktuellen Problem finde ich einfach keine Lösung.

    Ich habe für meine Kollegen und mich ein Tool geschrieben, dass die tägliche Arbeit sehr erleichtert. In diesem Tool ist u.a.
    eine Funktion enthalten, mit der man überall Text Templates einfügen kann. (Sowas wie AutoText für alle Anwendungen)

    Kurze Funktionbeschreibung:
    Wenn man an der Stelle ist, wo man einen Text-Schnipsel einfügen möchten, öffnet man über einen HotKey ein Fenster.
    Dieses Fenster enthält eine ListView, welche die ganzen Text-Schnipsel enthält. Man sucht sich den gewünschten aus und
    AutoIt fügt den Text ins Ursprungs-Programm ein.

    Problembeschreibung:
    Anfangs wollte ich die Texte über ControlSetText in das jeweilige Programm einfügen aber da gab es immer wieder Probleme
    mit den sehr verschiedenen Eingabefeldern und Textfeldern. Also benutze ich folgenden einfachen Code, um den Text ins
    Ursprungs-Programm einzufügen.

    [autoit]

    $aTextTemplate = _GUICtrlListView_GetItemTextArray($hMainSpecialPasteList, _GUICtrlListView_GetSelectionMark($hMainSpecialPasteList))
    $sOldClip = ClipGet() ;alten ClipBrd Eintrag sichern
    ClipPut($aTextTemplate[2]) ;TextTemplate ins ClipBrd schreiben (1 = Category; 2 = Text)
    WinActivate(GUICtrlRead($hMainSpecialPasteWindowName)) ;Ursprungs-Programm in Vordergrund holen
    Send("^v",0) ;ClipBrd Inhalt einfügen
    ClipPut($sOldClip) ;alten ClipBrd Eintrag schreiben
    GUISetState(@SW_HIDE, $hMainSpecialPaste) ;Text Template Auswahl Fenster verstecken

    [/autoit]

    Jetzt passiert es aber immer wieder, dass im Ursprungs-Programm der Wert $sOldClip eingefügt wird. Beim debuggen
    habe ich festgestellt, dass der Wert immer richtig in die Zwischenablage übernommen wird, wenn der falsche Text im
    Ursprungs-Programm landet. Somit kann es eigentlich nur sein, dass der "Einfügen-Befehl" nachdem ClipPut($sOldClip)
    im Ursprungs-Programm ankommt. Dies habe ich versuchte mit diversen Delay-Einstellungen zu umgehen aber selbst
    bei hohen Sleep-Werten kommt der Fehler noch vor.

    Leider passiert der Fehler nicht nur eins, zwei mal, sondern kommt immer wieder vor und manchmal mehrfach hinter-
    einander. Somit ist die Zeitersparnis gleich Null und man wäre schneller, wenn man den Text von Hand schreibt.
    Hat vielleicht noch jemand hier im Forum eine Idee, was ich noch machen könnte oder andere Ansätze dies umzusetzen?

    Vielen Dank und Grüße

    ic4u

  • Hi und willkommen im Forum,
    versuch einfach mal ein

    [autoit]

    Sleep(1000)

    [/autoit]


    nach dem Send einzufügen.
    Dein Script schreibt wieder den alten Wert in die Zwischenablage,
    aber Windows ist zu langsam und schafft es nicht den Text einzufügen.

    Aber eigentlich brauchst du die Zwischenablage doch nicht,
    machs doch mit Variablen und Send:

    [autoit]

    $aTextTemplate = _GUICtrlListView_GetItemTextArray($hMainSpecialPasteList, _GUICtrlListView_GetSelectionMark($hMainSpecialPasteList))
    WinActivate(GUICtrlRead($hMainSpecialPasteWindowName)) ;Ursprungs-Programm in Vordergrund holen
    Send($aTextTemplate[2],0) ;Inhalt einfügen
    GUISetState(@SW_HIDE, $hMainSpecialPaste) ;Text Template Auswahl Fenster verstecken

    [/autoit]

    Jan

    o
    L_/
    | ||

    This ist janaiky. Copy janaiky into your signature to help him on the war to the Weltherrschaft.

  • Danke janaiky :)

    Ich hatte schon viel höhere Sleep-Werte - bei 5000 habe ich dann aufgehört - selbst da ist
    der Fehler noch aufgetreten. Die Variable direkt zu senden habe ich auch schon versucht
    aber da kam es auch zu Fehlern (Zeichen fehlten und ähnliches), selbst mit ...

    [autoit]

    Send($aTextTemplate[2],1)

    [/autoit]

    ... deshalb bin ich dann zur Zwischenablage gewechselt.

    EDIT: BugFix - Ich habe auch Text-Felder mit

    [autoit]

    [CLASS:SWT_Window0; INSTANCE:59]

    [/autoit]

    da funktioniert ControlSetText nicht - wir arbeiten mit verschieden Programmen und in allen sollte es funktionieren.

    ic4u

  • Schau dir mal ControlGetFocus an, damit kannst du herausbekommen, welchen CLassNameNN ein Control hat in dem der Cursor drin ist. Und dann kannst du mit einem Switch entscheiden mit welcher Möglichkeit du den Text einfügst in das Control.

    Hab ich das richtig verstanden. Du hast ein Tool was im Hintergrund läuft. Wenn du ein externes Programm hast und dort in einem Edit oder Input oder was anderes, deinen Cursor reinsetzt und dann den HotKey drückst, kommt dann eine von dir erstellte Gui mit einem Listview. Dort wählst du den Text aus der dann in das Control rein soll????

  • hast du $aTextTemplate[2] mal in eine Msgbox oder Console ausgegeben um rauszufinden ob der richtige Text drinsteht?
    wenn du winwaitactive() benutzt, kannst du dir das sleep() sparen...

  • Zitat

    Schau dir mal ControlGetFocus an, damit kannst du herausbekommen, welchen CLassNameNN ein Control hat in dem der Cursor drin ist. Und dann kannst du mit einem Switch entscheiden mit welcher Möglichkeit du den Text einfügst in das Control.

    So hatte ich das Anfangs gemacht. Mit ControlGetFocus die Class des Eingabe-Felds ausgelesen - das hat aber nur bei Eingabe-Feldern funktioniert, sobald es eine Textarea war, funktionierte die Methode mit ControlSendText nicht mehr oder gibt es doch eine Extra Funktion, die ich bis jetzt noch nicht gefunden habe und es gibt ja bestimmt eine ClassNames, die man bestimmt nicht alle ins Skript aufnehmen kann? ?(

    Zitat

    Hab ich das richtig verstanden. Du hast ein Tool was im Hintergrund läuft. Wenn du ein externes Programm hast und dort in einem Edit oder Input oder was anderes, deinen Cursor reinsetzt und dann den HotKey drückst, kommt dann eine von dir erstellte Gui mit einem Listview. Dort wählst du den Text aus der dann in das Control rein soll????

    Richtig verstanden :thumbup:

    janaiky - trotzdem Vielen Danke für deine Tipps :thumbup:

    Andy - hatte nicht genau geschrieben, was ich alles im Debug hatte aber dies war mit dabei. Außerdem war dabei Rückgabe-Wert von ClipPut, Werte von ClipGet vor und nach ClipPut.

    Ich vermute, wie janaiky auch, dass bei dieser ClipBoard-Lösung der STRG+V zu spät im Programm ankommt und somit der alte Wert der Zwischenablage wieder geschrieben wurde.

  • Versuch mal dies hier. Du setzt den Cursor da hin, wo du was einfügen willst. Dann drückst du Strg+Shift+e, Dann wählst du den Text aus und drückst den Button zum einfügen. Zum Beenden des Programms musst du erstmal unten rechts am AutoIt-Trayicon Exit drücken. Das X vom Fenster schliesst nur das Fenster (siehe MsgBox). Du musst aber noch eine Ini erstellen die folgendermaßen aussieht.

    Code
    [Texte]
    1=Dies ist der erste Text.
    2=Na wie gehts dir so?
    3=Hallöchen
    4=Wat guckst du???
    
    
    [ClassNameNN]

    Du kannst da immer neue Texte hinzufügen, einfach hinzuschreiben, eine Zahl höher und den Text. In die Sektion ClassNameNN kommen die Control-ClassNameNN's rein die man nur über ControlSetText ansprechen kann. Ansonsten werden alle über den Send-Befehl angesprochen.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("SendKeyDelay", 0)
    Opt("SendKeyDownDelay", 0)

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet("^E", "_Gui") ; Strg+Shift+e

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Gui()
    $hWinHWND = WinGetHandle("[Active]")
    $sControlClassNameNN = ControlGetFocus("[Active]")

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("Gui", 300, 200)
    $hTextlist = GUICtrlCreateList("", 10, 10, 280, 100)
    $aIni = IniReadSection(@ScriptDir & "\Texte.ini", "Texte")
    For $i = 1 To $aIni[0][0]
    GUICtrlSetData(-1, $aIni[$i][1])
    Next
    $hInsertText = GUICtrlCreateButton("Text einfügen", 110, 130, 80, 25)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    MsgBox(0, "Hinweis", "Das Fenster wird nur geschlossen, beenden kann man das Programm über das Trayicon")
    GUIDelete()
    Return
    Case $hInsertText
    $sText = GUICtrlRead($hTextlist)
    GUIDelete()
    WinActivate($hWinHWND)
    _InsertText($hWinHWND, $sControlClassNameNN, $sText)
    Return
    EndSwitch
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _InsertText($hWinHWND, $sControlClassNameNN, $sText)
    $aIni = IniReadSection(@ScriptDir & "\Texte.ini", "ClassNameNN")
    If @error Then
    Send($sText, 1)
    Return
    EndIf
    For $i = 1 To $aIni[0][0]
    If $sControlClassNameNN = $aIni[$i][1] Then
    ControlSetText($hWinHWND, "", $sControlClassNameNN, $sText)
    Return
    EndIf
    Next
    Send($sText, 1)
    Return
    EndFunc

    [/autoit]

    Achja die Ini sollte Texte.ini heißen, aber den Namen kannste ja noch ändern.

  • Zitat

    dass bei dieser ClipBoard-Lösung der STRG+V zu spät im Programm ankommt und somit der alte Wert der Zwischenablage wieder geschrieben wurde.

    das würde nichts anderes bedeuten, als das dein "neuer" Text nie in der Zwischenablage angekommen ist....

    bau doch mal folgendes in dein Script ein:
    Ich meine die Ermittlung der zzt. aktiven Fenster und deren Aktivierung

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    ;script aus scite mit F5 starten

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt("WinTitleMatchMode", 2)
    ;Opt("SendKeyDelay", 100)

    [/autoit] [autoit][/autoit] [autoit]

    Send("^{end}") ;cursor in Scite nach unten im aktuellen script
    Send("{ENTER}") ;neue zeile, schreibt in die letzte zeile des scriptes

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $hwnd = WinGetHandle("[active]") ;aktives fenster ist scite
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hwnd = ' & $hwnd & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aTextTemplate[10]
    For $i = 0 To 9 ;array füllen
    $aTextTemplate[$i] = "TEST" & $i & @CRLF
    Next
    _ArrayDisplay($aTextTemplate)
    ClipPut("OLD_TEXT" & @CRLF) ;alten text ins clipboard schreiben
    $sOldClip = ClipGet() ;alten ClipBrd Eintrag sichern
    MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$sOldClip' & @LF & @LF & 'Return:' & @LF & $sOldClip) ;### Debug MSGBOX

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 9
    ClipPut($aTextTemplate[$i]) ;TextTemplate ins ClipBrd schreiben (1 = Category; 2 = Text)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : ClipPut($aTextTemplate) = ' & ClipPut($aTextTemplate[$i]) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & 'clipget()' & @LF & @LF & 'Return:' & @LF & ClipGet()) ;### Debug MSGBOX
    $b = WinActivate($hwnd)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $b = ' & $b & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $a = WinWaitActive($hwnd, "");Ursprungs-Programm in Vordergrund holen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    Send("^v") ;ClipBrd Inhalt einfügen
    ClipPut($sOldClip) ;alten ClipBrd Eintrag schreiben
    ;GUISetState(@SW_HIDE, $hMainSpecialPaste) ;Text Template Auswahl Fenster verstecken
    Send("^v") ;ClipBrd Inhalt einfügen
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]

    Btw, kann es sein, daß auf euren Rechnern ein Keylogger mitläuft? Ich meine eines dieser altmodischen verbotenen "ChefichhabdawasumdieProduktivitätderMitarbeiterzubestimmen"-Tools....

  • Erstmal Danke an euch beide, werde das ganze mal testen. :thumbup:

    Zitat

    Btw, kann es sein, daß auf euren Rechnern ein Keylogger mitläuft? Ich meine eines dieser altmodischen verbotenen "ChefichhabdawasumdieProduktivitätderMitarbeiterzubestimmen"-Tools....

    Nein, so etwas gibt es nicht und der Betriebsrat wäre darüber auch nicht sehr begeistert. ;)

    Ich glaube, dass hat wohl noch eher direkt mit dem einen Programm zu tun. Aus diesem geht auch ständig STRG+C nicht - tja ist halt in Java programmiert :wacko:

    EDIT:
    Also die Werte die im Debug erscheinen sind alle korrekt, selbst wenn ein Fehler (also der Falsche Text in das Programm eingefügt wird. Da ich mir nicht mehr sicher war, warum ControlSetText nicht funktionierte, habe ich hier auch ein Debug laufen lassen. ControlSetText gibt z.B. für Class SWT_Window59 ein Rückgabewert von 1 zurück aber es wird kein Text angezeigt. Dies ist bei allen Text-Feldern mit SWT_Window als Class.
    Momentan teste ich ControlSend mit der STRG+V Methode, bis jetzt, war immer der korrekte Wert in den Feldern gelandet.

    Einmal editiert, zuletzt von ic4u (27. April 2010 um 10:50)

  • Ich kann zwar keine Doppelposts leiden aber lässt sich hier im Forum wohl nicht vermeiden.

    *Update im letzten Beitrag*

  • Hatte mich etwas länger nicht gemeldet, da ich die ganzen Tipps mal ausprobiert habe.

    Zitat

    Du kannst da immer neue Texte hinzufügen, einfach hinzuschreiben, eine Zahl höher und den Text. In die Sektion ClassNameNN kommen die Control-ClassNameNN's rein die man nur über ControlSetText ansprechen kann. Ansonsten werden alle über den Send-Befehl angesprochen.

    @m-obi ich habe deinen Vorschlag mal so umgeändet, dass er immer ControlSetText nimmt und nur die aus der Sektion mit Send anspricht, dann bin ich haber wieder bei dem Problem mit Send oder ControlSend - da passiert es manchmal das der Text falsch übertragen wird. Egal in welchem Modus, z.B.

    Code
    aus: http://autoit.de wird http:/7Autoit.de
    aus: Start wird: staRT oder auch mal stArt usw.

    Habe auch schon mit den SendKeyDelay und SendKeyDownDelay experimentiert aber ohne Erfolg. Bei ControlSend(x,y,"^v",0) habe ich immer mal das Phänomen, dass nur "v" erscheint .... :wacko:

    Grüße ic4u

  • Momentan habe ich eine Lösung gefunden, wie es bislang problemlos funktionierte.
    Und zwar bin ich von ClipGet und ClipPut auf die Clipboard Management UDF gewechselt.

    Seitdem gab es nocht kein Problem mit dem Special Paste Tool.

    Mit den SWT_Class Textboxen und ControlSetText hatte ich kein glück. Konnte auch nix brauchbares im Netz finden, außer das ich nicht der Einzige bin, wo dies nicht funktioniert.

    Grüße ic4u

  • Guten Morgen zusammen,

    gestern bin ich über das Template Text Script gestolpert.
    Dieses wäre hier in meinem Umfled super einzusetzen, um Kollegen das 'standadisierte Ausfüllen von Formularen' zu erleichtern.

    Allerdings müsste es möglich sein in den in der Text.ini hinterlegten TextSnips auch Zeilenumbrüche nutzen zu können.
    Geht das so überhaupt ?

    Stand jetzt
    aaaa - bbbb - cccc - dddd

    Stand gewünscht
    aaaa
    bbbb
    cccc
    dddd

    Leider ist es mir nicht gelungen hierzu eine Lösung zu finden / zu realisieren
    Daher wende ich mich hier an das Forum mit meiner Frage.


    Danke schon einmal im voraus

    mfg
    ugt100