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. BugFix

Beiträge von BugFix

  • PDF Drucken

    • BugFix
    • 17. Oktober 2022 um 09:15

    Nun möchte ich auch mal noch meinen Senf dazu geben. ^^

    Für beide Varianten (Acrobat od. portabler Reader) kann es nachvollziehbare Gründe geben, die auch von meinen Vorpostern ausreichend aufgezählt wurden. Ich persönlich bin ein absoluter Gegner des Acrobat Reader (wohlgemerkt: des Readers). Im Laufe der Jahre wurde ein schlanker (schnell startender) Reader durch Hinzufügen sinnfreier Komponenten zu einem Monstrum aufgeblasen. Ich weiß nicht, wie platzhungrig das Teil im Moment ist, als ich vor Jahren das letzte mal so ein Teil auf dem Rechner hatte, waren es rund 200 MB! - für einen READER!!! Und Ladezeiten, als wollte man ein 2-Std. Video preloaden. :Face:

    Deshalb ist erste Amtshandlung bei neuen PC: Falls installiert - Deinstallation des Acrobat-Readers bzw. Entfernen seines Installationslinks.

    Ich selbst nutze den XChange PDF-Viewer, mit 16 MB für diesen Zweck völlig ausreichend.

    Ich bin durchaus bereit, für funktionale Software Geld auszugeben. So kaufe ich grundsätzlich Apps für mein Smartphone, wenn diese nach einer mehrmonatigen Testphase für mich zufriedenstellend laufen. Nur aus Enthusiasmus heraus wird auf Dauer ein Produkt nur schwer zu pflegen sein. Deshalb unterstütze ich dann gern.

    Zum Thema "Gute Sitten / Umgangston":

    Peter S. Taler, ich kann durchaus verstehen, dass du nach dem Post von Andy etwas angefasst warst. Ich hatte nach dem Lesen deines ersten Posts schon den Gedanken "Das triggert den Andy". Denn in dem Punkt seid ihr euch gar nicht so unähnlich - und ich ticke auch so 8o. Meinungen sind absolut und müssen erst mal kräftig postuliert werden. Am Besten mit einem Schuss Provokation versehen. Aber glaub mir, wenn dir Andy im Biergarten gegenüber säße, würde er sagen: "Das ging nicht gegen dich als Person, aber ich schieße mit breitem Streufeuer und du standest nun mal gerade im Weg."

    Wir hatten im Laufe der Jahre erst ganz wenige Fälle, in denen wir gezielt rau gegen einzelne User vorgingen. Da war ich dann auch mit im Boot und das hatte entsprechende Gründe. Ansonsten kommen wir hier recht gut miteinander aus.

    Vielleicht hilft dir die Vorstellung, Andy könnte Mr. Waldorf aus der Muppet Show sein (Mr. Statler beanspruche ich für mich, denn ich habe einen Bart - bei Andy weiß ich es nicht :P ). Was ich irgendwie auch passend finde: Nach eigener Aussage heißen die beiden letzten Bücher, die die zwei Zyniker gelesen haben "Die Kunst des Beleidigens" und "Wie man die Kunst beleidigt". :rofl:

    In diesem Sinne: Ein virtuelles Prost und eine schöne Woche.

  • To Wert einer For-Schleife bearbeiten

    • BugFix
    • 10. Oktober 2022 um 16:23
    Zitat von Musashi

    Du könntest auch deine For..Next Schleife beibehalten, dann musst Du nur, wie Micha_he bereits schrieb, mit dem letzten Element beginnen.

    Code
    #include <Array.au3>
    Local $aArray[16] = [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1]
    For $i = Ubound($aArray) - 1 To 0 Step -1
        If $aArray[$i] = 1 Then _ArrayDelete($aArray, $i)
    Next
    _ArrayDisplay($aArray)

    Jein.

    Wenn du _ArrayDelete verwendest, wird jedes mal ein ReDim ausgeführt, sollte man tunlichst vermeiden.

  • Background Bild und GUI Elemente

    • BugFix
    • 10. Oktober 2022 um 10:04

    Noch zum Punkt Aktualisierungsintervall:

    100 ms ist der letzte Wert, bei dem noch ohne Flackern aktualisiert werden kann. Aber trotzdem ist das wenig sinnvoll. Du musst ja noch die Zeit hinzurechnen um den Wert wahrnehmen zu können. Wenn Du sehr gut drauf ist, passiert das in weiteren 100 ms, d.h. wirklich lesbar ist die Anzeige erst bei einer Aktualisierung alle 200 ms.

    Kannst du in diesem Bsp. mal selbst probieren, ob du bei 100 ms wirklich jeden neuen Wert erfassen kannst. 8o

    AutoIt
    #include <GUIConstantsEx.au3>
    
    GUICreate('Test Label-Update')
    Global $aLabel[6], $aRadio[6]
    $aRadio[4] = GUICtrlCreateRadio(' ', 5, 7, 10, 15)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlCreateLabel('Update: 1 s (1 Hz)', 20, 10, 150)
    $aLabel[4] = GUICtrlCreateLabel('', 160, 10, 120, 17)
    $aRadio[3] = GUICtrlCreateRadio(' ', 5, 37, 10, 15)
    GUICtrlCreateLabel('Update: 0,5 s (2 Hz)', 20, 40, 150)
    $aLabel[3] = GUICtrlCreateLabel('', 160, 40, 120, 17)
    $aRadio[2] = GUICtrlCreateRadio(' ', 5, 67, 10, 15)
    GUICtrlCreateLabel('Update: 0,2 s (5 Hz)', 20, 70, 150)
    $aLabel[2] = GUICtrlCreateLabel('', 160, 70, 120, 17)
    $aRadio[1] = GUICtrlCreateRadio(' ', 5, 97, 10, 15)
    GUICtrlCreateLabel('Update: 0,1 s (10 Hz)', 20, 100, 150)
    $aLabel[1] = GUICtrlCreateLabel('', 160, 100, 120, 17)
    $aRadio[5] = GUICtrlCreateRadio(' ', 5, 127, 10, 15)
    GUICtrlCreateLabel('Update: 0,08 s (12,5 Hz)', 20, 130, 150)
    $aLabel[5] = GUICtrlCreateLabel('', 160, 130, 120, 17)
    $aRadio[0] = GUICtrlCreateRadio(' ', 5, 157, 10, 15)
    GUICtrlCreateLabel('Update: 0,05 s (20 Hz)', 20, 160, 150)
    $aLabel[0] = GUICtrlCreateLabel('', 160, 160, 120, 17)
    
    AdlibRegister(_Intervall005, 50)
    AdlibRegister(_Intervall008, 80)
    
    GUISetState()
    Do
    Until GUIGetMsg() = -3
    
    Func _Intervall005()
        Local Static $aSum[][] = [[0,1],[0,2],[0,4],[0,10],[0,20]]
        For $i = 0 To UBound($aSum) -1
            $aSum[$i][0] += 1
            If $aSum[$i][0] = $aSum[$i][1] Then
                $aSum[$i][0] = 0
                If BitAND(GUICtrlRead($aRadio[$i]), $GUI_CHECKED) Then _
                    GUICtrlSetData($aLabel[$i], StringFormat('%02d:%02d:%02d,%03d', @HOUR, @MIN, @SEC, @MSEC))
            EndIf
        Next
    EndFunc
    
    Func _Intervall008()
        If Not BitAND(GUICtrlRead($aRadio[5]), $GUI_CHECKED) Then Return
        GUICtrlSetData($aLabel[5], StringFormat('%02d:%02d:%02d,%03d', @HOUR, @MIN, @SEC, @MSEC))
    EndFunc
    Alles anzeigen

    Für Anzeigen von Statusmeldungen, die sich an Schwellwerten orientieren in der Art: "OK", "Geht Noch", "Gefahr", ist m.M.n. die Hintergrundfärbung der Label in Grün/Gelb/Rot viel intuitiver als ein Zahlenwert.

  • Overheadarmes/Codearmes Keyboard capturing

    • BugFix
    • 6. Oktober 2022 um 19:24
    Zitat von Oscar

    Bei der Window-Prozedur muss man doch nur zur bisherigen Prozedur springen, dann ist auch eine Verkettung möglich.

    Klar, so geht's ja. ^^

    Sollte man dann aber auch immer auf dem Schirm haben, dass das der Weg ist.

  • Overheadarmes/Codearmes Keyboard capturing

    • BugFix
    • 6. Oktober 2022 um 18:08

    Es gibt ein Problem:

    Es eignet sich für eine vernünftige Performance eigentlich nur ein Hook (bzw. 2: Key- und WM). Was zum Problem führt, dass der User später keinen eigenen (gleichartigen) Hook in seinem Code einbauen kann, da dieser in der UDF bereits registriert ist. Vielleicht ist es schonmal jemandem gelungen, das in einen anderen Prozess oder Thread auszulagern und ggf. über IPC zu kommunizieren.

    Die Auswertung von Shift, Capslock, etc. ist auf den ersten Blick etwas schwierig, bis man es dann mal gemacht hat. Ich hatte mal eine derartige Auswertesoftware geschrieben zum Aufspüren von Benutzerfehlern an neuer Software. Wobei hier die erfassten Zeichen parallel in der Statusleiste angezeigt wurden, damit die Kontrolle nicht "heimlich" lief.

    Wenn ich am WE wieder daheim bin, kann ich das gern mal vorsuchen.

    Was du noch vergessen hast an Eigenschaften:

    Bewegen des Cursor im Ctrl mit

    - Pfeil li/re/auf/ab

    - Home/End

    - Kombinationen mit Shift/Ctrl und daraus resultierende Textmarkierung

    Diese Eigenschaften waren mein allererstes Programm - geschrieben in Turbopascal zur Ausführung in der Konsole (Nachbildung des Userinput von dbase) ;)

  • Zeitrechner

    • BugFix
    • 3. Oktober 2022 um 18:36
    Zitat von Chris_pac

    Ist es eigentlich möglich, mehrere Variablen in eine Variable zu packen

    Ja, dazu gibt es den Variablentyp Array.

  • Helligkeit von Farben schrittweise oder mit Fixwert ändern: _GetColorWithBrightness

    • BugFix
    • 30. September 2022 um 12:13

    Mit der Funktion _GetColorWithBrightness erhaltet ihr zu einer RGB-Farbe den um n-Helligkeitschritte (+/-) oder auf eine fixe Helligkeit geänderten Farbwert.

    Bei den reinen Farben (R, G, B) sind recht große Schritte erforderlich (ca. 10), bei Mischfarben reichen meist Schrittweiten von 2-3. Könnt ihr im Bsp.-Skript testen.

    AutoIt: ColorBrightness.au3
     ;-- TIME_STAMP   2022-09-30 12:10:37
    
    _TestBrightness(0xF5F5DC, 2)
    _TestBrightness(0x0000FF, 10)
    _TestBrightness(0xE9967A, 4)
    
    
    
    Func _TestBrightness($_RGB, $_step)
        Local $hGui = GUICreate('Test Brightness', 400, 200)
        Local $RGB2 = $_RGB, $aL1[6], $aL2[6], $y
        GUICtrlCreateLabel('AUFHELLEN', 10, 10)
        GUICtrlCreateLabel('ABDUNKELN', 200, 10)
        For $i = 0 To UBound($aL1) -1
            $y = 30 + $i*21
            $aL1[$i] = GUICtrlCreateLabel('', 10, $y, 180, 20)
            $aL2[$i] = GUICtrlCreateLabel('', 200, $y, 180, 20)
        Next
        GUICtrlSetBkColor($aL1[0], $_RGB)
        GUICtrlSetBkColor($aL2[0], $RGB2)
        For $i = 1 To UBound($aL1) -1
            $_RGB = _GetColorWithBrightness($_RGB, $_step)
            GUICtrlSetBkColor($aL1[$i], $_RGB)
            $RGB2 = _GetColorWithBrightness($RGB2, (-1)*$_step)
            GUICtrlSetBkColor($aL2[$i], $RGB2)
        Next
    
        GUISetState()
        Do
        Until GUIGetMsg() = -3
        GUIDelete($hGui)
    EndFunc
    
    
    ; #FUNCTION# =======================================================================================
    ; Name ..........: _GetColorWithBrightness
    ; Description ...: Gibt zu einer Farbe die auf einen Helligkeitswert geänderte Farbe zurück
    ; Parameter(s)...: $_RGB
    ; ....[optional].: $_iStep        Zur Änderung der Helligkeit um einzelne Schritte (+/-), (Default: 0)
    ; ...............:                Nur wirksam, wenn "$_iBrightness=Null".
    ; ....[optional].: $_iBrightness  Zur Änderung der Helligkeit auf einen fixen Wert (Default: Null)
    ; Return values .: Success        Der neue Farbwert
    ; ...............: Failure        Der Farbwert, wie übergeben ($_iStep/$_iBrightness nicht angegeben)
    ; Author ........: BugFix
    ; ==================================================================================================
    Func _GetColorWithBrightness($_RGB, $_iStep=0, $_iBrightness=Null)
        Local $R = BitAND(BitShift($_RGB, 16), 0xFF)
        Local $G = BitAND(BitShift($_RGB, 8), 0xFF)
        Local $B = BitAND($_RGB, 0xFF)
        Local $R1 = $R, $G1 = $G, $B1 = $B
        Local $Brightness = Int(Sqrt($R^2*0.299 + $G^2*0.587 + $B^2*0.114))
        If $_iBrightness = Null Then ; Schrittweite wird verwendet
            $_iBrightness = $Brightness + ($_iStep)
        EndIf
        $_iBrightness = $_iBrightness < 0 ? 0 : ($_iBrightness > 255 ? 255 : $_iBrightness)
        If $_iBrightness > $Brightness Then
            While $Brightness < $_iBrightness
                $R1 = $R1 +1 > 255 ? 255 : $R1 +1
                $G1 = $G1 +1 > 255 ? 255 : $G1 +1
                $B1 = $B1 +1 > 255 ? 255 : $B1 +1
                $Brightness = Int(Sqrt($R1^2*0.299 + $G1^2*0.587 + $B1^2*0.114))
            WEnd
        ElseIf $_iBrightness < $Brightness Then
            While $Brightness > $_iBrightness
                $R1 = $R1 -1 < 0 ? 0 : $R1 -1
                $G1 = $G1 -1 < 0 ? 0 : $G1 -1
                $B1 = $B1 -1 < 0 ? 0 : $B1 -1
                $Brightness = Int(Sqrt($R1^2*0.299 + $G1^2*0.587 + $B1^2*0.114))
            WEnd
        EndIf
        Return '0x' & Hex($R1,2) & Hex($G1,2) & Hex($B1,2)
    EndFunc
    Alles anzeigen

    bright1.PNG  bright2.PNG

    bright3.PNG

    Dateien

    ColorBrightness.au3 2,98 kB – 267 Downloads
  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 28. September 2022 um 18:26

    ListCtrl mit AlternateColors

    Nim
    import wNim/[wApp, wWindow, wFrame, wPanel, wListCtrl]
    import winim/[inc\commctrl]
    
    
    # ------------------------------------------------------------------------------
    type 
      ListHead = tuple[text: string, format: int, width: int]
      ListText = seq[string]
    proc setListColumns(list: wListCtrl, head: openArray[ListHead]) =
      for i in 0..<head.len:
        list.appendColumn(text=head[i][0], width=head[i][2])
        list.setColumnFormat(i, head[i][1])
    proc setListText(list: wListCtrl, stuff: openArray[ListText]) =
      var item: int
      for i in 0..<stuff.len:
        item = list.appendItem(stuff[i][0])   
        for j in 1..<stuff[i].len:            
          list.setItem(item, j, stuff[i][j])  
    # ------------------------------------------------------------------------------
    
    
    let 
      app = App()
      frame = Frame(title="Test Alternate Color",size=(500,250))
      panel = frame.Panel()
      lc1 = panel.ListCtrl(style=wLcReport or wBorderDouble or wLcSingleSel or wLcNoSortHeader)
      lc2 = panel.ListCtrl(style=wLcReport or wBorderDouble or wLcSingleSel or wLcNoSortHeader)
    
    
    lc1.setExtendedStyle(LVS_EX_GRIDLINES)
    lc1.setListColumns([
         ("Column 1",wListFormatLeft,110),
         ("Column 2",wListFormatLeft,110)])
    lc1.setListText([@["1111","2222"], @["3333","4444"], @["5555","6666"]])
    
    lc2.setExtendedStyle(LVS_EX_GRIDLINES)
    lc2.setListColumns([
         ("Column 1",wListFormatLeft,110),
         ("Column 2",wListFormatLeft,110)])
    lc2.setListText([@["7777","8888"], @["9999","0000"], @["1122","3344"]])
    
    
    # Listview 1: even / odd color setzen (ARGB konvertieren zu wColor)
    lc1.setBackgroundColor(0x00B0E0E6.wColor)
    lc1.setAlternateRowColor(wLightBlue)
    
    
    # Listview 2: even color setzen, odd color berechnet
    lc2.setBackgroundColor(0x00B0E0E6.wColor)
    lc2.enableAlternateRowColors()
    
    
    proc layout() =
      panel.autolayout """
      |-[lc1(==lc2)]-[lc2]-|
      V:|-[lc1]-|
      V:|-[lc2]-|
      """
    
    
    frame.wIdExit do ():
      frame.delete()
    
    
    layout()
    frame.center()
    frame.show()
    app.mainLoop()
    Alles anzeigen

    alternateColor.PNG

  • Listview - AlternateColors Calculated

    • BugFix
    • 28. September 2022 um 13:46

    Um im Listview die Zeilen abwechselnd zu färben werden mit GuiCtrlSetBkColor($Listview, COLOR_ODD) die Farbe für die ungeraden Zeilen bestimmt und das Setzen des Flag GUICtrlSetBkColor($Listview, $GUI_BKCOLOR_LV_ALTERNATE) ermöglicht dann bei der Erstellung der ListviewItem mit GuiCtrlSetBkColor($Listview, COLOR_EVEN) die Färbung der geraden Zeilen zu definieren.

    Optisch gefällt mir an der Variante nicht, dass der gesamte Listviewhintergrund (auch ohne Dateninhalt) eingefärbt wird.

    Zum anderen wäre es doch praktisch, die alternative Farbe automatisch zu bestimmen, wenn man keinen speziellen Wunsch hat. (Diese Möglichkeit habe ich in Nim entdeckt)

    Ich habe das noch kombiniert mit der Berechnung der Farbe für den Text (Farbe für hellen oder dunklen Hintergrund), damit ein ausreichender Kontrast zum Lesen vorhanden ist. Gefärbt werden nun ausschließlich die mit Daten befüllten Item.

    Vielleicht könnt ihr es brauchen.

    EDIT: Da war noch ein Fehler drin. Durch die Berechnung entstanden Floatzahlen, die durch die Funktion Hex nicht verarbeitet werden können.

    Zusätzlich wird jetzt ohne Angabe von Farben weiß/grau verwendet.

    AutoIt: AlternatColorsLV_examples.au3
    ;-- TIME_STAMP   2022-09-29 16:01:46
    
    #include <GUIConstantsEx.au3>
    
    _AlternateColors_ByFlag()
    
    _AlternateColors_EvenByUser()
    
    _AlternateColors_EvenCalculated(0xEFE4B0)
    _AlternateColors_EvenCalculated(0xFFD700)
    _AlternateColors_EvenCalculated(0xDC143C)
    _AlternateColors_EvenCalculated(0x00FF00)
    _AlternateColors_EvenCalculated(0xA0A0A0)
    _AlternateColors_EvenCalculated() ; ohne Angabe: weiß / grau
    
    Func _AlternateColors_ByFlag()
        Local $hGui = GUICreate('AlternateColors by Flag')
        Local $LV = GUICtrlCreateListView("Col 1|Col 2", 15, 15, 300, 250)
        GUICtrlSetBkColor(-1, 0xEFE4B0) ; Color odd row
        GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
    
        For $i = 1 To 30
            GUICtrlCreateListViewItem(Random(10000, 1000000, 1) & '|' & Random(10000, 1000000, 1), $LV)
            GUICtrlSetBkColor(-1, 0xC8BFE7) ; Color even row
        Next
    
        GUISetState()
    
        Do
        Until GUIGetMsg() = -3
        GUIDelete($hGui)
    EndFunc
    
    
    Func _AlternateColors_EvenByUser()
        Local $hGui = GUICreate('AlternateColors by User')
        Local $LV = GUICtrlCreateListView("Col 1|Col 2", 15, 15, 300, 250)
    
        For $i = 1 To 30
            GUICtrlCreateListViewItem(Random(10000, 1000000, 1) & '|' & Random(10000, 1000000, 1), $LV)
            _LV_SetAlternateBkColor($i-1, 0xC8BFE7, 0xEFE4B0) ; color even, color odd - by user
        Next
    
        GUISetState()
    
        Do
        Until GUIGetMsg() = -3
        GUIDelete($hGui)
    EndFunc
    
    
    Func _AlternateColors_EvenCalculated($_colorOdd=-1)
        Local $hGui = GUICreate('AlternateColors Calculated')
        Local $LV = GUICtrlCreateListView("Col 1|Col 2", 15, 15, 300, 250)
    
        For $i = 1 To 30
            GUICtrlCreateListViewItem(Random(10000, 1000000, 1) & '|' & Random(10000, 1000000, 1), $LV)
            _LV_SetAlternateBkColor($i-1, $_colorOdd) ; color odd, color even - calculated
        Next
    
        GUISetState()
    
        Do
        Until GUIGetMsg() = -3
        GUIDelete($hGui)
    EndFunc
    
    
    
    Func _LV_SetAlternateBkColor($_Index, $_RGBodd=-1, $_RGBeven=-1, $_ColOnDark=-1, $_ColOnBright=-1)
        $_RGBodd = $_RGBodd = -1 ? 0xFFFFFF : $_RGBodd
        $_ColOnDark = $_ColOnDark = -1 ? 0xFAFAFA : $_ColOnDark
        $_ColOnBright = $_ColOnBright = -1 ? 0x000088 : $_ColOnBright
        Local $R, $G, $B
        If Mod($_Index, 2) <> 0 Then
            GUICtrlSetBkColor(-1, $_RGBodd)
        Else
            If $_RGBeven = -1 Then
                $R = Int(0.8*BitAND(BitShift($_RGBodd, 16), 0xFF))
                $G = Int(0.8*BitAND(BitShift($_RGBodd, 8), 0xFF))
                $B = Int(0.8*BitAND($_RGBodd, 0xFF))
                $_RGBeven = '0x' & Hex($R, 2) & Hex($G, 2) & Hex($B, 2)
            EndIf
            GUICtrlSetBkColor(-1, $_RGBeven)
        EndIf
        GUICtrlSetColor(-1, _RGB_GetContrast((Mod($_Index, 2) <> 0 ? $_RGBodd : $_RGBeven), $_ColOnDark, $_ColOnBright))
    EndFunc
    
    
    Func _RGB_GetContrast($_RGB, $_ColOnDark=0xFAFAFA, $_colOnBright=0x000088)
        ; get brightness
        Local $R = BitAND(BitShift($_RGB, 16), 0xFF)
        Local $G = BitAND(BitShift($_RGB, 8), 0xFF)
        Local $B = BitAND($_RGB, 0xFF)
        Local $Brightness = Sqrt($R^2*0.299 + $G^2*0.587 + $B^2*0.114)
    
        If $Brightness < 140 Then  ; dark
            Return $_ColOnDark     ; contrast text color if background is dark
        Else
            Return $_colOnBright   ; contrast text color if background is bright
        EndIf
    EndFunc
    Alles anzeigen

    Standard:

    [_LV_SetAlternateBkColor] User setzt Farbe für odd und even:

    [_LV_SetAlternateBkColor] User setzt nur Farbe für odd:

         

    Dateien

    AlternatColorsLV_examples.au3 3,25 kB – 234 Downloads
  • wNim - setFocus

    • BugFix
    • 28. September 2022 um 09:46
    Zitat von Bitnugger

    Da finde ich jede Menge...

    :rofl: Klassischer Fall von Eigentor.

    Mir war zwar klar, dass die Ctrl als Fenster behandelt werden - nach der setFocus Prozedur hatte ich aber in den Ctrl-Dokus gesucht. Es gibt ja aber das übergeordnete wWindow, dem die Ctrl angehören. Und somit sind die dort dokumentierten Prozeduren auch für die Ctrl gültig.

  • Automatisierung eines Impressum-Grabbers

    • BugFix
    • 26. September 2022 um 20:38
    Zitat von water

    Kannst Du bitte kurz beschreiben, wofür Du einen Impressumgrabber brauchst

    Hab ich mich auch schon gefragt.

    Ich befürchte um Firmen mit ungewollter Werbung zuzuschei... Im Gegensatz zu Privatpersonen können sich Firmen leider nicht dagegen wehren. (Außer DNS-Attacke als Antwort :rofl:)

  • wNim - setFocus

    • BugFix
    • 23. September 2022 um 20:22
    Zitat von Bitnugger

    allerdings meckert VSCodium:


    "message": 'setFocus' is declared but not used [XDeclaredButNotUsed]

    Das hat mich auch gewundert.

    Ich will grundsätzlich nichts ausschließen und halte es deshalb für möglich, dass diese proceure in den Tiefen der Includes doch schon existiert (aber dokumentiert habe ich es nicht gefunden). Somit wäre sie doppelt - und deshalb "nicht genutzt" ?

  • wNim - setFocus

    • BugFix
    • 22. September 2022 um 19:14

    Die Funktion hatte ich schmerzlich vermisst. Deshalb habe ich sie mir erstellt.

    Ich war auf Irrwegen :D - s. Post #5

    Um Zugriff auf die fenstertypischen Prozeduren zu bekommen muss nur wWindow importiert werden:

    Nim
    import wNim/[wWindow]
    Nim
    # compile: nim c --app:gui testfocus.nim
    
    
    include winim/[inc\winuser]
    import wNim/[wApp, wFrame, wPanel, wListBox, wTextCtrl]
    
    
    # sets the focus to passed handle
    # required: include winim/[inc\winuser]
    proc setFocus(hwnd: HWND): WINBOOL {.discardable, stdcall, dynlib: "user32", importc: "SetFocus".}
    
    
    let 
      app = App()
      frame = Frame(title="Test Focus",size=(400,250))
      panel = frame.Panel()
      lb = panel.ListBox(style=wLbNeededScroll or wLbNoSel)
      tc = panel.TextCtrl(style=wBorderSunken)
    
    
    for e in @["Eintrag A","Eintrag B","Eintrag C","Eintrag D"]:
      lb.append(e)
    
    
    # Fokus liegt jetzt auf: lb
    # setzen auf: tc
    tc.setFocus()
    
    
    proc layout() =
      panel.layout:
        lb:
          left = 10
          top = 30
          width = 120
          height = 100
        tc:
          left = 20
          top = lb.bottom + 20
          width = 80
          height = 20
    
    
    frame.wIdExit do ():
      frame.delete()
    
    
    layout()
    frame.center()
    frame.show()
    app.mainLoop()
    Alles anzeigen
  • [gelöst] Nested JSON to Object

    • BugFix
    • 21. September 2022 um 14:21

    GELÖST

    So, bin nun auf kleinem Umweg zum Ziel (Objekt) gelangt. Wobei ich hier nur die Fehlerinfos in das Objekt lade, die anderen Nodes sind ja direkt abfragbar.

    Nim
    import json
    
    
    type
      oErrCode = object
        code: string 
        device: seq[JsonNode]
        name: string
        description: string
        reason: seq[JsonNode]
        disposal: seq[JsonNode]
        remark: string
    
    
    let str_json =
      """
      {
        "title": "Test",
        "author": "BugFix",
        "articles": [
          {"number": "a123", "storage_location": "D-75"},
          {"number": "b456", "storage_location": "C-145"},
          {"number": "c789", "storage_location": "H-63"}
        ],
        "error_list": [
          {
            "code": "101",
            "device": ["dev A","dev B","dev C"],
            "name": "SensorErrBla",
            "description": "Sensorfehler",
            "reason": ["Mainboard defekt"],
            "disposal": ["Mainboard ersetzen"],
            "remark": ""
          },
          {
            "code": "101",
            "device": ["dev D","dev E","dev F"],
            "name": "SensorErrBlub",
            "description": "Sensorfehler",
            "reason": ["Mainboard defekt"],
            "disposal": ["Mainboard ersetzen"],
            "remark": ""
          },
          {
            "code": "102",
            "device": ["dev A","dev B","dev C"],
            "name": "BatteryErrBla",
            "description": "Akkufehler",
            "reason": ["Akku defekt","Controllerboard defekt"],
            "disposal": ["Akku erstzen","Controllerboard ersetzen"],
            "remark": ""
          },
          {
            "code": "102",
            "device": ["dev D","dev E","dev F"],
            "name": "BatteryErrBlub",
            "description": "Akkufehler",
            "reason": ["Akku defekt","Controllerboard defekt","Mainboard defekt"],
            "disposal": ["Akku erstzen","Controllerboard ersetzen","Mainboard ersetzen"],
            "remark": "Bei Akkutausch: Reset Nutzung im Wartungsmenü"
          }
        ]
      }
      """
    
    
    let parsed_json = parseJson(str_json)
    
    
    proc getErrCodes(jn: JsonNode, errcode = ""): seq[oErrCode] =
      var 
        s_errors = newSeq[oErrCode]()
        oErr: oErrCode
      let a_errlist = jn["error_list"].getElems()
      for err in a_errlist:
        if errcode == "" or (errcode != "" and errcode == err["code"].getStr()):
          oErr.code = err["code"].getStr()
          oErr.device = @(err["device"].getElems())
          oErr.name = err["name"].getStr()
          oErr.description = err["description"].getStr()
          oErr.reason = @(err["reason"].getElems())
          oErr.disposal = @(err["disposal"].getElems())
          oErr.remark = err["remark"].getStr()
          s_errors.add(oErr)
      result = s_errors
      
    let sError102 = getErrCodes(parsed_json, "102")
    
    
    for oE in sError102:
      echo oE.code & ", " & oE.name
      echo oE.device
      echo "----------------------------------------"
    Alles anzeigen
    Code: Console
    102, BatteryErrBla
    @["dev A", "dev B", "dev C"]
    ----------------------------------------
    102, BatteryErrBlub
    @["dev D", "dev E", "dev F"]
    ----------------------------------------
  • [gelöst] Nested JSON to Object

    • BugFix
    • 21. September 2022 um 14:15
    Zitat von Moombas

    Ich meinte hier:

    Das ist keine JSON-Datei, sondern nur die Struktur mit Kommentaren (die in JSON-Dateien ja nicht möglich sind).

  • [gelöst] Nested JSON to Object

    • BugFix
    • 21. September 2022 um 13:02

    OK, ich löse das Problem nun anders. Die Verschachtelung der error_list konnte von der json Funktion nicht geparst werden, ich bekam ein Objekt mit einem leeren Array.

    Somit habe ich das um eine Stufe "entschachtelt" und führe den Error-Code in jedem Error-List Objekt mit.

    Nim
    import json
    
    
    let str_json =
      """
      {
        "title": "Test",
        "author": "BugFix",
        "articles": [
          {"number": "a123", "storage_location": "D-75"},
          {"number": "b456", "storage_location": "C-145"},
          {"number": "c789", "storage_location": "H-63"}
        ],
        "error_list": [
          {
            "code": "101",
            "device": ["dev A","dev B","dev C"],
            "name": "SensorErrBla",
            "description": "Sensorfehler",
            "reason": ["Mainboard defekt"],
            "disposal": ["Mainboard ersetzen"],
            "remark": ""
          },
          {
            "code": "101",
            "device": ["dev D","dev E","dev F"],
            "name": "SensorErrBlub",
            "description": "Sensorfehler",
            "reason": ["Mainboard defekt"],
            "disposal": ["Mainboard ersetzen"],
            "remark": ""
          },
          {
            "code": "102",
            "device": ["dev A","dev B","dev C"],
            "name": "BatteryErrBla",
            "description": "Akkufehler",
            "reason": ["Akku defekt","Controllerboard defekt"],
            "disposal": ["Akku erstzen","Controllerboard ersetzen"],
            "remark": ""
          },
          {
            "code": "102",
            "device": ["dev D","dev E","dev F"],
            "name": "BatteryErrBlub",
            "description": "Akkufehler",
            "reason": ["Akku defekt","Controllerboard defekt","Mainboard defekt"],
            "disposal": ["Akku erstzen","Controllerboard ersetzen","Mainboard ersetzen"],
            "remark": "Bei Akkutausch: Reset Nutzung im Wartungsmenü"
          }
        ]
      }
      """
    let 
      parse_json = parseJson(str_json)
      a_errlist = parse_json["error_list"].getElems()
    
    
    for e in a_errlist:
      if e["code"].getStr() == "102": echo e["name"].getStr(), ":   ", e["device"].getElems()
    Alles anzeigen
  • File in use / Überprüfung

    • BugFix
    • 21. September 2022 um 12:42
    Zitat

    Function _WinAPI_FileInUse

    Tests whether the specified file in use by another application

    #include <WinAPIFiles.au3>

    _WinAPI_FileInUse ( $sFilePath )

    Success: 1 - File in use by another application.

    Failure: 0.

    Alles anzeigen
  • [gelöst] Nested JSON to Object

    • BugFix
    • 21. September 2022 um 12:15
    Zitat von Moombas

    Fehlt dir in Zeile 18 deines Json strings nicht ein ","? Wobei das natürlich ein Copy/Paste Fehler sein kann, da du ja sicher mit anderen Daten arbeitest.

    Kann sein, dass ich den Wald vor lauter Bäumen nicht sehe.

    Zeile #18 des JSON ist doch Code-Zeile #43

    43    ],

    44 "error_list": {
    45 "101": [

    Da ist doch ein Komma. Oder wo meinst Du? Gib mal die Codezeile an oder kopiere die Zeile hier rein.

  • [gelöst] Nested JSON to Object

    • BugFix
    • 21. September 2022 um 10:30

    EDIT #3: Lösung mit geänderter JSON-Struktur hier: Post #4

    Lösung mit Überführung in Objekt hier: Post #7

    Ich hatte hier auf meine JSON-Datei verwiesen.

    Die Umsetzung in mein Projekt soll in Nim erfolgen.

    Ich habe die Struktur der JSON-Datei mal heruntergebrochen auf ein Minimum:

    Code
    {
      "KEY": "Value-String",            "# Version"
      "KEY": "Value-String",            "# Creator"
      "KEY": [                          "# Source: ARRAY OBJEKTE - keine fixe Anzahl"
        {
          "KEY": "Value-String",        "# product-number"
          "KEY": "Value-String"         "# title"
        }        
      ],
      "KEY": {                                                "# error-list: OBJEKT"
          "KEY": [                                            "# error-code: ARRAY OBJEKTE - keine fixe Anzahl"
            {
              "KEY": ["Array Strings - keine fixe Anzahl"],   "# device"
              "KEY": "Value-String",                          "# name"
              "KEY": "Value-String",                          "# description"
              "KEY": ["Array Strings - keine fixe Anzahl"],   "# reason"
              "KEY": ["Array Strings - keine fixe Anzahl"],   "# disposal"
              "KEY": "Value-String"                           "# remark"
            }
          ]
      }
    }
    Alles anzeigen

    Die Nim JSON Library bietet die Möglichkeit, die geparsten JSON-Daten in ein Objekt zu überführen.

    Somit habe ich auf obiger Struktur aufbauend meine Datentypen erstellt.

    Hier mal meine Testdatei mit minimalem JSON-Musterdatensatz:

    Nim
    import json
    type 
      oSource = object
        product_number: string
        product_title: string
      oErrCode = object
        device: openArray[string]
        name: string
        description: string
        reason: openArray[string]
        disposal: openArray[string]
        remark: string
      oErrListItem = object
        code_number: string
        code_item: openArray[oErrCode]
      oErrList = object
        errors: openArray[oErrListItem]
      oError = object
        version: string
        craetor: string
        source: openArray[oSource]
        error_list: oErrList
    
    
    let err_json = 
      """
      {
        "version": "2022-09",
        "creator": "BugFix",
        "source": [
          {
            "product_number": "XYZ 123ab",
            "product_title": "Servicemanual für Geräte des Typs A / B"
          },
          {
            "product_number": "XYZ 123c",
            "product_title": "Servicemanual für Geräte des Typs C"
          },
          {
            "product_number": "XYZ 123def",
            "product_title": "Servicemanual für Geräte des Typs D / E / F"
          }
        ],
        "error_list": {
          "101": [
            {
              "device": ["dev A","dev B","dev C"],
              "name": "SensorErrBla",
              "description": "Sensorfehler",
              "reason": ["Mainboard defekt"],
              "disposal": ["Mainboard ersetzen"],
              "remark": ""
            },
            {
              "device": ["dev D","dev E","dev F"],
              "name": "SensorErrBlub",
              "description": "Sensorfehler",
              "reason": ["Mainboard defekt"],
              "disposal": ["Mainboard ersetzen"],
              "remark": ""
            }
          ],
          "102": [
            {
              "device": ["dev A","dev B"],
              "name": "BatteryErrBla",
              "description": "Akkufehler",
              "reason": ["Akku defekt","Controllerboard defekt"],
              "disposal": ["Akku erstzen","Controllerboard ersetzen"],
              "remark": "Bei Akkutausch: Reset Nutzung im Wartungsmenü"
            },
            {
              "device": ["dev C"],
              "name": "BatteryErrBlub",
              "description": "Akkuladefehler",
              "reason": ["Controllerboard defekt"],
              "disposal": ["Controllerboard ersetzen"],
              "remark": ""
            },
            {
              "device": ["dev D","dev D],
              "name": "BatteryErrBlaBlub",
              "description": "Akkufehler",
              "reason": ["Akku defekt","Akku nicht vorhanden"],
              "disposal": ["Akku ersetzen","Akku einsetzen"],
              "remark": "Bei Akkutausch: Reset Nutzung im Wartungsmenü"
            }
          ]
        }
      }
      """  
      
    let 
      obj_json = parseJson(err_json)        # JSON String parsen
      oErrorsJSON = to(obj_json, oError)    # JSON String in mein Objekt überführen
    
    
    echo oErrorsJSON.creator
    Alles anzeigen

    Grundsätzlich ist die Überführung verschachtelteter Strukturen in ein Objekt möglich: Nim: How to parse nested JSON into objects

    Im dortigen Bsp. sind jedoch alle Daten fix.

    Ich habe jedoch in allen Arrays eine veränderliche Anzahl von Einträgen, deshalb die Nutzung von "openArray". Und hier liegt das Problem. Gleich beim ersten Auftauchen fliegt es mir um die Ohren:

    Code
    Error: type mismatch: got <openArray[oSource], JsonNode, string>
    but expected one of:
    proc initFromJson(dst: var JsonNode; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var JsonNode
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson(dst: var bool; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var bool
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson(dst: var string; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var string
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[S, T](dst: var array[S, T]; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var array[S, T]
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T: SomeFloat](dst: var T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var T: SomeFloat
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T: SomeInteger](dst: var T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var T: SomeInteger
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T: distinct](dst: var T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var T: distinct
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T: enum](dst: var T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var T: enum
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T: object | tuple](dst: var T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var T: object or tuple
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T](dst: var Option[T]; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var Option[initFromJson.T]
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T](dst: var OrderedTable[string, T]; jsonNode: JsonNode;
                        jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var OrderedTable[system.string, initFromJson.T]
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T](dst: var Table[string, T]; jsonNode: JsonNode;
                        jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var Table[system.string, initFromJson.T]
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T](dst: var ref T; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var ref T
      but expression 'dst.source' is of type: openArray[oSource]
    proc initFromJson[T](dst: var seq[T]; jsonNode: JsonNode; jsonPath: var string)
      first type mismatch at position: 1
      required type for dst: var seq[T]
      but expression 'dst.source' is of type: openArray[oSource]
    Alles anzeigen

    In einem ersten Versuch hatte ich statt "openArray[string]" mit Sequences gearbeitet. Nur schlägt auch das fehl, weil der JSON-Parser wohl erkennt, wenn Daten in einem Array vorliegen und die Übernahme in eine Sequenz ablehnt. - Fehlermeldung (Compile) war in etwa: "Type is seq[string] but array found".

    Wie komme ich nun am besten aus der Situation raus?

    Momentan fiele mir nur ein: Statt "openArray" mit "array[string,FIXE-ZAHL]" zu arbeiten und alle Einträge in der JSON-Datei entsprechend mit Leerwerten auffüllen.

    Also wenn ihr Ideen habt: Gern her damit.

    EDIT:

    OK, in der Beschreibung zur Funktion to steht es auch

    Zitat

    Known limitations:

    Heterogeneous arrays are not supported.

    Dann muss ich mich wohl doch von Node zu Node hangeln.

    EDIT #2:

    Hmm, ein weiteres Problem

    Mit dem JSON-String aus obigem Code

    Nim
    let 
      obj_json = parseJson(err_json)        # JSON String parsen
    
    echo obj_json["version"].getStr()

    Führt zum Fehler bei der Ausführung:

    Code
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(931) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(847) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(806) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(806) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(815) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(806) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\json.nim(818) parseJson
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\parsejson.nim(526) eat
    C:\Users\BugFix\scoop\apps\nim\1.2.0\lib\pure\parsejson.nim(522) raiseParseErr
    Error: unhandled exception: input(36, 15) Error: ] expected [JsonParsingError]

    Die Zeile, bevor der Error geworfen wird ist: eat(p, tkBracketRi)

    Nach meinem Verständnis ein Fehler: Schließende Klammer nicht gefunden. Aber die Klammerzuordnung ist korrekt im JSON-String.

    Großes :?:

  • Daten in JSON anlegen - Struktur korrekt?

    • BugFix
    • 19. September 2022 um 22:45
    Zitat von Kanashius

    Es kommt zwar drauf an, wie viele Geräte du generell verwerwaltest,... Aber ich würde in Erwägung ziehen, die Infos nach Gerät zu speichern und dann ggf. alle durchiterieren, um die Geräte zu finden, die die Fehlermeldung haben.

    Selbst wenn du 10000 Geräte hast dürfte das durchlaufen nicht lange dauern.

    Der Hinweis ist grundsätzlich richtig. Ich hatte aber nicht erwähnt, dass es hier nur um Gerätetypen allgemein geht. Also nicht für jedes (mit Seriennnummer identifizierbare) Gerät werden Fehlercodes gespeichert, sondern nur über den Artikel als solchen. Und diese Anzahl ist bei uns überschaubar, so etwa 50-60 Artikel sind betroffen. Die Anzahl der relevanten Fehler ist bei etwa 30 - 40 pro Gerätetyp.

    Ausschnitt JSON
    Code
      "error-list": {
        "207": [
          {
          "device": ["prisma SMART/SOFT","prisma SMART/SOFT plus/max"],
          "name": "TempSensorError",
          "description": "Sensorfehler",
          "reason": ["Temperatursensor defekt oder nicht angeschlossen","Mainboard defekt"],
          "disposal": ["Temperatursensor ersetzen","Mainboard ersetzen"],
          "remark": ""
          },
          {
          "device": ["prisma VENT30/40/50","prisma VENT30-C/40-C/50-C"],
          "name": "",
          "description": "Modulfehler",
          "reason": ["Verbindungskabel defekt","Mainboard defekt","PSG-Modul defekt","prisma CHECK defekt"],
          "disposal": ["Verbindungskabel ersetzen","Mainboard ersetzen","PSG-Modul ersetzen","prisma CHECK ersetzen"],
          "remark": ""
          }
        ],
        ...
      }
    Alles anzeigen

    Ich habe bei einigen Fehlercodes 2 max. 3 unterschiedliche Bedeutungen. Somit ist der Aufwand (s. Bsp.) auf 2 oder 3 Einträge begrenzt.

    Eine Speicherung mit PrimärKey=Gerätetyp würde für jeden Eintrag aus dem Array "device" einen Eintrag erfordern mit allen anderen Angaben. Der obige Eintrag wäre dann doppelt so umfangreich und voll unnötiger Redundanzen.

    Meiner Meinung nach ist die bisherige Variante für meinen Anwendungsfall passend.

    Trotzdem Danke für die Investition deines Gehirnschmalzes. 8o

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™