1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Kanashius

Beiträge von Kanashius

  • Funktionsnamen mit Unterstrich

    • Kanashius
    • 28. Juni 2023 um 15:38
    Zitat von mumpel

    Nämlich sprechende Namen mit dem Kürzel des Typs davor (var für Variant, str für String, int für Integer, lng für Long, obj für Object etc. pp.). Z.B. $strEditbox1 = für den Inhalt der ersten Textbox.

    Es gibt für AutoIt auch "best coding practices", die vorgeben, wie man am besten benennen sollte: https://www.autoitscript.com/wiki/Best_coding_practices

    Deshalb wirst du in AutoIt eig. nur (v für Variant, s für String, i für Integer, o für Object etc. pp.) finden.

    Ist aber zumindest ähnlich zu VBA.

  • Funktionsnamen mit Unterstrich

    • Kanashius
    • 27. Juni 2023 um 15:49

    Ich mach es so, dann kann man am besten zwischen den Funktionen unterscheiden.

    AutoIt
    GuiCtrlCreateEdit(...) ; AutoIt-Funktion
    __GuiCtrlEdit_Create(...) ; UDF-Funktion (mit AutoIt ausgeliefert)
    _GuiCtrlCreateEdit(...) ; Eigene Funktion (um z.B. ein Edit zu erstellen und schon nen Font,... an einer einheitlichen Stelle zu setzen, wenn man mehrere Controls braucht)
    __ExtendedEdit_GuiCtrlCreateEdit(...) ; Eigene UDF-Funktion (Wenn man selbst eine lib/UDF(user defined function) erstellt)

    Man kann die Funktionen natürlich auch anders benennen, aber mit dieser Notation sieht man auf den ersten Blick, ob es sich um eine Grundfunktion handelt, eine eigene Funktion, oder ob die Funktion aus einer UDF stammt (und auch aus welcher).

    Die UDF Notation nutze ich auch bei globalen Variablen in eine UDF, wenn ich eine erstelle. Z.b. Local $__ExtendedEdit_sEdit = 0. Dann hat man nicht das Problem, dass Konflikte mit den Namen entstehen und wenn man z.B. Konstanten verwendet weiß man auch direkt, aus welcher UDF die kommt.

    Ich finde das z.B. bei den mitgelieferten UDFs teilweise nervig, weil die Konstanten das dort nicht haben und du dann oft erstmal rausfinden musst, aus welcher UDF denn jetzt die blöde Konstante kommt. Oft am schnellsten in dem man nach nem Script Beispiel schaut und dort alle includes nimmt und nacheinander ausprobiert/auskommentiert :/. Die wenigsten wissen direkt, ob z.B. $ES_RIGHT aus GUIConstants.au3, GUIConstantsEx.au3 oder WindowsConstants,... kommt. Aber das ist das Problem, das entsteht, wenn man sich nicht einheitlich Festlegt (man muss es ja nicht vom Compiler erzwingen, sollte es aber als gewollten Stil angeben...). Das selbe Problem gibts auch mit zurückgegebenen Arrays. Manche Funktionen geben beim ersten Index ([0]) die Anzahl der Ergebnisse zurück, andere geben keine Anzahl zurück... Ich persönlich bin der Meinung, dass es dafür Ubound gibt und man Programmierinfos und Daten trennen sollte, aber es wurde halt nie eindeutig definiert, also gibts jetzt nen Wildwuchs von beidem und man hat halt manchmal das Problem, dass komische Fehler auftreten, weil plötzlich son extra Wert immer Array steht, der da nicht hingehört...

    Würde also empfehlen, das so zu handhaben, damit auch andere sich in deinem Code schneller zurechtfinden und direkt wissen, wo eine Funktion und deren Dokumentation denn zu finden ist.

  • Barcode Scanner mit Etiketten Drucker

    • Kanashius
    • 15. Juni 2023 um 13:42
    Zitat von Haldi

    Okay... ich seh ich hab wesentlich weniger Ahnung als ich gedacht habe^^


    Irgendwie muss da also im Else der Ignore Shift befehlt eingebaut werden....

    In Zeile 51 findest du den Aufruf der Methode Chr(). Wenn du die Hilfe dazu öffnest (anklicken und F1), dann Findest du unter "Remarks" einen Link zur ASCII Character Code table. Da stehen die Zahlen zu allen Zeichen drin.

    Ansonsten kannst du auch einfach nach Zeile 47 ein ConsoleWrite($iKeyCode&@crlf) einfügen. Dann bekommst du die Ausgabe des Zahlencodes, wenn du die Taste drückst und kannst einfach ausprobieren ;)

    In diesem Fall würde ich einfach das Else in Zeile 55 (Zeile 9 in dem Ausschnitt, den du gepostet hast) abändern zu ElseIf $iKeyCode<>0 Then. Damit sollten alle Tasten, die nichts ausgeben (wie SHIFT, ALT,...) keinen Unterschied mehr machen.

  • Barcode Scanner mit Etiketten Drucker

    • Kanashius
    • 14. Juni 2023 um 17:31

    Hi,

    Ich hatte gerade Zeit und fand das ganze interessant, also hab ich das mal mit Pattern-Matching umgesetzt.

    AutoIt
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    #include <WinAPIvkeysConstants.au3>
    OnAutoItExitRegister('OnAutoItExit')
    
    ;HotKeySet('{ESC}', '_exit')
    
    ;Global $sStart = StringUpper("TZProduktion-")
    Global $sStart = StringUpper("test")
    Global $arBuffer[200], $iBufferEnd = 0, $bBufferMatch = False, $arStart = StringSplit($sStart, "", BitOR(1, 2))
    
    Global $hKeyProc = DllCallbackRegister('_KeyProc', 'long', 'int;wparam;lparam')
    Global $hmod = _WinAPI_GetModuleHandle(0)
    Global $hKeyHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hKeyProc), $hmod)
    
    Global $iWidth = 300, $iHeigt = 200
    Global $hGui = GUICreate('Barcodescanner', $iWidth, $iHeigt)
    Global $idBarcode = GUICtrlCreateLabel('', 10, 10, $iWidth-20, 30)
    GUISetState(@SW_SHOW)
    
    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _exit()
        EndSwitch
    WEnd
    
    Func _barcodeFound($sBarcode)
        ConsoleWrite("FOUND: "&$sBarcode&@crlf)
    EndFunc
    
    Func _exit() ;just to enable the ESC hotkey
        Exit
    EndFunc
    
    ; ACHTUNG! Callback-Funktion!
    ; In dieser Funktion darf es keinen blockierenden Code (z.B. MsgBox, Sleep, etc.) geben!
    ; Hier werden direkt die virtuellen Keycodes der Tastatur ausgewertet:
    ; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
    Func _KeyProc($nCode, $wParam, $lParam)
        Local $tKBDLLHOOK = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
        Local $iKeyCode = $tKBDLLHOOK.vkCode, $iPressTime
        $iKeyCode = _WinAPI_MapVirtualKey($iKeyCode, $MAPVK_VK_TO_CHAR) ; needed for different keyboard layouts (e.g. US-layout - is ASCII 189, not 45 otherwise)
        If $nCode >= 0 Then
            Switch $wParam
                Case $WM_KEYUP
                    If $iKeyCode = 45 Or _
                        ($iKeyCode>=48 And $iKeyCode<=57) Or _
                        ($iKeyCode>=65 And $iKeyCode<=90) Then
                        $arBuffer[$iBufferEnd] = Chr($iKeyCode)
                        $iBufferEnd += 1
                        If $iBufferEnd>UBound($arBuffer)-1 Then $iBufferEnd = 0 ; Reset if longer than buffer, may lead to scan loss
                        If Not $bBufferMatch Then _checkBuffer()
                    Else
                        If $bBufferMatch Then _barcodeFound(_bufferToStr())
                        $bBufferMatch = False
                        $iBufferEnd = 0
                    EndIf
                    GUICtrlSetData($idBarcode, _bufferToStr())
                    ; Return 1
            EndSwitch
        EndIf
        Return _WinAPI_CallNextHookEx($hKeyHook, $nCode, $wParam, $lParam)
    EndFunc   ;==>_KeyProc
    
    Func _checkBuffer()
        Local $iCount = 0, $iStart = 0
        While $iCount<$iBufferEnd
            $iStart = $iCount
            While $iStart < $iBufferEnd
                If $arBuffer[$iStart] <> $arStart[$iStart-$iCount] Then
                    $iCount += 1
                    ContinueLoop 2
                EndIf
                If $iStart-$iCount >= UBound($arStart)-1 Then
                    $bBufferMatch = True
                    Return True
                EndIf
                $iStart+=1
            WEnd
            ExitLoop
        WEnd
        If $iCount<>0 Then
            Local $iDiff = $iBufferEnd-$iCount
            If $iDiff<=0 Then
                $iBufferEnd=0
            Else
                For $i=0 To $iDiff Step 1
                    $arBuffer[$i] = $arBuffer[$iCount+$i]
                Next
                $iBufferEnd=$iDiff
            EndIf
            Return False
        EndIf
        Return True
    EndFunc
    
    Func _bufferToStr()
        Local $sRes = ""
        For $i=0 To $iBufferEnd-1 Step 1
            $sRes &= $arBuffer[$i]
        Next
        Return $sRes
    EndFunc
    
    ; Wichtig! Beim Programmende den Hook wieder entfernen.
    Func OnAutoItExit()
        _WinAPI_UnhookWindowsHookEx($hKeyHook)
        DllCallbackFree($hKeyProc)
    EndFunc   ;==>OnAutoItExit
    Alles anzeigen

    Das Fenster ist optional, ich habs nur zum Anzeigen und Testen drin.

    In der Funktion _barcodeFound kannst du dann mit dem Code machen, was du möchtest. (Also auch dein Programm öffnen,...).

    Ich lese alle 0-9, A-Z und - Zeichen ein und füge sie zum Buffer hinzu. Wird eine andere Taste gedrückt, wird der Buffer zurückgesetzt, oder der Barcode als erkannt gemeldet (je nachdem, ob das Pattern passt oder nicht).

    Das betrifft auch Tasten wie SHIFT. Falls dein Scanner Groß/Klein-schreibung beachtet musst du evtl. den Code für SHIFT ignorieren, um nicht zurückzusetzen (Zeile 55). Dementsprechend ignoriert der Code auch Groß/Klein-Schreibung beim Pattern.

    Der Buffer hat max. 200 Zeichen, das ganze Funktioniert also nur, wenn dein Code weniger als 200 Zeichen hat. Ggf. musst du den Buffer anpassen, bis es für dich passt.

    Ich hab dabei auch festgestellt, dass man nicht einfach den KeyCode zum vergleichen verwenden sollte. Ich nutze eine Tastatur mit US-Layout und das - hat dort den vkCode 189 und nicht 45. Deshalb nutze ich die _WinAPI_MapVirtualKey um den Virtuellen Keycode auf den eigentlichen KeyCode umzuwandeln. Sollte man also immer machen; man weiß ja nie, was für eine Tastatur grad angeschlossen ist.

    Ich hoffe das hilft dir weiter :)

    MfG, Kanashius

  • Barcode Scanner mit Etiketten Drucker

    • Kanashius
    • 14. Juni 2023 um 15:25

    Hi,

    vor nicht allzu langer Zeit hatte jemand eine ähnliche Anfrage. Das wurde dort von Oscar mit einem Keyboardhook gelöst. Der Code kann relativ einfach auf dein Problem umgebaut werden. Einfach das Fenster weglassen und in der _KeyProc die Tasten erfassen. Dabei immer weiter in eine Variable schreiben, bis der Inhalt von dem gewollten Pattern abweicht. Bei einer Abweichung den Anfang wegnehmen, bis zum nächsten möglichen Anfang des Patterns.

    Den Code findest du hier: RE: Barcode in Variable scannen ohne den Inhalt irgendwo anzuzeigen

    Falls du das selbst nicht anpassen kannst, meld dich gerne wieder.

    MfG, Kanashius

  • GUI Menü - klickbar machen?

    • Kanashius
    • 26. Mai 2023 um 20:11

    Hi, weil ich im moment so gerne mit Maps programmiere würde ich es so machen:

    AutoIt
    #include <GUIConstantsEx.au3>
    
    Global $mMainGui[]
    $mMainGui.iWidth = 300
    $mMainGui.iHeight = 200
    
    $mMainGui.hGui = GUICreate("Menu example", $mMainGui.iWidth, $mMainGui.iHeight)
    
    Global $mMenus[]
    _addMenuEntry($mMenus, "menu1", "Menü 1")
    _addMenuEntry($mMenus, "menu1_1", "Menü 1.1", "menu1", "_menu1_1")
    _addMenuEntry($mMenus, "menu1_2", "Menü 1.2", "menu1", "_menu1_2")
    _addMenuEntry($mMenus, "menu1_2_1", "Menü 1.2.1", "menu1_2", "_menu1_2_1")
    _addMenuEntry($mMenus, "menu1_2_2", "Menü 1.2.2", "menu1_2")
    _addMenuEntry($mMenus, "menu2", "Menü 2", -1, "_menu2")
    _addMenuEntry($mMenus, "exit", "exit")
    _generateMenu($mMainGui.hGui, $mMenus)
    
    GUISetState(@SW_SHOW, $mMainGui.hGui)
    
    Local $arMenuKeys = MapKeys($mMenus), $iMsg
    While 1
        $iMsg = GUIGetMsg()
        If $iMsg<>0 Then
            Switch $iMsg
                Case $GUI_EVENT_CLOSE, $mMenus.exit.control
                    GUIDelete($mMainGui.hGui)
                    Exit
                Case $mMenus.menu1_2_2.control
                    MsgBox(64, "Info", "Menu 1.2.2")
                Case Else
                    For $i=0 To UBound($arMenuKeys)-1 Step 1
                        If $iMsg = $mMenus[$arMenuKeys[$i]].control And $mMenus[$arMenuKeys[$i]].func<>-1 Then Call($mMenus[$arMenuKeys[$i]].func)
                    Next
            EndSwitch
        EndIf
    WEnd
    
    Func _menu1()
        MsgBox(64, "Info", "Menu 1")
    EndFunc
    
    Func _menu1_1()
        MsgBox(64, "Info", "Menu 1.1")
    EndFunc
    
    Func _menu1_2()
        MsgBox(64, "Info", "Menu 1.2")
    EndFunc
    
    Func _menu1_2_1()
        MsgBox(64, "Info", "Menu 1.2.1")
    EndFunc
    
    Func _menu2()
        MsgBox(64, "Info", "Menu 2")
    EndFunc
    
    Func _generateMenu($hGui, ByRef $mMenuMap)
        Local $hOldGui = GUISwitch($hGui)
        Local $arMenuKeys = MapKeys($mMenuMap)
        For $i=0 To UBound($arMenuKeys)-1 Step 1
            Local $mEntry = $mMenuMap[$arMenuKeys[$i]]
            If $mEntry.hasChilds Then
                $mMenuMap[$arMenuKeys[$i]].control = GUICtrlCreateMenu($mEntry.name, $mEntry.parent<>-1?$mMenuMap[$mEntry.parent].control:-1, $mEntry.index)
            Else
                If $mEntry.parent = -1 Then
                    $mMenuMap[$arMenuKeys[$i]].control = GUICtrlCreateMenuItem($mEntry.name, -1, $mEntry.index, $mEntry.radio)
                Else
                    $mMenuMap[$arMenuKeys[$i]].control = GUICtrlCreateMenuItem($mEntry.name, $mMenuMap[$mEntry.parent].control, $mEntry.index, $mEntry.radio)
                EndIf
            EndIf
        Next
        GUISwitch($hOldGui)
    EndFunc
    
    Func _addMenuEntry(ByRef $mMenuMap, $sKey, $sName, $sParentKey = -1, $sFunc = -1, $iEntryIndex = -1, $bRadioItem = False)
        If Not MapExists($mMenuMap, $sKey) Then
            Local $mMap[]
            $mMenuMap[$sKey] = $mMap
        EndIf
        $mMenuMap[$sKey].name = $sName
        $mMenuMap[$sKey].func = $sFunc
        $mMenuMap[$sKey].parent = $sParentKey
        $mMenuMap[$sKey].index = $iEntryIndex
        $mMenuMap[$sKey].radio = $bRadioItem?1:0
        If Not MapExists($mMenuMap[$sKey], "hasChilds") Then $mMenuMap[$sKey].hasChilds = False
        If $sParentKey<>-1 Then
            If Not MapExists($mMenuMap, $sParentKey) Then
                Local $mParentMap[]
                $mMenuMap[$sParentKey] = $mParentMap
            EndIf
            $mMenuMap[$sParentKey].hasChilds = True
        EndIf
    EndFunc
    Alles anzeigen

    Bei der Methode kannst du dir auch aussuchen, ob du alle Menuitems in der Mainloop abarbeiten möchtest, oder ob du eine extra Funktion definieren willst.

    Extra Funktionen haben den Vorteil, dass deine Mainloop nicht groß und unübersichtlich wird und eine Funktionalität ohne Probleme im Menü oder über z.B. einen Button im Fenster ausgelöst werden soll.

    Würdest du z.B. "Save" im Menü "File" haben mit der Methode "_save" kannst du die auch automatisch alle 10min. aufrufen, über extra Buttons,...

    Deshalb arbeite ich gerne mit Funktionen statt sehr großen Mainloops.

    Statt _addMenuEntry($mMenus, "menu1", "Menü 1") solltest du natürlich sinnvolle Namen vergeben, wie z.B. _addMenuEntry($mMenus, "file", "File")

  • InetGet Funktioniert einach nicht...

    • Kanashius
    • 25. Mai 2023 um 10:58

    Hi, ich hab das Script umgeschrieben und Fehlerbehandlung hinzugefügt. Sollte man generell bei allen Scripts machen, um Fehler schneller zu finden.

    AutoIt
    #include <InetConstants.au3>
    #include <AutoItConstants.au3>
    
    _downloadFile()
    If @error Then
        MsgBox(16, "Error downloading", @error&" => "&@extended)
    Else
        MsgBox(64, "Info", "Download done.")
    EndIf
    
    Func _downloadFile()
        Local $bLocationData = InetRead('http://www.zockery.de/huch.php')
        If @error Then Return SetError(1, @error, False)
        Local $sLocationData = BinaryToString($bLocationData)
        ; Should be 0: URL, 1: Target-File
        Local $arLocationData = StringSplit($sLocationData, ";", BitOr(1, 2))
        If UBound($arLocationData)<>2 Then Return SetError(2, UBound($arLocationData), False)
        $arLocationData[0] = "http://"&$arLocationData[0]
        ConsoleWrite($arLocationData[0]&@TAB&$arLocationData[1]&@CRLF)
        ; Create parent directory
        DirCreate(StringRegExpReplace($arLocationData[1], "(.*)/[^/]*", "$1"))
    
        Local $hDownload = InetGet($arLocationData[0], $arLocationData[1], 1, 1)
        ProgressOn("Download" & @CRLF & "..." , "0%", -1, -1, BitOR($DLG_NOTONTOP, $DLG_MOVEABLE))
        Local $iDownloadSize = InetGetInfo($hDownload, $INET_DOWNLOADSIZE)
        Local $iProgress
        Do
            $iDownloadSize = InetGetInfo($hDownload, $INET_DOWNLOADSIZE)
            If $iDownloadSize=0 Then
                ProgressSet(50, InetGetInfo($hDownload, $INET_DOWNLOADREAD) & "/? bytes", "Downloading File")
            Else
                $iProgress = InetGetInfo($hDownload, $INET_DOWNLOADREAD)/$iDownloadSize*100
                ProgressSet($iProgress, round($iProgress,1) & "%", "Downloading File")
            EndIf
            Sleep(100)
        Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
    
        ConsoleWrite(InetGetInfo($hDownload, $INET_DOWNLOADERROR)&" : "&InetGetInfo($hDownload, $INET_DOWNLOADEXTENDED)&@crlf)
        ; Got Extended Error: 12006
        ; Look up at https://learn.microsoft.com/en-us/windows/win32/wininet/wininet-errors => ERROR_INTERNET_UNRECOGNIZED_SCHEME
    
        If InetGetInfo($hDownload, $INET_DOWNLOADERROR) Then Return SetError(3, InetGetInfo($hDownload, $INET_DOWNLOADERROR)&" : "&InetGetInfo($hDownload, $INET_DOWNLOADEXTENDED), False)
        InetClose($hDownload)
        ProgressSet(100, "100%", "Download Complete")
        Sleep(1000)
        ProgressOff()
    
        Return True
    EndFunc
    Alles anzeigen

    Ich hab mehrere Problemstellen gefunden:

    1. Bei InetGet muss der Ordner, in den die Datei heruntergeladen werden soll, bereits existieren => Ich erstell den Parent-Folder vorher.

    2. Bei InetGet muss das Schema der URL passen. Beim auslesen von $INET_DOWNLOADEXTENDED hab ich den Fehler 12006 bekommen. Nachgeschaut auf https://learn.microsoft.com/en-us/windows/…/wininet-errors steht der Fehler für ERROR_INTERNET_UNRECOGNIZED_SCHEME. Irgendetwas stimmt also mit der URL nicht. Dabei ist mir aufgefallen, dass http:// am Anfang fehlt und ich habs hinzugefügt. (InetGet fügt das nicht automatisch hinzu, so wie Browser, die annehmen, dass normalerweise eine http anfrage gemeint ist.)

    Jetzt läuft es bei mir (habs aber nicht bis zum Ende laufen lassen; keine Lust auf >100GB download :D)

  • Translate.google + Grafik

    • Kanashius
    • 24. Mai 2023 um 14:48

    Ich hätte noch einen anderen Ansatz, der ggf. komplizierter ist, aber von der Umsetzung einfacher.

    Man könnte mit OBS den Bildschirm aufnehmen und als Kamera zur Verfügungstellen.

    Für Android gibt es bei der Google-Translate-App die Möglichkeit für live Übersetzung.

    Es sollte also theoretisch möglich sein, mit nem Emulator (Windows 11 hat ja auch einen eingebaut, meine ich, hab den aber noch nicht getestet => Nutze Win10) das ganze am PC laufen zu lassen und die OBS Kamera im Emulator zu nutzen.

    Ich habs nicht getestet, sollte aber theoretisch funktionieren.

    MfG, Kanashius.

    PS: Warum gibt es solche Funktionen nur fürs Handy als App und nicht am PC, wo man eh viel mehr Ressourcen hat das lokal laufen zu lassen :Face:

  • Arrayreihenfolge

    • Kanashius
    • 13. Mai 2023 um 20:59

    Hi Alina,

    ich hab das ganze mal umgesetzt, so wie ich es verstanden habe. Am Ende besteht nur das Problem, dass die letzten Werte nicht zugeordnet werden können, da das Positions-Array kein Vielfaches vom Value-Array ist...

    Es geht sich also am Ende nicht aus, oder man hätte leere Zellen. In der Lösung wird das Ende erstmal weggelassen, ggf. kannst du ja klarstellen, was dann passieren soll.

    Außerdem: Position <> Index? Bei mir sind die Einträge einen Wert höher, weil man beim Programmieren mit 0 anfängt, nicht mit 1.

    Ansonsten hier das Script:

    AutoIt
    #include <Array.au3>
    
    Global $arValues =  ["DK45","DK28","963","NOR17","731","575","276","679","366","NOR15","NOR58","NOR23","958","166","909","478","634","846","744","525","701","77","162","211","51DK","873","401", _
                         "909","717","52","552","707","327","782","705","644","47","524","596","NOR88","246","700","197","696","497","913","35","99","DK42","725","652","584","701","36","296","402", _
                         "483","961","NOR87","9","482","944","613","161","205","657","734","329","791","750","731","196","437","312","979","489","NOR55","787","39","FIN01","764","344","745","666", _
                         "733","37","273","38","784","797","109","903","340","272","742","426","127","206","623","842","DK45","DK28","963","NOR17","731","575","276","679","366","NOR15","NOR58", _
                         "NOR23","958","166","909","478","634","846","744","525","701","77","162","211","51DK","873","401","909","717","52","552","707","327","782","705","644","47","524","596", _
                         "NOR88","246","700","197","696","497","913","35","99","DK42","725","652","584","701","36","296","402","483","961","NOR87","9","482","944","613","161","205","657","734", _
                         "329","791","750","731","196","437","312","979","489","NOR55","787","39","FIN01","764","344","745","666","733","37","273","38","784","797","109","903","340","272","742", _
                          "426","127","206","623","842","39","954","99NOR","FIN2","388"]
    
    Global $iPosBegin = 55
    ;,Reihenfolge,64,Werte
    Global $arPositions =     [55,30,17,42,27,36,15,38,18,43,54,29,16,39,26,35,31,56,41,20,33,28,37,14,44,19,32,53,40,13,34,25,57,2,45,8,21,64,51,12,46,5,60,1,52,9,24,63,3,58,7,48,61,22,11,50,6,47, _
                             4,59,10,49,62,23]
    
    Local $arRes = _sortByArray($arValues, $arPositions, $iPosBegin)
    If @error Then MsgBox(16,"Error",@error&" => "&@extended)
    _ArrayDisplay($arRes)
    
    
    ; $arValues => Values to sort
    ; $arPos => Positions to sort to
    ; $iStartValue => First position to start with; Default => Start with $arPos index 0; If $iStartValue is not in $arPos => Start with $arPos index 0; Starts with the first position found
    Func _sortByArray(ByRef $arValues, ByRef $arPos, $iStartValue = Default)
        Local $iStartIndex = 0
        If $iStartValue<>Default Then
            For $i=0 To UBound($arPos)-1 Step 1
                If $iStartValue=$arPos[$i] Then
                    $iStartIndex = $i
                    ExitLoop
                EndIf
            Next
        EndIf
        Local $iIndex = $iStartIndex
        Local $iPosCount = UBound($arPos)
        Local $arResult[UBound($arValues)]
        Local $iPassCount = 0
        For $i=0 To UBound($arValues)-1 Step 1
            Local $iTmpIndex = $iPassCount*$iPosCount+$arPos[$iIndex] - 1 ; -1 because positions in $arPos start with 1 and not 0
            If $iTmpIndex>=UBound($arValues) Or $iTmpIndex<0 Then
                ;Return SetError(1, $iTmpIndex, -1) ; check if new index is in range
            Else
                $arResult[$iTmpIndex] = $arValues[$i]
            EndIf
            $iIndex+=1
            If $iIndex>=UBound($arPos) Then $iIndex=0
            If $iIndex=$iStartIndex Then $iPassCount+=1
        Next
        Return $arResult
    EndFunc
    Alles anzeigen

    MfG, Kanashius

  • Labelaktualisierung will wieder mal nicht

    • Kanashius
    • 9. Mai 2023 um 18:08

    Ich hab selbst keinen echten Drucker (nur Software wie Adobe PDF), kann dir da also leider nicht weiterhelfen :(

    Deshalb hab ich bei dem Drucker-Zeug eigentlich nur deinen Code genommen und wiederverwendet (und reduntantes rausgenommen; Das waren aber nur String Ersetzungen).

    GGf. ersetz mal alle Run commands mit nem Consolewrite und vergleich die Ausgabe, die der Code jetzt gibt, mit der, die der Code vorher gegeben hat.

    Dann siehst du die Unterschiede und man kann das Beheben.

  • Labelaktualisierung will wieder mal nicht

    • Kanashius
    • 6. Mai 2023 um 22:17

    Hi,

    In Zeile 24 wird die Variable deklariert, die du nutzen musst.

    Also statt $mPrinterGuiData.idNetworkPrinters musst du $mPrinter.idNetworkPrinters nutzen.

    $mPrinterGuiData ist nur Lokal in der Funktion _createPrinterGui vorhanden.

    Dadurch kannst du theoretisch beliebig viele Druck-Fenster erstellen und verwalten.

    Dazu müsstest du nur alle erstellten Gui-Handle mit $mPrinterGuiData beim erstellen in der _createPrinterGui in eine Map werfen und dann entsprechend bei allen Button,... (GuiOnEventMode)-Funktionen mit dem Makro @GUI_WinHandle die Variable zu der GUI aus der Map holen.

    Das ganze würde dann so aussehen:

    AutoIt
    #include-once
    #include <ButtonConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <ComboConstants.au3>
    #include <MsgBoxConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListBox.au3>
    #include <GuiComboBox.au3>
    
    Opt("GUIOnEventMode", 1)
    #NoTrayIcon
    
    Global $SubBack = 0xFFFFFF, $sBeepFile="", $mPrinterGuis[]
    Global $sPrintServer = "Druck.vwlt.antrax-berlin.de"
    
    
    $hMainGui = GUICreate("Some Window", 600, 400)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_close", $hMainGui)
    
    $idButton = GUICtrlCreateButton("Printers", 10, 10)
    GUICtrlSetOnEvent(-1, "_openPrinters")
    
    Global $mPrinter = _createPrinterGui($hMainGui)
    If @error Then MsgBox(16, "Error", "Fehler bei der Initialisierung des Druckerfensters: "&@error&":"&@extended)
    
    
    GUICtrlCreateButton("Printers2", 10, 40)
    GUICtrlSetOnEvent(-1, "_openPrinters2")
    Global $mPrinter2 = _createPrinterGui($hMainGui)
    If @error Then MsgBox(16, "Error", "Fehler bei der Initialisierung des Druckerfensters: "&@error&":"&@extended)
    
    
    GUISetState(@SW_SHOW, $hMainGui)
    
    
    While Sleep(100)
    WEnd
    
    Func _openPrinters()
        _updatePrinters($mPrinter)
        GUISetState(@SW_SHOW, $mPrinter.Gui)
    EndFunc
    
    Func _openPrinters2()
        _updatePrinters($mPrinter2)
        GUISetState(@SW_SHOW, $mPrinter2.Gui)
    EndFunc
    
    Func _close()
        Exit
    EndFunc
    
    ; Creates and shows the printer gui and returns a map with printer data:
    ;    $mPrinterGuiData.Gui                     => Gui handle
    ;    $mPrinterGuiData.idDefaultPrinter         => Label with name of default printer
    ;    $mPrinterGuiData.idInstalledPrinters     => List with installed printers
    ;    $mPrinterGuiData.idConnectedPrinters    => List with connected printers
    ;    $mPrinterGuiData.idNetworkPrinters        => Combo with network printers
    ;    $mPrinterGuiData.idNoPrintServer        => Label to show, that no network printers are available
    ;    $mPrinterGuiData.idTestprint            => Button for Testprinting
    ;    $mPrinterGuiData.idSettings                => Button for Settings
    ;    $mPrinterGuiData.idPreferences            => Button for Preferences
    ;    $mPrinterGuiData.idQueue                => Button for Queue
    ;    $mPrinterGuiData.idPrintfolder            => Button for Printfolder
    ;    $mPrinterGuiData.idDefault                => Button for Default printer
    ; Errors:     1 - Gui could not be created
    ;             2 - Default printer could not be found (extended contains the _getDefaultPrinter error)
    ;------------------------------------------------------------------------------------------------------------------------
    Func _createPrinterGui($hParent)
        Local $iWidth = 430, $iHeight = 430, $iBorder = 10, $iWidthRight = 100, $iListHeight = 120, $iLineHeight = 30
        Local $iWidthLeft = $iWidth-$iWidthRight-$iBorder*3
        Local $mPrinterGuiData[]
        Global $aList = _getNetworkPrinters()
    
        ; Create Gui
        $mPrinterGuiData.Gui = GUICreate("DRUCKER ZUWEISEN", $iWidth, $iHeight, -1, -1, -1, -1, $hParent)
        If @error Then Return SetError(1, 0, -1)
        GUISetOnEvent($GUI_EVENT_CLOSE, "_closePrinterGui", $mPrinterGuiData.Gui)
        GUISetBkColor($SubBack, $mPrinterGuiData.Gui)
    
    
        ; create left column
        Local $iTop = $iBorder
    
        ; default printer
        GUICtrlCreateLabel("Standarddrucker: ", $iBorder, $iTop, $iWidth-$iBorder*2, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        $mPrinterGuiData.idDefaultPrinter = GUICtrlCreateLabel("", $iBorder, $iTop, $iWidth-$iBorder*2, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        _updateDefaultPrinter($mPrinterGuiData.idDefaultPrinter)
    
    
    
        ; installed printers
        ;$iTop += $iLineHeight
        GUICtrlCreateLabel("Installierte Drucker: ", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        Local $iRightColumnTop = $iTop
        $mPrinterGuiData.idInstalledPrinters = GUICtrlCreateList("", $iBorder, $iTop, $iWidthLeft, $iListHeight)
        GUICtrlSetOnEvent(-1, "_selPrinterLimitToOne")
        $iTop += $iListHeight+$iLineHeight
        _updateInstalledPrinters($mPrinterGuiData.idInstalledPrinters)
    
    
    
        ; connected printers
        GUICtrlCreateLabel ( "Verbundene Drucker: ", 10, 220, 120, 20 )
       GUICtrlSetFont(-1, 9, 900) ; bold
        $mPrinterGuiData.idConnectedPrinters = GUICtrlCreateList("", $iBorder, $iTop, $iWidthLeft, $iListHeight)
        GUICtrlSetOnEvent(-1, "_selPrinterLimitToOne")
        $iTop += $iListHeight
        _updateConnectedPrinters($mPrinterGuiData.idConnectedPrinters)
    
    
    
        ; network printers
        GUICtrlCreateLabel("Netzwerkdrucker einbinden: ", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        $mPrinterGuiData.idNoPrintServer = GUICtrlCreateLabel("Kein Druckserver", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        GUICtrlSetFont(-1, 9, 900) ; bold
        GUICtrlSetState(-1, $GUI_HIDE)
    
    
        $mPrinterGuiData.idNetworkPrinters = GUICtrlCreateCombo("", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += 50
         GUICtrlSetOnEvent(-1, "_conPrinter")
        _updateNetworkPrinters($mPrinterGuiData.idNetworkPrinters, $mPrinterGuiData.idNoPrintServer)
    
    
        ; create right column
        Local $arButtons = [["idTestprint", "Testdruck", "_doTestPrint"],["idSettings", "Einstellungen", "_openSettings"],["idPreferences", "Eigenschaften", "_openPreferences"], _
                            ["idQueue", "Warteschlange", "_openQueue"],["idPrintfolder", "Druckerordner", "_openPrintFolder"],["idDefault", "Standard", "_setDefaultPrinter"], _
                            ["idDelete", "Delete", "_DeletePrinter"], ["idIPlist", "IP-List", "_IPList"]]
        For $i = 0 To UBound($arButtons)-1 Step 1
            ;$mPrinterGuiData[$arButtons[$i][0]] = GUICtrlCreateButton($arButtons[$i][1], $iBorder*2+$iWidthLeft, $iRightColumnTop+$iBorder+($iLineHeight+$iBorder)*$i, $iWidthRight, $iLineHeight)
            $mPrinterGuiData[$arButtons[$i][0]] = GUICtrlCreateButton($arButtons[$i][1], $iBorder*2+$iWidthLeft, $iRightColumnTop-0+($iLineHeight+$iBorder)*$i, $iWidthRight, $iLineHeight)
            GUICtrlSetOnEvent(-1, $arButtons[$i][2])
        Next
    
        $mPrinterGuis[$mPrinterGuiData.Gui] = $mPrinterGuiData
        GUISwitch($hParent)
        Return $mPrinterGuiData
    EndFunc
    ;------------------------------------------------------------------------------------------------------------------------
    
    Func _conPrinter()
        Local $sText = GUICtrlRead($mPrinterGuis[@GUI_WinHandle].idNetworkPrinters)
        MsgBox('262144', "printer", $sText)
        ;RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /in /n  " & _getSelectedPrinter() & $sText)
        ;RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /q /y /n "  & _getSelectedPrinter() & $sText)
        MsgBox('262144', "Default printer", "Default printer set to: " & $sText)
    endFunc
    
    Func _IPList()
          If  IsArray($aList) = "" Then
           MsgBox(262144,"Title", "keine Netzerkdrucker verfügbar! ")
          else
           _ArrayDisplay($aList)
          EndIF
    EndFunc
    
    Func _selPrinterLimitToOne()
        _GUICtrlListBox_SetCurSel(@GUI_CtrlId=$mPrinterGuis[@GUI_WinHandle].idConnectedPrinters?$mPrinterGuis[@GUI_WinHandle].idInstalledPrinters:$mPrinterGuis[@GUI_WinHandle].idConnectedPrinters, -1)
    EndFunc
    
    Func _updatePrinters($mPrinterGuiData)
        _updateDefaultPrinter($mPrinterGuiData.idDefaultPrinter)
        _updateInstalledPrinters($mPrinterGuiData.idInstalledPrinters)
        _updateConnectedPrinters($mPrinterGuiData.idConnectedPrinters)
        _updateNetworkPrinters($mPrinterGuiData.idNetworkPrinters, $mPrinterGuiData.idNoPrintServer)
    EndFunc
    
    Func _closePrinterGui()
        GUISetState(@SW_HIDE, $mPrinterGuis[@GUI_WinHandle].Gui)
    EndFunc
    
    Func _networkPrinterSelection()
        Local $sPrinter = GUICtrlRead($mPrinterGuis[@GUI_WinHandle].idNetworkPrinters)
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /in /n  \\" & $sPrintServer &"\"& $sPrinter)
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /q /y /n \\"  & $sPrintServer &"\"& $sPrinter)
        MsgBox('262144', "Default printer", "Default printer set to: " & $sPrinter)
    EndFunc
    
    Func _doTestPrint()
        SoundPlay($sBeepFile)
        Local $sPrinter = _printExec("/k")
        If Not @error Then MsgBox('262144', "TestDruck", "Der TestDruck wurde an den Drucker """ & _getSelectedPrinter() & """ abgeschickt!" & @CRLF & "Bitte überprüfen Sie den Ausdruck.")
    EndFunc
    
    Func _openSettings()
        SoundPlay($sBeepFile)
        _printExec("/e")
    EndFunc
    
    Func _openPreferences()
        SoundPlay($sBeepFile)
        _printExec("/p")
    EndFunc
    
    Func _openQueue()
        SoundPlay($sBeepFile)
        _printExec("/o")
    EndFunc
    
    Func _openPrintFolder()
        SoundPlay($sBeepFile)
        Run("rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder")
    EndFunc
    
    Func _setDefaultPrinter()
        SoundPlay($sBeepFile)
        Local $sPrinter = '"' & GUICtrlRead($mPrinterGuis[@GUI_WinHandle].idInstalledPrinters) & '"'
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /q /y /n " & $sPrinter)
        _updateDefaultPrinter($mPrinterGuis[@GUI_WinHandle].idDefaultPrinter)
    EndFunc
    
    Func _printExec($sCommand)
        Local $sPrinter = _getSelectedPrinterAbs()
        If @error Then Return SetError(1, 0, -1)
        RunWait( "rundll32 printui.dll,PrintUIEntry /n " & $sPrinter & " "&$sCommand )
        If @error Then Return SetError(2, 0, -1)
        Return $sPrinter
    EndFunc
    
    ; Returns the selected printer with the absolute path including \\ and the computer name
    Func _getSelectedPrinterAbs()
        Local $sPrinter = _getSelectedPrinter()
        If @error Then Return SetError(1, 0, -1)
        If Not StringInStr($sPrinter, "\\") Then $sPrinter = '"\\' & @ComputerName & "\" & $sPrinter & '"'
        Return $sPrinter
    EndFunc
    
    Func _getSelectedPrinter()
        Local $sPrinter = GUICtrlRead($mPrinterGuis[@GUI_WinHandle].idInstalledPrinters)
        If $sPrinter = "" Then $sPrinter = GUICtrlRead($mPrinterGuis[@GUI_WinHandle].idConnectedPrinters)
        If $sPrinter = "" Then
            MsgBox(16, "Druckerauswahl", "Es wurde kein Drucker ausgewählt!")
            Return SetError(1, 0, -1)
        EndIf
        Return $sPrinter
    EndFunc
    
    Func _updateDefaultPrinter($idLabel)
        Local $sDefaultPrinter = _getDefaultPrinter()
        If @error Then Return SetError(2, @error, -1)
        GUICtrlSetData($idLabel, $sDefaultPrinter)
        Return 1
    EndFunc
    
    Func _updateInstalledPrinters($idList)
        _GUICtrlListBox_ResetContent($idList)
        Local $iCount = 1
        While True
            Local $sPrinterName = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers", $iCount)
            If @error = -1 Then ExitLoop
            $iCount+=1
            _GUICtrlListBox_AddString($idList, $sPrinterName)
        WEnd
        _GUICtrlListBox_SelectString($idList, _getDefaultPrinter())
        Return 1
    EndFunc
    
    ;----------------------------------------------------
    Func _updateConnectedPrinters($idList)
        _GUICtrlListBox_ResetContent($idList)
        Local $iCount = 1
        While True
            Local $sPrinterName = RegEnumKey("HKEY_CURRENT_USER\Printers\Connections", $iCount)
            If @error = -1 Then ExitLoop
            $iCount+=1
             Local $arPrinter = StringSplit($sPrinterName, ",")
            If UBound($arPrinter)>1 Then _GUICtrlListBox_AddString($idList, $arPrinter[4])
        WEnd
        _GUICtrlListBox_SelectString($idList, _getDefaultPrinter())
        Return 1
    EndFunc
    
    Func _updateNetworkPrinters($idCombo, $idLabel)
        _GUICtrlComboBox_ResetContent($idCombo)
        Local $arPrinters = _getNetworkPrinters()
        If Not IsArray($arPrinters) Then
            GUICtrlSetState($idCombo, $GUI_HIDE)
            GUICtrlSetState($idLabel, $GUI_SHOW)
        Else
            GUICtrlSetState($idCombo, $GUI_SHOW)
            GUICtrlSetState($idLabel, $GUI_HIDE)
            For $i=1 To UBound($arPrinters)-1 Step 1
                If $arPrinters[$i][0] <> "" Then _GUICtrlComboBox_AddString($idCombo, $arPrinters[$i][0])
            Next
        EndIf
        Return 1
    EndFunc
    
    
    
    ; Returns the name of the default printer;
    ; Errors:     1 - Registry entry could not be read
    ;             2 - Registry entry could not be parsed
    Func _getDefaultPrinter()
        Local $sDefaultPrinter = RegRead( "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\windows", "Device")
        If @error Then Return SetError(1, 0, -1)
        Local $arDefaultPrinter = StringSplit($sDefaultPrinter, ",")
        If UBound($arDefaultPrinter)>0 Then Return $arDefaultPrinter[1]
        Return SetError(2, 0, -1)
    EndFunc
    
    ;-------------------------------------------------------------------------------------------------------------------
    ; Returns a 2D array with network printers: 0 name; 1 driverName; 2 portName; 3 Shared; 4 ShareName; 5 Published; 6 Local; 7 Location; 8 DeviceID; 9 DriverName
    ; Errors:     1 - Printserver file does not exist
    ;             2 - Printer query failed
    ;             3 - No printers found
    Func _getNetworkPrinters()
        If Not FileExists("\\"&$sPrintServer&"\c$") Then Return SetError(1, 0, -1)
    
        Local $objWMIService = ObjGet("winmgmts:\\" & $sPrintServer & "\root\CIMV2")
        Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Printer')
        If Not IsObj($colItems) Then Return SetError(2, 0, -1)
        If Not $colItems.count Then Return SetError(3, 0, -1) ; No Printer found
        Local $aPrinter[$colItems.count][10], $i = 0
        For $oItem In $colItems
            $aPrinter[$i][0] = $oItem.Name
            $aPrinter[$i][1] = $oItem.DriverName
            $aPrinter[$i][2] = $oItem.PortName
            $aPrinter[$i][3] = $oItem.Shared
            $aPrinter[$i][4] = $oItem.ShareName
            $aPrinter[$i][5] = $oItem.Published
            $aPrinter[$i][6] = $oItem.Local
            $aPrinter[$i][7] = $oItem.Location
            $aPrinter[$i][8] = $oItem.DeviceID
            $aPrinter[$i][9] = $oItem.DriverName
            $i += 1
        Next
        Return $aPrinter
         _ArrayDisplay($aPrinter)
    EndFunc
    Alles anzeigen

    Ich hab auch das globale $sText entfernt... global wird NUR im Notfall genutzt, wenn man Daten über mehrere Funktionen austauschen muss. Versuch das so oft wie möglich zu vermeiden, indem Funktionen Werte zurückgeben oder als Parameter übergeben bekommen. Das ist auch der Grund, warum ich die Map mit den $mPrinterGuiData.Gui, $mPrinterGuiData.idDefaultPrinter,... nutze. Die müsste sonst alle global sein und würden verhindern, dass mehrere Fenster gleichzeitig erstellt werden können und machen den Code allgemein unübersichtlich, wenn auf einmal Globale Variablen überall in Funktionen auftauchen wird das schnell unübersichtlich. Besonders wenn es nichtssagende namen wie $sText sind. Was für ein Text, woher, wo wird er verwendet,...

    $mPrinterGuis z.B. sagt eindeutig: Es ist eine Map mit mehreren Printer-Guis. => Eindeutig, was es ist. Selbiges beim $sPrintServer: Es ist der server unter dem die Drucker erreichbar sind.

    $sText: Ist ein Text, der ? ist und wo verwendet wird?

    Das birgt auch die Gefahr, dass du $sText noch woanders nutzt und dann ausversehen die eine Variable die andere Überschreibt, wenn das nicht beabsichtigt ist,... Viel Spaß beim Fehler finden :D

    MfG, Kanashius

  • Download der Avast-Free-Offline-Dateien klappt seit ein paar Tagen nicht mehr mit AutoIt ... ?

    • Kanashius
    • 4. Mai 2023 um 19:40

    Bei mir (Win10/Keine Firewall/Kein Antivirus) funktioniert es auch ohne Probleme. Also geb ich dir noch was zum nachschauen:

    Hast du dabei auch die Windows-Firewall UND den Windows-Defender (Integrierter Virenschutz von Windows) schon ausgeschaltet?

    Hast du einen Router/Firewall/.... , die das Blockieren könnte?

    Hat dein DNS resolver ein Problem, die Domain aufzulösen? => ping mal bits.avcdn.net

    Nutzt Avast Cloudflare oder ähnliches, sodass eventuell die IP gesperrt wurde (Wurde schon teilweise bei Urheberrechtsverletzungen in Österreich gemacht (auch wenn das wieder rückgängig gemacht wurde, meine ich))?

    Ne Überlegung: Brauchst du Avast wirklich? Der Windows-Defender ist mitlerweile genausogut wie andere Antivirenprogramme, aufgrund der großen Reichweite (überall mit Windows vorinstalliert) vermutlich sogar besser, deshalb lohnt es sich eigentlich nicht, den zu ersetzen.

  • Download der Avast-Free-Offline-Dateien klappt seit ein paar Tagen nicht mehr mit AutoIt ... ?

    • Kanashius
    • 4. Mai 2023 um 11:35

    Falls du mehrere Antivirenprogramme hast macht dir vllt. auch Avast probleme (auch wenn man normal nicht mehr als ein Antivirenprogramm gleichzeitig laufen lassen sollte):

    Virenschutz: Avira stört Firefox
    Zahlreiche Firefox-Nutzer haben Probleme beim Aufrufen von Webseiten. Der Störenfried ist der Avira-Virenschutz.
    www.heise.de

    :rofl:

    :ironie:

  • Labelaktualisierung will wieder mal nicht

    • Kanashius
    • 1. Mai 2023 um 17:40
    Zitat

    Eine sehr interessante Art und Weise die Buttons zu erzeugen (mit Arrays), wusste ich gar nicht dass das geht, wobei ich mir trotzdem die Frage stelle, ob dass irgendwie einen Geschwindigkeitsvorteil oder so am Ende mitbringt..

    Ich nutze das gerne, um die Controls einfacher zu generieren. Es sorgt dafür, dass ich die Controls in einer Schleife generieren kann und somit deutlich weniger Zeilen Code habe, gerade wenn man noch Schriftgröße, Farbe,... ändern will oder so, dann kommen schnell >4 Zeilen pro Control. Ist für mich übersichtlicher und schneller zu erweitern. Außerdem ist es einfacher, die Position der Controls anzugeben, weil man einfach mit START+(CONTROLHEIGHT+SPACE)*$i die Höhe berechnet und dann nur an der Stelle was ändern muss, wenn man alle Controls z.B. 20px höher haben will.

    Zitat

    Noch eine Interessante Einlassung fand ich deine Bemerkung, dass ich mit GUISetOnEvent eine existierende Haupt Gui weiter bedienbar halte, ist das wirklich so, bisher habe ich immer gelsen, dass Autoi eine solche Multitaskingfähigkeit wohl eher nicht hätte, aber vielleicht war das ja Unsinn, ich lasse mich gerne eines besseren belehren.

    AutoIt hat nicht wirklich Multitasking, es hat aber begrenzt Asynchrone Fähigkeiten. Windows-Events (wie z.B. Mausklicks, Tastatur,...) unterbrechen quasi das eigentliche Programm und werden zuerst ausgeführt. Du kannst dir das so vorstellen, dass normalerweise, wenn du auf ein Control klickst, AutoIt im Hintergrund den klick wahrnimmt und in einem Array speichert. Wenn du dann GuiGetMsg aufrufst schaust du in dem Array nach, was denn in der Zwischenzeit an Events passiert ist. Beim GuiOnEventMode wird statt das Event in dem Array zu speichern, direkt die angegebene Funktion aufgerufen und ausgeführt. Deshalb wird quasi der eigentliche Code unterbrochen, die Methode ausgeführt und dann wird der Code an der Vorherigen Stelle weiter ausgeführt. Beim GuiOnEventMode hat man deshalb quasi eine leere While-Schleife, die dann bei jedem Event unterbrochen wird und danach weiter läuft. Selbiges passiert übrigens auch bei AdlibRegister. Du kannst also AdlibRegister nutzen um Dinge "nebenbei" auszuführen.

    Zitat

    Warum dein Code bei mir nicht läuft ist mir aber schleierhaft, dass gab es ja schön öfter hier, vielleicht fehlt mir ja auch eine UDF.

    Ich hab nur die UDFs genutzt, die AutoIt mitliefert. Ggf. kann es sein, dass du eine ältere Version nutzt. Ich habe v3.3.16.1 als Basis genommen.

    Zitat

    Haste wahrscheinlich extra reingemacht, damit ich was zum tüfteln habe lach.

    Ne, ich nutze das tatsächlich immer. Ich bin der Meinung, dass man Daten und Programmier-Informationen strikt trennen sollte und es ein unding ist, in nem Array die Größe vorne reinzuschreiben.

    Ich hatte schon oft das Problem, dass man beim Programmieren kurz nicht dran denkt (AutoIt ist da nämlich nicht mal konsistent; es ist mal so mal so) und dann länger sucht, bis man den Fehler findet.

    Fehlerquellen sollten so oft wie möglich vermieden werden.

    Zitat

    Warum die Combo nicht will ist mir immer noch rätselhaft

    Schau mal, ob es auftaucht, wenn du das Fenster größer machst (in der Höhe).

    Zitat

    irgendwie entscheiden, ob es ein Lokaler Drucker ist oder nicht, da sonst der Druckerstring nur bei den lokalen geht.

    Schau mal in _getSelectedPrinter Zeile 183/184. Dort wird rausgefunden, ob ein Lokal installierter oder ein Verbundener (?Netzwerk) Drucker ausgewählt ist.

    Zitat

    Wie kommt man eigentlich darauf, also als mit durchschnittlichr Fantasie ausgestatteter Mensch auf die Idee, dass es eine Funktion Namens _GUICtrlListBox_SetCurSel gibt?

    Die Namensgebung in AutoIt ist meiner Meinung nach etwas gewöhnungsbedürftig. Ich hab selbst zum Beispiel nen Moment gebraucht um _GUICtrlListBox_ResetContent zu finden, weil ich nach sowas wie _GUICtrlListBox_Clear gesucht habe. Generell würd ich sagen: Wenn du irgendwas mit nem Control machen willst, schau mal die User definied funktions zu dem Control in der Hilfe durch, welche Funktionen es alles gibt. Für die meisten Controls sind sie ähnlich und man wird schneller, die passenden Funktionen zu finden.

    Zitat

    Ich sehe gerade Deinen Code durch und weiss jetzt wass du mit Einrückungen meintest, ich habe Dir wohl zu viele gemacht, hat etwas gedauert;) Du hast ja so gut wie gar keine. schein wohl Geschmackssache zu sein, mach ich keine, bekomm ich auf den Deckel, mach ich welche krieg ich auch;)

    Ne, ich meinte tatsächlich die Tabs/Leerzeichen am Anfang einer Zeile. Jeder macht unterschiedlich viele Leerzeilen. Ich bin eher Sparsammer damit, weil es für mich nicht übersichtlicher ist, nach fast jeder Zeile ne Leerzeile zu haben und ich lieber mehr Zeilen auf einmal sehen will. Ist aber natürlich Geschmackssache.

    Ich dachte z.B. an Zeile 49-59 in deinem Original geposteten Script und daran, dass die Funktion,... nicht passend (mit Tabs/Leerzeichen) eingrückt sind. Passiert auch manchmal auf der Webseite hier, weil Leerzeichen/Tabs Probleme machen,... Bei der Einrückung gibts bei mir keine Geschmackssache, die muss korrekt sein, weil man nur dadurch gut/schnell sehen kann, wo Funktionen/Schleifen/Ifs anfangen/enden... Das gehört zu sauberen Code dazu. Es hat nen Moment gedauert, bis ich gesehen habe, wo z.B. deine erste Funktion (_form2) endet.

    Lg, Kanashius :)

  • Labelaktualisierung will wieder mal nicht

    • Kanashius
    • 28. April 2023 um 23:55

    Hi, ich hab den ganzen Code mal umstrukturiert. Dazu kommen dann ein paar Hinweise, was ich geändert hab. Ich hab dabei auch umgesetzt, was du am Ende erfragt hast: Aus den beiden Listen kann immer nur ein Eintrag gleichzeitig ausgewählt werden und der ausgewählte Drucker wird verwendet, egal aus welcher Liste.

    AutoIt
    #include <GUIConstantsEx.au3>
    #include <GuiListBox.au3>
    #include <GuiComboBox.au3>
    Opt("GUIOnEventMode", 1)
    
    Global $SubBack = 0xFFFFFF, $sBeepFile=""
    Global $sPrintServer = "Druck.vwlt.antrax-berlin.de"
    
    $hMainGui = GUICreate("Some Window", 600, 400)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_close", $hMainGui)
    
    $idButton = GUICtrlCreateButton("Printers", 10, 10)
    GUICtrlSetOnEvent(-1, "_openPrinters")
    
    Global $mPrinter = _createPrinterGui()
    If @error Then MsgBox(16, "Error", "Fehler bei der Initialisierung des Druckerfensters: "&@error&":"&@extended)
    
    GUISetState(@SW_SHOW, $hMainGui)
    
    
    While Sleep(100)
    WEnd
    
    Func _openPrinters()
        _updatePrinters($mPrinter)
        GUISetState(@SW_SHOW, $mPrinter.hGui)
    EndFunc
    
    Func _close()
        Exit
    EndFunc
    
    ; Creates and shows the printer gui and returns a map with printer data:
    ;     $mPrinterGuiData.hGui                     => Gui handle
    ;    $mPrinterGuiData.idDefaultPrinter         => Label with name of default printer
    ;    $mPrinterGuiData.idInstalledPrinters     => List with installed printers
    ;    $mPrinterGuiData.idConnectedPrinters    => List with connected printers
    ;    $mPrinterGuiData.idNetworkPrinters        => Combo with network printers
    ;    $mPrinterGuiData.idNoPrintServer        => Label to show, that no network printers are available
    ;    $mPrinterGuiData.idTestprint            => Button for Testprinting
    ;    $mPrinterGuiData.idSettings                => Button for Settings
    ;    $mPrinterGuiData.idPreferences            => Button for Preferences
    ;    $mPrinterGuiData.idQueue                => Button for Queue
    ;    $mPrinterGuiData.idPrintfolder            => Button for Printfolder
    ;    $mPrinterGuiData.idDefault                => Button for Default printer
    ; Errors:     1 - Gui could not be created
    ;             2 - Default printer could not be found (extended contains the _getDefaultPrinter error)
    Func _createPrinterGui($hParent = 0)
        Local $iWidth = 430, $iHeight = 430, $iBorder = 10, $iWidthRight = 100, $iListHeight = 120, $iLineHeight = 30
        Local $iWidthLeft = $iWidth-$iWidthRight-$iBorder*3
        Local $mPrinterGuiData[]
    
        ; Create Gui
        $mPrinterGuiData.hGui = GUICreate("DRUCKER ZUWEISEN", $iWidth, $iHeight, -1, -1, -1, -1, $hParent)
        If @error Then Return SetError(1, 0, -1)
        GUISetOnEvent($GUI_EVENT_CLOSE, "_closePrinterGui", $mPrinterGuiData.hGui)
        GUISetBkColor($SubBack, $mPrinterGuiData.hGui)
    
    
        ; create left column
        Local $iTop = $iBorder
    
        ; default printer
        GUICtrlCreateLabel("Standarddrucker: ", $iBorder, $iTop, $iWidth-$iBorder*2, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        $mPrinterGuiData.idDefaultPrinter = GUICtrlCreateLabel("", $iBorder, $iTop, $iWidth-$iBorder*2, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        _updateDefaultPrinter($mPrinterGuiData.idDefaultPrinter)
    
        ; installed printers
        ;$iTop += $iLineHeight
        GUICtrlCreateLabel("Installierte Drucker: ", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        Local $iRightColumnTop = $iTop
        $mPrinterGuiData.idInstalledPrinters = GUICtrlCreateList("", $iBorder, $iTop, $iWidthLeft, $iListHeight)
        GUICtrlSetOnEvent(-1, "_selPrinterLimitToOne")
        $iTop += $iListHeight+$iLineHeight
        _updateInstalledPrinters($mPrinterGuiData.idInstalledPrinters)
    
        ; connected printers
        $mPrinterGuiData.idConnectedPrinters = GUICtrlCreateList("", $iBorder, $iTop, $iWidthLeft, $iListHeight)
        GUICtrlSetOnEvent(-1, "_selPrinterLimitToOne")
        $iTop += $iListHeight
        _updateConnectedPrinters($mPrinterGuiData.idConnectedPrinters)
    
        ; network printers
        GUICtrlCreateLabel("Netzwerkdrucker einbinden: ", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += $iLineHeight
        GUICtrlSetFont(-1, 9, 900) ; bold
        $mPrinterGuiData.idNoPrintServer = GUICtrlCreateLabel("Kein Druckserver", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        GUICtrlSetFont(-1, 9, 900) ; bold
        GUICtrlSetState(-1, $GUI_HIDE)
        $mPrinterGuiData.idNetworkPrinters = GUICtrlCreateCombo("", $iBorder, $iTop, $iWidthLeft, $iLineHeight)
        $iTop += $iLineHeight
        _updateNetworkPrinters($mPrinterGuiData.idNetworkPrinters, $mPrinterGuiData.idNoPrintServer)
    
    
        ; create right column
        Local $arButtons = [["idTestprint", "Testdruck", "_doTestPrint"],["idSettings", "Einstellungen", "_openSettings"],["idPreferences", "Eigenschaften", "_openPreferences"], _
                            ["idQueue", "Warteschlange", "_openQueue"],["idPrintfolder", "Druckerordner", "_openPrintFolder"],["idDefault", "Standard", "_setDefaultPrinter"]]
        For $i = 0 To UBound($arButtons)-1 Step 1
            $mPrinterGuiData[$arButtons[$i][0]] = GUICtrlCreateButton($arButtons[$i][1], $iBorder*2+$iWidthLeft, $iRightColumnTop+$iBorder+($iLineHeight+$iBorder)*$i, $iWidthRight, $iLineHeight)
            GUICtrlSetOnEvent(-1, $arButtons[$i][2])
        Next
    
        Return $mPrinterGuiData
    EndFunc
    
    Func _selPrinterLimitToOne()
        _GUICtrlListBox_SetCurSel(@GUI_CtrlId=$mPrinter.idConnectedPrinters?$mPrinter.idInstalledPrinters:$mPrinter.idConnectedPrinters, -1)
    EndFunc
    
    Func _updatePrinters($mPrinterGuiData)
        _updateDefaultPrinter($mPrinterGuiData.idDefaultPrinter)
        _updateInstalledPrinters($mPrinterGuiData.idInstalledPrinters)
        _updateConnectedPrinters($mPrinterGuiData.idConnectedPrinters)
        _updateNetworkPrinters($mPrinterGuiData.idNetworkPrinters, $mPrinterGuiData.idNoPrintServer)
    EndFunc
    
    Func _closePrinterGui()
        GUISetState(@SW_HIDE, $mPrinter.hGui)
    EndFunc
    
    Func _networkPrinterSelection()
        Local $sPrinter = GUICtrlRead($mPrinter.idNetworkPrinters)
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /in /n  \\" & $sPrintServer &"\"& $sPrinter)
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /q /y /n \\"  & $sPrintServer &"\"& $sPrinter)
        MsgBox('262144', "Default printer", "Default printer set to: " & $sPrinter)
    EndFunc
    
    Func _doTestPrint()
        SoundPlay($sBeepFile)
        Local $sPrinter = _printExec("/k")
        If Not @error Then MsgBox('262144', "TestDruck", "Der TestDruck wurde an den Drucker """ & _getSelectedPrinter() & """ abgeschickt!" & @CRLF & "Bitte überprüfen Sie den Ausdruck.")
    EndFunc
    
    Func _openSettings()
        SoundPlay($sBeepFile)
        _printExec("/e")
    EndFunc
    
    Func _openPreferences()
        SoundPlay($sBeepFile)
        _printExec("/p")
    EndFunc
    
    Func _openQueue()
        SoundPlay($sBeepFile)
        _printExec("/o")
    EndFunc
    
    Func _openPrintFolder()
        SoundPlay($sBeepFile)
        Run("rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder")
    EndFunc
    
    Func _setDefaultPrinter()
        SoundPlay($sBeepFile)
        Local $sPrinter = '"' & GUICtrlRead($mPrinter.idInstalledPrinters) & '"'
        RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /q /y /n " & $sPrinter)
        _updateDefaultPrinter($mPrinter.idDefaultPrinter)
    EndFunc
    
    Func _printExec($sCommand)
        Local $sPrinter = _getSelectedPrinterAbs()
        If @error Then Return SetError(1, 0, -1)
        RunWait( "rundll32 printui.dll,PrintUIEntry /n " & $sPrinter & " "&$sCommand )
        If @error Then Return SetError(2, 0, -1)
        Return $sPrinter
    EndFunc
    
    ; Returns the selected printer with the absolute path including \\ and the computer name
    Func _getSelectedPrinterAbs()
        Local $sPrinter = _getSelectedPrinter()
        If @error Then Return SetError(1, 0, -1)
        If Not StringInStr($sPrinter, "\\") Then $sPrinter = '"\\' & @ComputerName & "\" & $sPrinter & '"'
        Return $sPrinter
    EndFunc
    
    Func _getSelectedPrinter()
        Local $sPrinter = GUICtrlRead($mPrinter.idInstalledPrinters)
        If $sPrinter = "" Then $sPrinter = GUICtrlRead($mPrinter.idConnectedPrinters)
        If $sPrinter = "" Then
            MsgBox(16, "Druckerauswahl", "Es wurde kein Drucker ausgewählt!")
            Return SetError(1, 0, -1)
        EndIf
        Return $sPrinter
    EndFunc
    
    Func _updateDefaultPrinter($idLabel)
        Local $sDefaultPrinter = _getDefaultPrinter()
        If @error Then Return SetError(2, @error, -1)
        GUICtrlSetData($idLabel, $sDefaultPrinter)
        Return 1
    EndFunc
    
    Func _updateInstalledPrinters($idList)
        _GUICtrlListBox_ResetContent($idList)
        Local $iCount = 1
        While True
            Local $sPrinterName = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers", $iCount)
            If @error = -1 Then ExitLoop
            $iCount+=1
            _GUICtrlListBox_AddString($idList, $sPrinterName)
        WEnd
        _GUICtrlListBox_SelectString($idList, _getDefaultPrinter())
        Return 1
    EndFunc
    
    Func _updateConnectedPrinters($idList)
        _GUICtrlListBox_ResetContent($idList)
        Local $iCount = 1
        While True
            Local $sPrinterName = RegEnumKey("HKEY_CURRENT_USER\Printers\Connections", $iCount)
            If @error = -1 Then ExitLoop
            $iCount+=1
            Local $arPrinter = StringSplit($sPrinterName, "1", 1+2)
            If UBound($arPrinter)>1 Then _GUICtrlListBox_AddString($idList, $arPrinter[3])
        WEnd
        _GUICtrlListBox_SelectString($idList, _getDefaultPrinter())
        Return 1
    EndFunc
    
    Func _updateNetworkPrinters($idCombo, $idLabel)
        _GUICtrlComboBox_ResetContent($idCombo)
        Local $arPrinters = _getNetworkPrinters()
        If Not IsArray($arPrinters) Then
            GUICtrlSetState($idCombo, $GUI_HIDE)
            GUICtrlSetState($idLabel, $GUI_SHOW)
        Else
            GUICtrlSetState($idCombo, $GUI_SHOW)
            GUICtrlSetState($idLabel, $GUI_HIDE)
            For $i=1 To UBound($arPrinters)-1 Step 1
                If $arPrinters[$i][0] <> "" Then _GUICtrlComboBox_AddString($idCombo, $arPrinters[$i][0])
            Next
        EndIf
        Return 1
    EndFunc
    
    ; Returns the name of the default printer;
    ; Errors:     1 - Registry entry could not be read
    ;             2 - Registry entry could not be parsed
    Func _getDefaultPrinter()
        Local $sDefaultPrinter = RegRead( "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\windows", "Device")
        If @error Then Return SetError(1, 0, -1)
        Local $arDefaultPrinter = StringSplit($sDefaultPrinter, ",")
        If UBound($arDefaultPrinter)>0 Then Return $arDefaultPrinter[1]
        Return SetError(2, 0, -1)
    EndFunc
    
    ; Returns a 2D array with network printers: 0 name; 1 driverName; 2 portName; 3 Shared; 4 ShareName; 5 Published; 6 Local; 7 Location; 8 DeviceID; 9 DriverName
    ; Errors:     1 - Printserver file does not exist
    ;             2 - Printer query failed
    ;            3 - No printers found
    Func _getNetworkPrinters()
        If Not FileExists("\\"&$sPrintServer&"\c$") Then Return SetError(1, 0, -1)
    
        Local $objWMIService = ObjGet("winmgmts:\\" & $sPrintServer & "\root\CIMV2")
        Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Printer')
        If Not IsObj($colItems) Then Return SetError(2, 0, -1)
        If Not $colItems.count Then Return SetError(3, 0, -1) ; No Printer found
        Local $aPrinter[$colItems.count][10], $i = 0
        For $oItem In $colItems
            $aPrinter[$i][0] = $oItem.Name
            $aPrinter[$i][1] = $oItem.DriverName
            $aPrinter[$i][2] = $oItem.PortName
            $aPrinter[$i][3] = $oItem.Shared
            $aPrinter[$i][4] = $oItem.ShareName
            $aPrinter[$i][5] = $oItem.Published
            $aPrinter[$i][6] = $oItem.Local
            $aPrinter[$i][7] = $oItem.Location
            $aPrinter[$i][8] = $oItem.DeviceID
            $aPrinter[$i][9] = $oItem.DriverName
            $i += 1
        Next
        Return $aPrinter
    EndFunc
    Alles anzeigen

    Also, fangen wir mal an:

    1. Ich würde dir empfehlen beim programmieren mehr auf sauberen Code zu achten. Bei deinem Code ist die Einrückung das reinste Chaos, Deutsche/Englische Variablen sind gemischt,... Sauberer Code ist das wichtigste um effektiv zu programmieren und Fehler schnell zu erkennen/finden.

    2. Du verwendest das ganze in einem größeren Script (vermute ich mal, weil du statt exit nen anderes Fenster einblendest, alles in einer Funktion ist,...). Dabei würde ich dir den GuiOnEventMode empfehlen. Dann bleibt das Hauptfenster responsive, auch wenn du das extra Fenster öffnest, weil du nicht die While-Schleife des zweiten Fensters hast, was verhindert, dass die Schleife des ersten Fensters abgearbeitet wird. Kann man zwar auch mit GuiGetMsg lösen, das wird dann aber komplizierter. Dabei kann ich auch gleich erwähnen, dass ich WinOnTop rausgenommen hab und dadurch ersetzt habe, dass das Printer-Fenster das Hauptfenster als Parent bekommen hat. Dadurch ist es automatisch über dem Parent-Fenster, ohne dass es global über allen Fenstern (inkl. der Drucker Einstellungsfenster,...) ist.

    3. Vermeide doppelten/mehrfach gleichen Code. DruckerFenster, DruckerEigenschaft, DruckerEinstellung und Testdruck haben quasi immer den gleichen Code, das einzige was sich ändert ist der Parameter bei dem Command der mit RunWait ausgeführt wird (/o /p /e /k). Also einfach ne Funktion schreiben, wo das übergeben wird und schon hast du den Code nur an einer Stelle.

    Ähnliches hab ich für das Füllen der Listen/Combos gemacht. Ich hab eine Update-Funktion für jedes Control erstellt, welche die Liste leert und neu befüllt. Deshalb kann ich mit einem Funktionsaufruf alles aktualisieren, wenn das Fenster erneut angezeigt wird.

    Selbiges habe ich auch für die Abfrage des ausgewählten Druckers implementiert. Und ebenso für die Adresse des Druckservers.

    4. Beim erstellen des Fensters habe ich wie immer alle Pixeleinheiten in Variablen verlagert. Dadurch kannst du die Variablen am Anfang der Funktion ändern und alle Controls passen sich automatisch an. Macht das Designen deutlich einfacher, weil nur an einer Stelle z.B. die Breite der rechten Buttons geändert werden muss und sich alle anderen Controls automatisch daran anpassen.

    5. Error Handling: Immer wenn es eine Möglichkeit gibt, dass eine Funktion schiefgehen kann sollte man Fehler hinzufügen, die man beim Aufruf der Funktion dann prüfen kann. Wenn dann später was schief geht bekommt man direkt eine Fehlermeldung mit der passenden Nummer und weiß wo das Problem ist.

    6. Ich hab die Combobox für Netzwerkdrucker ausgeblendet, wenn der Server nicht erreichbar ist und stattdessen ein Label dort angezeigt. Ist etwas übersichtlicher und man kann nicht ausversehen "Kein Printserver" als Drucker auswählen. Da kommen nen paar nette Fehlermeldungen ;)

    Ich hoffe die Tipps helfen dir weiter :)

    MfG, Kanashius.

  • Teil eines Arrays wie in Excel bearbeiten

    • Kanashius
    • 14. April 2023 um 22:29

    Um eine ListView editierbar zu machen habe ich mal eine UDF geschrieben. Du musst sie quasi nur mit dem Array befüllen und beim "speichern" (deselektieren/enter/...) den Array-Eintrag an dem Index+SubIndex verändern.

    Sollte das sein, was du willst: Listview edit subitems UDF

  • *.zip *.7z Archive durchsuchen ohne entpacken

    • Kanashius
    • 13. April 2023 um 19:43

    Keine Ahnung von AutoIt, aber in Java hab ich schon öfter mit Zip-Dateien im RAM gearbeitet, ohne die auf die Festplatte zu entpacken...

    Wenn du also nichts in AutoIt findest kannst du mich gerne anschreiben, dann bastel ich dir was, das du dann mit AutoIt startest mit den benötigten Argumenten (Dateien/Ordner/...) und dann das Ergebnis bekommst.

  • TCP - Send

    • Kanashius
    • 6. April 2023 um 14:28
    Zitat von MojoeB

    $oXML sollte doch der ganze gebaute String sein oder nicht ?
    Aber irgendwie gibt er mir diesen nicht zurück, bin nun einen Umweg gegangen, ich speichere es erst als Datei und dann lese ich die Datei nochmal aus.

    Du kannst mit $oXML.xml darauf zugreifen. (Alle verfügbaren Attribute findest du hier: https://learn.microsoft.com/en-us/previous…s763798(v=vs.85) )
    $oXML ist ein Objekt mit verschiedenen Daten (Fields/Properties) und Methoden. Es ist kein String! Deshalb kannst du z.B. mit $oXML.createElement("Ereignis") ein Element hinzufügen. Es wird eine Methode an dem Objekt aufgerufen.

    Bei deinem Beispiel würde ich persönlich eher den String mit StringFormat verwenden, statt das XML-Objekt. Es ist einfach übersichtlicher, da du nur ein kleines Template hast. Wenn du aber XML lesen/ändern willst oder das ganze noch komplizierter/verschachtelter wird würde ich das XML-Objekt nutzen. Musst du wissen, was in diesem Fall mehr Sinn macht/was du mit dem Tool noch vorhast.

    Zitat von MojoeB

    danke für deine Mühe, das muss ich mir mal genauer ansehen die Tage. mein Problem dabei ist das ich StringFormat noch nicht wirklich verstanden habe.

    Bei StringFormat übergibst du einen String (hier das XML). In dem String schreibst du z.B. %s, %u,... (Schau in der Hilfe, was es noch alles gibt). Das sind Platzhalter für Daten, die später mit StringFormat eingefügt werden.

    %s steht dabei für einen String, %u für eine positive, ganze Zahl. Und die werden nacheinander mit den Parametern von StringFormat ersetzt. Das erste %_ mit dem ersten Parameter von StringFormat, usw.

    Statt z.B. also $sText = "Ich bin die " & $sType & " Zahl: " & $iZahl kann man schreiben: $sText = StringFormat("Ich bin die %s Zahl: %u", $sType, $iZahl) Dabei kann man bei Dezimal Zahlen auch angeben, wie viele Nachkommastellen angezeigt werden sollen,... Und in diesem Fall macht es das ganze übersichtlicher, weil du den String nur einmal speichern musst und ihn immer wieder mit anderen Variablen füllen kannst, ohne dass jedesmal die ganze Zuweisung mit dem ganzen Text dort stehen muss.

    AutoIt
    ; statt
    $iZahl = 5
    $sType = "positive"
    $sText = "Ich bin die " & $sType & " Zahl: " & $iZahl ; Text wird 2x definiert => muss hier und weiter unten geändert werden
    
    $iZahl = -5
    $sType = "negative"
    $sText = "Ich bin die " & $sType & " Zahl: " & $iZahl ; Text wird 2x definiert => muss hier und weiter oben geändert werden
    
    
    ; hast du also
    $sTemplateNumber = "Ich bin die %s Zahl: %u" ; wird hier nur einmal definiert, und wenn du was ändern musst, musst du es nur einmal hier ändern und es passt überall
    $iZahl = 5
    $sType = "positive"
    $sText = StringFormat($sTemplateNumber, $sType, $iZahl)
    
    $iZahl = -5
    $sType = "negative"
    $sText = StringFormat($sTemplateNumber, $sType, $iZahl)
    Alles anzeigen

    Auf diese Weise sind Änderungen/Fehler leichter zu beheben, gerade wenn es öfter verwendet wird als hier im Beispiel und es spart Code-Zeilen (=>übersichtlicher), wenn du so wie bei dir mehrere Zeilen an Text hast, die recht lang werden.

  • TCP - Send

    • Kanashius
    • 4. April 2023 um 21:11

    Hi, freut mich, dass du den Fehler gefunden hast.

    Ich hätte sonst noch den Vorschlag gehabt, den XML-Teil als Template zu haben. Ist etwas lesbarer und solange die Menge überschaubar ist ggf. auch sinnvoll.

    Ich hab dabei das ganze Script etwas umgebaut um zu zeigen, wie ich das umgesetzt hätte. Ist meiner Meinung nach etwas übersichtlicher, vereinfacht die Fehlersuche und ist generell mehr auf Wiederverwendbarkeit ausgelegt.

    AutoIt
    Global $sMainTemplate = '<?xml VERSION="1.0" ENCODING="UTF-8"?>'&@CRLF& _
                            '<LISA>'&@CRLF& _
                            '    <VERSION>%s</VERSION>'&@CRLF& _ ; Version
                            '    <MEDIUM>%u</MEDIUM>'&@CRLF& _ ; Medium
                            '    <KANAL>%u</KANAL>'&@CRLF& _ ; Kanal
                            '    <SENDER>%s</SENDER>'&@CRLF& _ ; IP sender
                            '    <ENTSTEHUNG>%sUHR</ENTSTEHUNG>'&@CRLF& _ ; date time 'dd.mm.yyyy hh:mm:ss'
                            '%s'& _ ; Template VERBINDUNGSMELDUNG *times
                            '</LISA>'
    Global $sSubTemplate =    '    <VERBINDUNGSMELDUNG>'&@CRLF& _
                            '        <IDENTNUMMER>%s</IDENTNUMMER>'&@CRLF& _ ; Ident number
                            '        <EREIGNIS>%s</EREIGNIS>'&@CRLF& _ ; message
                            '    </VERBINDUNGSMELDUNG>'&@CRLF
    
    Global $bDebug = True
    
    
    Global $mConn = _connect("127.0.0.1", 1337, "1111")
    If @error Then
        _showError("Error connecting to the Server", @error, @extended, $mConn)
        Exit
    EndIf
    
    _send($mConn, "SOMETHING")
    If @error Then _showError("Error sending to the Server: 1", @error, @extended)
    
    Local $arMultiple = ["SOME", "MORE"]
    _send($mConn, $arMultiple)
    If @error Then _showError("Error sending to the Server: 2", @error, @extended)
    
    _disconnect($mConn)
    If @error Then _showError("Error disconnecting from the Server", @error, @extended)
    
    
    
    Func _connect($sServerIP, $iPort, $sID)
        TCPStartup()
        Local $mConn[]
        $mConn.id = $sID
        $mConn.socket = TCPConnect($sServerIP, $iPort)
        If @error Then Return SetError(1, @error, -1)
        Local $arMsg = ["CONNECT", "ROUTINE"]
        _send($mConn, $arMsg)
        If @error Then Return SetError(2, @error, -1)
        Return $mConn
    EndFunc
    
    Func _send(ByRef $mConn, $connMsg)
        Local $sSubMsg = ""
        If IsString($connMsg) Then
            $sSubMsg = StringFormat($sSubTemplate, $mConn.id, $connMsg)
        ElseIf IsArray($connMsg) Then
            For $i=0 To UBound($connMsg)-1 Step 1
                $sSubMsg &= StringFormat($sSubTemplate, $mConn.id, $connMsg[$i])
            Next
        Else
            Return SetError(1, 0, -1)
        EndIf
        Local $sMsg = StringFormat($sMainTemplate, 5.8, 12, 610, @IPAddress1, @MDAY&"."&@MON&"."&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC, $sSubMsg)
        TCPSend($mConn.socket, $sMsg)
        If @error Then Return SetError(2, @error, -1)
        If $bDebug Then ConsoleWrite($sMsg&@CRLF)
        Return 1
    EndFunc
    
    Func _disconnect(ByRef $mConn)
        _send($mConn, "DISCONNECT")
        If @error Then Return SetError(1, @error, -1)
        TCPCloseSocket($mConn.socket)
        If @error Then Return SetError(2, @error, -1)
        TCPShutdown()
        If @error Then Return SetError(3, @error, -1)
    EndFunc
    
    Func _showError($sMsg, $iError, $sExtended, $sReturn = Default)
        MsgBox(16, "Error", $sMsg&@crlf&"Details: "&$iError&":"&$sExtended)
        If $bDebug Then ConsoleWrite($sMsg&@crlf&"Details: "&$iError&":"&$sExtended&" Return: "&@crlf&$sReturn&@crlf)
    EndFunc
    Alles anzeigen

    Dazu hab ich mir zum testen auch einen Server geschrieben. Der könnte für dich auch hilfreich sein um solche Fehler zu finden, wie den von dir genannten:

    AutoIt
    TCPStartup()
    $iMainSocket = TCPListen("127.0.0.1", 1337)
    While True
        Local $iSocket = -1
        ConsoleWrite("LISTEN FOR CLIENT"&@CRLF)
        While True
            $iSocket = TCPAccept($iMainSocket)
            If $iSocket<>-1 Then ExitLoop
        WEnd
        ConsoleWrite("CLIENT CONNECTED"&@CRLF)
        While True
            $sMsg = TCPRecv($iSocket, 8000)
            If @error Or @extended = 1 Or BinaryLen($sMsg) = 0 Then
                TCPCloseSocket($iSocket)
                ExitLoop
            EndIf
            If $sMsg<>"" Then
                ConsoleWrite("RECEIVED: "&@CRLF&$sMsg&@CRLF)
            EndIf
        WEnd
        ConsoleWrite("CLIENT DISCONNECTED"&@CRLF)
    WEnd
    Alles anzeigen

    MfG, Kanashius :)

  • Auto markieren / excel starter

    • Kanashius
    • 1. März 2023 um 15:49

    Da du dir ein Google-Sheet selbst exportierst würde ich einwerfen:

    1. Exportier es als .csv (File->Download->Comma seperated values)

    2. .csv Datei einlesen (FileRead) und mit Text-Verarbeitung (RegExp) auslesen

    3. Gui erstellen mit einem Suchfeld für die IMEI und einer anzeige für das Suchergebnis (Es gab auch vor kurzem einen Thread zum einlesen mit Scannern: RE: Barcode in Variable scannen ohne den Inhalt irgendwo anzuzeigen)

    4. Mit dem Scanner einscannen und Ergebnis direkt in der GUI anzeigen

    Das spart Excel komplett aus => einfacher und weniger Fehleranfällig und du brauchst die Lizenz nicht.

    Wenn du dann troztdem die Liste selbst anschauen willst, kannst du sie immernoch mit Excel öffnen (Excel unterstützt .csv).

    Ich würde Abhängigkeiten (wie hier Excel) immer vermeiden.

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™