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

Beiträge von Andy

  • Assembler: Farben zählen

    • Andy
    • 27. März 2024 um 20:44
    Zitat von DOheim

    Ich habe ja noch ein eigentlich einfaches Bitmap-Problem. Das verrate ich dir aber nicht. Sonst hast du es im Nu gelöst und ich lerne nichts hinzu :)

    Nanana....ich tüftele auch gerne, aber manchmal ist der Weg das Ziel! Mit dem "Weg" meine ich den gegenseitigen Austausch! Wie du sicher weißt, sind schon etliche der "anderen" Dinosaurier ausgestorben. Daher freue ich mich immer wie ein kleines Kind, wenn jemand an diesem "Oldschool Assembler Gedöns" auch (noch) seinen Spass hat.

    Wobei, um ehrlich zu sein, ich bemitleide ehrlich gesagt diese armen Schweine, die heute vor der Glotze sitzen und in irgendwelchen "neumodischen" esoterischen Sprachen sog. "Hightech" verzapfen und dann, wenn etwas nicht funktioniert, das Internet mit Hilfeanfragen fluten. Seltsamerweise sind dann die "Helfer" (fast) immer irgendwelche "alten Säcke", die sich (natürlich) sowohl mit dem altmodischen Kram aus dem Computerpleistozän auskennen, als auch mit dem neumodischen Gedöns:party:.

    Obwohl auch junge Leute unglaublich fit sind. Ich bekomme netterweise immer mal wieder Berichte aus Jülich vom dortigen Forschungszentrum und HPC (High-Performance-Computing) zugespielt und war auch schon dort und konnte mich mit einigen der "richtigen" Programmierer dort unterhalten. Da weiß jeder, wie er(sie) die Maschine codetechnisch zu füttern hat! Und ja, dort werden auch die letzten Register in den zig-tausenden Prozessoren ausgenutzt, um das letzte Quentchen Leistung rauszukitzeln. Ohne UMFASSENDE Assemblerkentnisse bzw. detailliertes Know-How über die internen Rechnerstrukturen ist auch keine "High-Performance" zu erzielen.


    Zitat von DOheim

    Jetzt habe ich mir erst einmal ein Rahmenprogramm geschrieben, das es mir beim Test leicht macht, zwischen den einzelnen Arbeitsphasen

    _AssembleIt2("uint ..." ,

    _AssembleIt2("retbinary ... " ,

    nur DllCallAddress("uint:cdecl ... " ohne _AssembleIt

    umzuschalten.

    :party:.....würdest du dieses "Rahmenprogramm" ggf. mit uns anderen "Dinosauriern" teilen oder wenigstens kurz beschreiben was es macht?!:Glaskugel:


    Zitat

    Zitat von UEZ

    Echt jetzt? 8|

    Zitat von BugFix

    Ja, ja - er ist der letzte Zeitzeuge der Schlacht von Waterloo. 😝

    =O.....du Sack8o...jetzt fühl ich mich alt.....:theke:...obwohl ich mich vor ner Stunde erst für 45min an meinen Klimmzugturm zum Schwitzen gebracht hatte....Calisthenics FTW!

  • Assembler: Farben zählen

    • Andy
    • 26. März 2024 um 21:19
    Zitat von DOheim

    Aber ein Mangel bestand noch, dass die schwarzen Pixel (also Farbwert 0x000000) nicht erkannt wurden.

    Hmmmm....DAS muss ich auch untersuchen....schön, wenn man Code dokumentiert...habs sofort gefunden :o)

    Code
        @count_colors:
        sub edx,1                   ;jedes pixel
     ;   jz @end                     ;alle pixel durchlaufen
        mov ecx,[esi+edx*4]         ;ecx=anzahl, edx=farbwert; esi=pointer pixelstruct
        cmp ecx,0
        je @count_colors            ;wenn ungleich null...ist farbe gefunden

    ich hatte schon bei Farbe = 0x000001 aufgehört, lass mal das jz @end weg und

    ersetze das Ende der Schleife mit

    Code
    	cmp edx,0					;ende erreicht?
        jne @count_colors           ;nein, dann weiter mit schleife alle farben

    Das müsste es gewesen sein....teste mal bitte und gib Rückmeldung :party:

    **EDIT

    besser das gesamte Script:

    AutoIt
     #include <GDIPlus.au3>
    ;~ #include <WinAPI.au3>
    ;~ #include <Array.au3>
    ;~ #include <GUIConstantsEx.au3>
    ;~ #include <StructureConstants.au3>
    #include <WindowsConstants.au3>
    ;~ #include <assembleit2_64.au3>
    #include <assembleit2_64.au3>
    
    
    
    
    #AutoIt3Wrapper_UseX64=n
    
    
    
    
    #cs _countpixelcolors           ;
        Use32                       ;32Bit!
    
    
        org $PTR_SOURCE_ASMCODE     ;only needed for assembleit debugger
    
    
        mov edi,dword[esp+4]        ;pointer bitmap
        mov ecx,dword[esp+8]        ;width bitmap
        mov ebx,dword[esp+12]       ;height bitmap
        mov esi,dword[esp+16]       ;pointer pixelstruct
        movd xmm1,dword[esp+20]     ;pointer textstruct
    
        rdtsc                       ;timer sichern
        push eax
    
        ;~ _asmdbg_()  ;debugger
    
    
        mov eax,ebx                 ;h
        mul ecx                     ;w*h
        mov edx,eax                 ;w*h
        movd xmm0, edx              ;sichern anzahl
    
    
        ;zuerst werden die Pixel durchlaufen, die Farbe jedes Pixels wird an der Speicherstelle seines "Farbwerts" hochgezählt
    
    
        @pixel_count:               ;alle pixel
        mov eax,[edi]               ;farbe
        and eax,0xFFFFFF            ;eliminieren alpha-channel
        ;~          _asmdbg_()
        inc dword [esi+eax*4]       ;farbwert=farbwert+1, address=colorRGB^^
        ;add dword [esi+eax*4],1         ;schneller?
        add edi,4                   ;nächste farbe
        sub edx,1                   ;pixelcounter
        jnz near @pixel_count       ;jump if not zero(<0)
    
        ;***********************************************************************************
        ;jetzt werden die gezählten Farbwerte nacheinander als Text in HEX-Darstellung und der Anzahl als Integerwert in eine textstruct geschrieben
        ;Format: 6BF1E5,1234567@crlf
    
    
        movd xmm4,edi               ;sichern pointer bitmap
    
    
        mov edx,0x1000000           ;anzahl farben 0xFFFFFF +1
        movd ebx,xmm1               ;pointer textstruct
        mov edi,-4                  ;pointer colorstruct
    
        @count_colors:
        sub edx,1                   ;jedes pixel
     ;   jz @end                     ;alle pixel durchlaufen
        mov ecx,[esi+edx*4]         ;ecx=anzahl, edx=farbwert; esi=pointer pixelstruct
        cmp ecx,0
        je @count_colors            ;wenn ungleich null...ist farbe gefunden
    
    
        ;~     _asmdbg_()
    
        ;hex-werte farbe =6 Bytes
        ;aus den 6 nibbles die 6 bytes machen, nibble+48 (0x30) =ASCII-Ziffer
        ;zuerst aus den beiden bytes ( Bit 4444333322221111) die nibble erweitern zu 0000444400003333 und 0000222200001111
    
    
        movd xmm3,eax               ;sichern wg registerpressure
        movd xmm4,edx               ;aka push/pop
        movd xmm5,esi
        movd xmm6,ecx
    
    
        mov eax,edx
        mov edi,eax
    
    
        ;schneller ist natürlich eine LUT^^, aber so geht es auch
        ;**************************************************************
        mov edx,0                   ;6  nibbles
        _int2hex:
        mov ecx,20                  ;5*4 shiften
        lea esi,[4*edx]             ;anzahl der zu shiftenden bits
        sub ecx,esi                 ;ecx=20,ecx
        shr eax,cl                  ;nach al shiften
        and al,0xF                  ;obere 4 nibble eliminieren
        cmp al,9                    ;größer oder kleiner als A?
        jle _groesserA
        add al,7                    ;A-F
        _groesserA:
        add al,48                   ;1-9
    
        mov byte[ebx+edx],al        ;ascii-hexcode in struct
        mov eax,edi
    
        add edx,1
        ;    _asmdbg_()
        cmp edx,6                   ;alle 6 nibble bearbeitet?
        jne _int2hex
    
        add ebx,edx                 ;ein zeichen (6 bytes) weiter
        mov byte [ebx],44           ;komma
        add ebx,1                   ;ein zeichen weiter
    
        mov edi,ebx                 ;pointer text
        movd ebx,xmm6               ;anzahl integer
    
        ;************************************************************
        ;aus einer Zahl(Registerinhalt) einen ZiffernString machen: http://dcla.rkhb.de/umwandlung/int2dez.html
        ;und in die struct schreiben
        push   ebx                  ;alle benötigten Register sichern
        push   ecx                  ;alle benötigten Register sichern
        mov eax, ebx                ;Zahl laden
        mov ebx, 10                 ;Divisor
        xor ecx, ecx                ;ECX=0 (Anzahl der Ziffern)
        Schleife_1:
        xor edx, edx
        div ebx                     ; EDX:EAX / EBX = EAX Rest EDX
        push dx                     ; LIFO
        add cl,1                    ; ADD soll schneller sein als INC
        or  eax, eax                ; AX = 0?
        jnz Schleife_1              ; nein: nochmal
        Schleife_2:
        pop ax                      ; gepushte Ziffern zurückholen
        or al, 00110000b            ; Umwandlung in ASCII
        stosb                       ; Nur AL nach [EDI] (EDI ist ein Zeiger auf den String)
        loop Schleife_2             ; bis keine Ziffern mehr da sind
        mov byte [edi],0Dh          ;CR  CarriageReturn, man könnte auch ein Komma (ascii=2C) einsetzen, dazu noch ein nullbyte als EndOfString
        add edi,1                   ;ein Byte weiter
        pop   ecx                   ;Register wiederherstellen
        pop   ebx                   ;Register wiederherstellen
        ;************************************************************Ende Ziffer aus Register
    
        movd esi,xmm5
        movd edx,xmm4               ;restaurieren
        mov ebx,edi
    
    	cmp edx,0
        jne @count_colors           ;schleife alle farben
    
        @end:
    	pop    ebx
    	rdtsc
    	sub    eax,ebx
    
        ret
    
    
    #ce
    
    
    
    
    
    
    
    
    
    
    AutoItSetOption("GUIOnEventMode", 1) ;event mode
    
    
    _GDIPlus_Startup()              ;tt
    
    
    Global $ptr_bitmap, $hbmp, $iwidth, $iheight ;werden ByRef von _CreateNewBmp32FromFile ausgefüllt
    
    
    
    
    $sFile = FileOpenDialog("Bilder", @ScriptDir, "Bilder (*.jpg;*.bmp;*.png)")
    $DC_bitmap = _CreateNewBmp32FromFile($sFile, $ptr_bitmap, $hbmp, $iwidth, $iheight)
    
    
    ;assembled code by AssembleIt_64
    ;~ $binarycode = "0x8B7C24048B4C24088B5C240C8B742410660F6E4C24140F315089D8F7E189C2660F6EC28B0725FFFFFF00FF048683C70483EA010F85EAFFFFFF660F6EE7BA00000001660F7ECBBFFCFFFFFF83EA010F848C0000008B0C9683F90074EF660F6ED8660F6EE2660F6EEE660F6EF189D089C7BA00000000B9140000008D34950000000029F1D3E8240F3C097E020407043088041389F883C20183FA0675D901D3C6032C83C30189DF660F7EF3535189D8BB0A00000031C931D2F7F3665280C10109C075F366580C30AAE2F9C6070D83C701595B660F7EEE660F7EE289FBE96BFFFFFF5B0F3129D8C3"
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;~ $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes
    ;~ DllStructSetData($tCodeBuffer, 1, $binarycode)
    
    
    
    
    $colorstruct = DllStructCreate("uint[" & 256 ^ 3 & "]");anzahl möglicher Farben
    $ptr_colorstruct = DllStructGetPtr($colorstruct)
    
    
    $textstruct = DllStructCreate("char[" & 18 * $iwidth * $iheight & "]");maximale Anzahl Zeichen
    $ptr_textstruct = DllStructGetPtr($textstruct)
    ;9 Stellen integer
    ;6 Stellen Hexdarstellung
    ;1 Stellen Komma
    ;2 Stellen CRLF
    
    
    $t = TimerInit()
    
    
    ;Pixelfarben zählen und in Hexcode,Anzahl umwandeln, schreiben in textstruct
    ;~ DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", $ptr_bitmap, "int_ptr", $iwidth, "int_ptr", $iheight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct)
    ;~ $binarycode = _AssembleIt2("retbinary", "_countpixelcolors")
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
     $ret = _AssembleIt2("uint", "_countpixelcolors", "ptr", $ptr_bitmap, "int_ptr", $iWidth, "int_ptr", $iHeight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct,"retbinary",@ScriptLineNumber)
    ConsoleWrite('Takte: ' & $ret & @CRLF) ;### Debug Console
    
    
    
    ;in der dllstruct stehen nun die Farbe,Anzahl
    $text = DllStructGetData($textstruct, 1)
    $text = StringTrimRight($text, 1) ;letztes LF entfernen
    
    
    $m = TimerDiff($t)
    
    
    $text = StringReplace($text, @CR, @CRLF) ;autoit is fast too^^
    $number_colors = @extended + 1
    
    
    
    
    MsgBox(0, "Timer ASM picelcounter", "Within " & Int($m) & "ms " & $number_colors & " colors were counted!")
    
    
    ;anzeigen als text
    FileDelete("Pixelcounter.txt")
    FileWrite("Pixelcounter.txt", $text)
    ShellExecute("Pixelcounter.txt")
    
    
    $colorarray = StringSplit($text, @LF)
    _ArrayDisplay($colorarray)
    
    
    
    
    ;Autoit-Version, dauert.....sehr lange^^
    ;~ For $color = 1 To 256 ^ 3                         ;alle farben
    ;~     $anzahl = DllStructGetData($colorstruct, 1, $color);auslesen
    ;~     If $anzahl <> 0 Then ConsoleWrite(Hex($color - 1, 6) & @TAB & $anzahl & @CRLF)
    ;~ Next
    
    
    $hGUI = GUICreate("ASM Pixelcounter", $iwidth, $iheight);GUI
    $DC_gui = _WinAPI_GetDC($hGUI)  ;Device-context
    
    
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()
    _WinAPI_BitBlt($DC_gui, 0, 0, $iwidth, $iheight, $DC_bitmap, 0, 0, 0xCC0020);bitmap in DC blitten
    
    
    Do
    Until Not Sleep(100)            ;
    
    
    
    
    Func _Exit()
    
    
        _GDIPlus_Shutdown()
        GUIDelete()
        Exit
    EndFunc                         ;==>_Exit
    
    
    
    
    Func _CreateNewBmp32FromFile($bmpfile, ByRef $ptr, ByRef $hbmp, ByRef $iwidth, ByRef $iheight) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
        Local $hbitmap, $hdc, $hcdc
    
    
        $hbitmap = _GDIPlus_ImageLoadFromFile($bmpfile)
        If @error Or $hbitmap = 0 Then
            MsgBox(0, "Func _CreateNewBmp32FromFile()", "Error opening File: " & @CRLF & $bmpfile)
            Return -1
        EndIf
        $hbmpfile = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
        $iwidth = _GDIPlus_ImageGetWidth($hbitmap)
        $iheight = _GDIPlus_ImageGetHeight($hbitmap)
        $hcdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hcdc, $hbmpfile) ;image im hcdc
    
    
        ;neue bitmap
        $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
        DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
        DllStructSetData($tBMI, 2, $iwidth)
        DllStructSetData($tBMI, 3, -$iheight) ;minus =standard = bottomup
        DllStructSetData($tBMI, 4, 1)
        DllStructSetData($tBMI, 5, 32) ;32 Bit = 4 Bytes => AABBGGRR
        $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
        $hbmp = $adib[0]            ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
        $ptr = $adib[4]             ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    
    
        $hdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hdc, $hbmp) ;leere bitmap im hdc
        _WinAPI_BitBlt($hdc, 0, 0, $iwidth, $iheight, $hcdc, 0, 0, $srccopy);image in leere bitmap
        _WinAPI_DeleteDC($hcdc)
        _WinAPI_DeleteObject($hbmpfile)
        Return $hdc                 ;DC der Bitmap zurückgeben
    
    
    EndFunc                         ;==>_CreateNewBmp32FromFile
    Alles anzeigen
  • Assembler: Farben zählen

    • Andy
    • 24. März 2024 um 12:17

    Hi,

    da sind in deinem asm-code wohl einige Zeilen verloren gegangen :o)

    @end:
    pop ebx
    rdtsc
    sub eax,ebx

    ret

    Füge die 3 Zeilen zwischen dem @end: und ret dazu und alles läuft...

    Nur zur Erklärung, ich nutze zum "Takte zählen" den (bzw. einen der) Prozessorinternen TimeStampCounter, also einen Timer. RDTSC aka ReaDTimeStampCounter

    Der schreibt den aktuellen timestamp als 64 Bit "Timer" in die Register EAX und EDX. Ich nutze für kurze Schleifen nur die unteren 32Bit, also das EAX-Register.

    Dieses wird am Anfang des Codes auf den Stack gepushed, am Ende des Codes wird durch RDTSC wieder der neue Timestamp ausgelesen.

    POP EBX holt den alten Wert vom Stack

    RDTSC schreibt den aktuellen Timerwert in EAX, Info dazu https://www.felixcloutier.com/x86/rdtsc übrigens ein feines Nachschlagewerk..

    SUB EAX,EBX ermittelt die Differenz, also die Anzahl der Prozessortakte, in EAX

    Nach dem RET wird EAX an das aufrufende Programm, also AutoIt, zurückgegeben und kann angezeigt werden. Das macht übrigens der erste Parameter, das "uint" in AssembleIt. Beim DllCalladdress() werden der Rückgabewert und die Aufrufparameter in einem Array zurückgegeben.


    Übrigens, wenn Du Interesse hast, ich hatte im letzten Jahr AssembleIt noch etwas weiter aufgebohrt und etliches gefixt.

    Jetzt gibt es auch ein rudimentäres "How to", schau mal rein und sag mal was du davon hälst...

    AssembleIt2_64 v 313.zip

    In den Dateien Example1 bis Example 5 wird haarklein erklärt welche Möglickeiten AssembleIt hat, eins der "neuen" Features ist bspw. durch Anhängen von

    ,"retbinary",@ScriptlineNumber) an den Funktionsaufruf von AssembleIt2 wird der Aufrufcode für DllCallAddress() als einige Zeilen Code generiert und in die Konsole und ins Clipboard geschrieben, hier mal als Beispiel:

    AutoIt
    #include <GDIPlus.au3>
    ;~ #include <WinAPI.au3>
    ;~ #include <Array.au3>
    ;~ #include <GUIConstantsEx.au3>
    ;~ #include <StructureConstants.au3>
    #include <WindowsConstants.au3>
    ;~ #include <assembleit2_64.au3>
    #include <assembleit2_64.au3>
    
    
    
    
    #AutoIt3Wrapper_UseX64=n
    
    
    
    
    #cs _countpixelcolors           ;
        Use32                       ;32Bit!
    
    
        org $PTR_SOURCE_ASMCODE     ;only needed for assembleit debugger
    
    
        mov edi,dword[esp+4]        ;pointer bitmap
        mov ecx,dword[esp+8]        ;width bitmap
        mov ebx,dword[esp+12]       ;height bitmap
        mov esi,dword[esp+16]       ;pointer pixelstruct
        movd xmm1,dword[esp+20]     ;pointer textstruct
    
        rdtsc                       ;timer sichern
        push eax
    
        ;~ _asmdbg_()  ;debugger
    
    
        mov eax,ebx                 ;h
        mul ecx                     ;w*h
        mov edx,eax                 ;w*h
        movd xmm0, edx              ;sichern anzahl
    
    
        ;zuerst werden die Pixel durchlaufen, die Farbe jedes Pixels wird an der Speicherstelle seines "Farbwerts" hochgezählt
    
    
        @pixel_count:               ;alle pixel
        mov eax,[edi]               ;farbe
        and eax,0xFFFFFF            ;eliminieren alpha-channel
        ;~          _asmdbg_()
        inc dword [esi+eax*4]       ;farbwert=farbwert+1, address=colorRGB^^
        ;add dword [esi+eax*4],1         ;schneller?
        add edi,4                   ;nächste farbe
        sub edx,1                   ;pixelcounter
        jnz near @pixel_count       ;jump if not zero(<0)
    
        ;***********************************************************************************
        ;jetzt werden die gezählten Farbwerte nacheinander als Text in HEX-Darstellung und der Anzahl als Integerwert in eine textstruct geschrieben
        ;Format: 6BF1E5,1234567@crlf
    
    
        movd xmm4,edi               ;sichern pointer bitmap
    
    
        mov edx,0x1000000           ;anzahl farben 0xFFFFFF +1
        movd ebx,xmm1               ;pointer textstruct
        mov edi,-4                  ;pointer colorstruct
    
        @count_colors:
        sub edx,1                   ;jedes pixel
        jz @end                     ;alle pixel durchlaufen
        mov ecx,[esi+edx*4]         ;ecx=anzahl, edx=farbwert; esi=pointer pixelstruct
        cmp ecx,0
        je @count_colors            ;wenn ungleich null...ist farbe gefunden
    
    
        ;~     _asmdbg_()
    
        ;hex-werte farbe =6 Bytes
        ;aus den 6 nibbles die 6 bytes machen, nibble+48 (0x30) =ASCII-Ziffer
        ;zuerst aus den beiden bytes ( Bit 4444333322221111) die nibble erweitern zu 0000444400003333 und 0000222200001111
    
    
        movd xmm3,eax               ;sichern wg registerpressure
        movd xmm4,edx               ;aka push/pop
        movd xmm5,esi
        movd xmm6,ecx
    
    
        mov eax,edx
        mov edi,eax
    
    
        ;schneller ist natürlich eine LUT^^, aber so geht es auch
        ;**************************************************************
        mov edx,0                   ;6  nibbles
        _int2hex:
        mov ecx,20                  ;5*4 shiften
        lea esi,[4*edx]             ;anzahl der zu shiftenden bits
        sub ecx,esi                 ;ecx=20,ecx
        shr eax,cl                  ;nach al shiften
        and al,0xF                  ;obere 4 nibble eliminieren
        cmp al,9                    ;größer oder kleiner als A?
        jle _groesserA
        add al,7                    ;A-F
        _groesserA:
        add al,48                   ;1-9
    
        mov byte[ebx+edx],al        ;ascii-hexcode in struct
        mov eax,edi
    
        add edx,1
        ;    _asmdbg_()
        cmp edx,6                   ;alle 6 nibble bearbeitet?
        jne _int2hex
    
        add ebx,edx                 ;ein zeichen (6 bytes) weiter
        mov byte [ebx],44           ;komma
        add ebx,1                   ;ein zeichen weiter
    
        mov edi,ebx                 ;pointer text
        movd ebx,xmm6               ;anzahl integer
    
        ;************************************************************
        ;aus einer Zahl(Registerinhalt) einen ZiffernString machen: http://dcla.rkhb.de/umwandlung/int2dez.html
        ;und in die struct schreiben
        push   ebx                  ;alle benötigten Register sichern
        push   ecx                  ;alle benötigten Register sichern
        mov eax, ebx                ;Zahl laden
        mov ebx, 10                 ;Divisor
        xor ecx, ecx                ;ECX=0 (Anzahl der Ziffern)
        Schleife_1:
        xor edx, edx
        div ebx                     ; EDX:EAX / EBX = EAX Rest EDX
        push dx                     ; LIFO
        add cl,1                    ; ADD soll schneller sein als INC
        or  eax, eax                ; AX = 0?
        jnz Schleife_1              ; nein: nochmal
        Schleife_2:
        pop ax                      ; gepushte Ziffern zurückholen
        or al, 00110000b            ; Umwandlung in ASCII
        stosb                       ; Nur AL nach [EDI] (EDI ist ein Zeiger auf den String)
        loop Schleife_2             ; bis keine Ziffern mehr da sind
        mov byte [edi],0Dh          ;CR  CarriageReturn, man könnte auch ein Komma (ascii=2C) einsetzen, dazu noch ein nullbyte als EndOfString
        add edi,1                   ;ein Byte weiter
        pop   ecx                   ;Register wiederherstellen
        pop   ebx                   ;Register wiederherstellen
        ;************************************************************Ende Ziffer aus Register
    
        movd esi,xmm5
        movd edx,xmm4               ;restaurieren
        mov ebx,edi
    
        jmp @count_colors           ;schleife alle farben
    
        @end:
    	pop    ebx
    	rdtsc
    	sub    eax,ebx
    
        ret
    
    
    #ce
    
    
    
    
    
    
    
    
    
    
    AutoItSetOption("GUIOnEventMode", 1) ;event mode
    
    
    _GDIPlus_Startup()              ;tt
    
    
    Global $ptr_bitmap, $hbmp, $iwidth, $iheight ;werden ByRef von _CreateNewBmp32FromFile ausgefüllt
    
    
    
    
    $sFile = FileOpenDialog("Bilder", @ScriptDir, "Bilder (*.jpg;*.bmp;*.png)")
    $DC_bitmap = _CreateNewBmp32FromFile($sFile, $ptr_bitmap, $hbmp, $iwidth, $iheight)
    
    
    ;assembled code by AssembleIt_64
    $binarycode = "0x8B7C24048B4C24088B5C240C8B742410660F6E4C24140F315089D8F7E189C2660F6EC28B0725FFFFFF00FF048683C70483EA010F85EAFFFFFF660F6EE7BA00000001660F7ECBBFFCFFFFFF83EA010F848C0000008B0C9683F90074EF660F6ED8660F6EE2660F6EEE660F6EF189D089C7BA00000000B9140000008D34950000000029F1D3E8240F3C097E020407043088041389F883C20183FA0675D901D3C6032C83C30189DF660F7EF3535189D8BB0A00000031C931D2F7F3665280C10109C075F366580C30AAE2F9C6070D83C701595B660F7EEE660F7EE289FBE96BFFFFFF5B0F3129D8C3"
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, $binarycode)
    
    
    
    
    $colorstruct = DllStructCreate("uint[" & 256 ^ 3 & "]");anzahl möglicher Farben
    $ptr_colorstruct = DllStructGetPtr($colorstruct)
    
    
    $textstruct = DllStructCreate("char[" & 18 * $iwidth * $iheight & "]");maximale Anzahl Zeichen
    $ptr_textstruct = DllStructGetPtr($textstruct)
    ;9 Stellen integer
    ;6 Stellen Hexdarstellung
    ;1 Stellen Komma
    ;2 Stellen CRLF
    
    
    $t = TimerInit()
    
    
    ;Pixelfarben zählen und in Hexcode,Anzahl umwandeln, schreiben in textstruct
    ;~ DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", $ptr_bitmap, "int_ptr", $iwidth, "int_ptr", $iheight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct)
    ;~ $binarycode = _AssembleIt2("retbinary", "_countpixelcolors")
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
     $ret = _AssembleIt2("uint", "_countpixelcolors", "ptr", $ptr_bitmap, "int_ptr", $iWidth, "int_ptr", $iHeight, "int_ptr", $ptr_colorstruct, "int_ptr", $ptr_textstruct,"retbinary",@ScriptLineNumber)
    ConsoleWrite('Takte: ' & $ret & @CRLF) ;### Debug Console
    
    
    ;in der dllstruct stehen nun die Farbe,Anzahl
    $text = DllStructGetData($textstruct, 1)
    $text = StringTrimRight($text, 1) ;letztes LF entfernen
    
    
    $m = TimerDiff($t)
    
    
    $text = StringReplace($text, @CR, @CRLF) ;autoit is fast too^^
    $number_colors = @extended + 1
    
    
    
    
    MsgBox(0, "Timer ASM picelcounter", "Within " & Int($m) & "ms " & $number_colors & " colors were counted!")
    
    
    ;anzeigen als text
    FileDelete("Pixelcounter.txt")
    FileWrite("Pixelcounter.txt", $text)
    ShellExecute("Pixelcounter.txt")
    
    
    $colorarray = StringSplit($text, @LF)
    _ArrayDisplay($colorarray)
    
    
    
    
    ;Autoit-Version, dauert.....sehr lange^^
    ;~ For $color = 1 To 256 ^ 3                         ;alle farben
    ;~     $anzahl = DllStructGetData($colorstruct, 1, $color);auslesen
    ;~     If $anzahl <> 0 Then ConsoleWrite(Hex($color - 1, 6) & @TAB & $anzahl & @CRLF)
    ;~ Next
    
    
    $hGUI = GUICreate("ASM Pixelcounter", $iwidth, $iheight);GUI
    $DC_gui = _WinAPI_GetDC($hGUI)  ;Device-context
    
    
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()
    _WinAPI_BitBlt($DC_gui, 0, 0, $iwidth, $iheight, $DC_bitmap, 0, 0, 0xCC0020);bitmap in DC blitten
    
    
    Do
    Until Not Sleep(100)            ;
    
    
    
    
    Func _Exit()
    
    
        _GDIPlus_Shutdown()
        GUIDelete()
        Exit
    EndFunc                         ;==>_Exit
    
    
    
    
    Func _CreateNewBmp32FromFile($bmpfile, ByRef $ptr, ByRef $hbmp, ByRef $iwidth, ByRef $iheight) ;ptr to bitmapdata, it is possible to manipulate one pixel if needed
        Local $hbitmap, $hdc, $hcdc
    
    
        $hbitmap = _GDIPlus_ImageLoadFromFile($bmpfile)
        If @error Or $hbitmap = 0 Then
            MsgBox(0, "Func _CreateNewBmp32FromFile()", "Error opening File: " & @CRLF & $bmpfile)
            Return -1
        EndIf
        $hbmpfile = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
        $iwidth = _GDIPlus_ImageGetWidth($hbitmap)
        $iheight = _GDIPlus_ImageGetHeight($hbitmap)
        $hcdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hcdc, $hbmpfile) ;image im hcdc
    
    
        ;neue bitmap
        $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
        DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
        DllStructSetData($tBMI, 2, $iwidth)
        DllStructSetData($tBMI, 3, -$iheight) ;minus =standard = bottomup
        DllStructSetData($tBMI, 4, 1)
        DllStructSetData($tBMI, 5, 32) ;32 Bit = 4 Bytes => AABBGGRR
        $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
        $hbmp = $adib[0]            ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
        $ptr = $adib[4]             ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    
    
        $hdc = _WinAPI_CreateCompatibleDC(0)
        _WinAPI_SelectObject($hdc, $hbmp) ;leere bitmap im hdc
        _WinAPI_BitBlt($hdc, 0, 0, $iwidth, $iheight, $hcdc, 0, 0, $srccopy);image in leere bitmap
        _WinAPI_DeleteDC($hcdc)
        _WinAPI_DeleteObject($hbmpfile)
        Return $hdc                 ;DC der Bitmap zurückgeben
    
    
    EndFunc                         ;==>_CreateNewBmp32FromFile
    Alles anzeigen
  • Konverter C++ Quellcode zu AutoIt-Skript

    • Andy
    • 15. März 2024 um 23:01

    Ja, "sehr kryptischer C(++)-Code" war und ist schon immer das allergrößte Problem, auch der C++-Programmierer gewesen....wenn es "fancy" ist, solch coolen Code zu schreiben, den kaum ein anderer lesen kann, dann ist das einfach nur ärmlich.

    Das hat auch definitiv nichts mit "Pro" zu tun, sondern damit, profilneurotisch den kurzen Bippes vertuschen zu wollen!

    Zitat von AspirinJunkie

    Dort kannst du dem einfach den Code vor die Füße werfen und fragen: "Was macht dieser Code?"

    DAS lass ich lieber^^. DIESE Versuche habe ich hinter mir! Ich hatte mich kurz nach Veröffentlichung von ChatGPT mal einige Tage intensiv mit der Materie und vor allem den Ergebnissen auseinandergesetzt und bin zur Ansicht gekommen, dass ich 90% der Zeit gespart hätte, wenn ich mich statt mit ChatGPT mit dem Thema auseinandergesetzt hätte! Die "schnelle" Antwort mag sich ab und zu ja "gut" anhören/lesen, aber die Verifizierung braucht umso länger! Und warum verifizieren wenn ich doch direkt die Thematik an der Quelle be- bzw. abarbeiten kann?

    Wenn ich Code ums verrecken nicht verstehe, dann ist der Code S C H E I S S E ! Wenn keine verständlichen Kommentare erklären was da vor sich geht und ich den Zusammenhang nirgendwo in einer Dokumentation finde, dann nützt mir der Code auch nichts?!

    Ich lese Code ja nicht "just for fun" (ok, manchmal schon^^) sondern um etwas (neues) zu lernen oder zu sehen wie ein anderer das/mein Problem besser als ich gelöst hat. DAS bringt mich weiter. Leider ist "guter" aka lesbarer Code vom Aussterben bedroht, weil (so gut wie) nicht mehr auffindbar. Und zwar deswegen, weil 1000-fach gecopypasteter und "cool" abgeänderter und "professionell" aussehender Code gepostet wird. In diesem Sumpf dann die Perlen zu finden, ist echt schwierig....

    Vor einigen Jahren, als Git noch in den Anfängen war und mehrheitlich von "echten" Profis genutzt wurde, konnte man zu bestimmten Themen zwar nur wenige, aber überwiegend brauchbare Treffer finden. Mittlerweile postet JEDER seinen Schrott dort und die Suche nach sinnvollen Beispielen endet meist im Frust.

    Zitat von PSblnkd

    Ich werde weitere Versuche unternehmen und berichten.

    Bin gespannt!:theke:

  • Konverter C++ Quellcode zu AutoIt-Skript

    • Andy
    • 10. März 2024 um 19:32
    Zitat von PSblnkd

    "C++ to VB Converter"

    Aus welchem anderen Grund als "just for fun" sollte man so etwas machen?!:/

    Autoit -> C(++) macht da wiederum Sinn, FALLS man die (wie angesprochen) 2 bis 3 verschachtelten FOR-Schleifen mit einigen mathematischen Berechnungen dazwischen etliche tausend mal schneller abwickeln möchte.

    Der Interpreter ist das Bottleneck! Die WIN-API-Aufrufe laufen in AutoIt genau so schnell wie in einer beliebigen Compilersprache, wenn man sich darauf beschränkt, was die eigentliche Intension von AutoIt ist!!

    Aber eine Compilersprache in eine andere "umzuwandeln", damit der Compiler daraus wiederum 99% identischen Maschinen-Code erzeugt ist imho sinnfrei! Es gibt auch nichts zu gewinnen, denn 100% aller "hardcore features" der "neuen" C++-Versionen sind in VB (oder einer anderen Sprache) nicht existent!


    Der Ansatz von AutoIt->LLVM scheint mir dagegen wesentlich fruchtbarer....ohne LLVM gäbe es definitiv 90% der "neuen" esoterischen Sprachen NICHT! Ein bisschen "coole" Syntax zu "entwickeln" ist eine Sache, aber daraus dann wettbewerbsfähige Compiler zu schnitzen für x verschiedene (Prozessor-) Architekturen ist etwas anderes...

    Wer sich für LLVM interessiert findet hier ein schönes und imho verständliches Beispiel! https://llvm.org/docs/tutorial/…tend/index.html

  • AutoIt WebDriver Crashkurs

    • Andy
    • 2. März 2024 um 10:08

    Hi Sven,

    sehr feines Projekt! Und aktuell sehr gut für mich um "einzusteigen":thumbup:

    "Früher" hatte ich, genau wie bei anderen "Programmiersprachen" auch bei Webseiten auf dem Standpunkt gestanden, "...if you want to know how it works, read the source...". Aber da HTML nur noch als Wrapper für JS und anderes (serverseitig ausgeführtes) Gedöns verwendet wird, fehlt(e), mir zumindest, der Ansatzpunkt.

    Aktuell habe ich ein Projekt, bei dem von einer Website ständig/täglich aktualisierte öffentliche Ausschreibungen gesichtet bzw gefiltert werden müssen. Ich stelle mir dann eine Ausgabe vor, welche die gefilterten Daten/Texte/Beschreibungen nach bestimmten Schlagwörtern durchsucht und bewertet und die Ergebnisse/Links dann ggf. per Mail versendet.

    Das "geklicke" und Einfügen/Einstellen von diversen Suchfiltern auf der Website ist das (mein) eigentliche(s) Problem, das Filtern bzw. Bewerten der Daten machen dann einige RegEx´e.

    Aber Dank deiner Repos sollte ich das in den Griff bekommen:Glaskugel:

  • SAP (Gesucht wird ein deutschsprachiges Tutorial für AutoIt mit SAP)

    • Andy
    • 25. Februar 2024 um 16:26
    Zitat von Mainz006

    (Deepl ist - wenn ich das richtig verstanden habe - für einen Monat kostenlos und kostet dann 89,88 jährlich.)

    Nein, Deepl ist komplett kostenlos in der Webvariante, genau wie google translate....https://www.deepl.com/translator

  • Richtig debuggen?

    • Andy
    • 23. Februar 2024 um 17:59
    Zitat von Moombas

    Ja, es ist Ansichtssache und soll kein "blame" sein aber gewisse Grundregeln gehören für mich dazu, auch wenn man alleine am Code arbeitet.

    Naja, ich denke wir sind da sehr nahe beieinander^^

    Wenn zu diesem Threadthema von jemandem der einen Namen wie der TE trägt ein "Fehler" wie oben gezeigt vorkommt, dann hat das sehe wenig mit deinen Ausführungen zu tun!

    Das Problem ist die strikte und generelle Unfähigkeit, Fehler (in welcher Form auch immer) zu finden und abzustellen! Woher diese Unfähigkeit kommt und wie dabei die (von dir nachvollziehbar beschriebenen) "Hilfen" einer Programmiersprache jemanden weiterbringen, sei dahingestellt....

    Jedenfalls sind 90% (eher mehr) Anfragen in den einschlägigen Programmier-Foren darin begründet, dass sich der Fragesteller mit dem Thema nicht oder nur oberflächlich befassen will, es wird stattdessen jemand gesucht, der einem "den Arm aus der Sonne legt", aka, die hingerotzten 5-10 Zeilen lauffähig macht!

    Aber irgendwie glaube ich, dass diejenigen unter uns, die in der Lage sind sich in anderer Leute Code hineinzuversetzen und in kürzester Zeit die "Fehler" zu finden, einen wieauchimmer "Knacks in der Birne" haben.

    Ich habe 13 Jahre mit einem Mitarbeiter zusammengearbeitet und immer mal wieder dessen Code debuggen müssen. Dabei saß ich immer neben ihm und habe genauestens erklärt was ich da mache und warum. 13 Jahre lang.....Mittlerweile ist es schon "viel" besser geworden, aber die Hilferufe kommen immer noch.....nicht mehr so oft, aber sie kommen?! Warum? Ich schreibe "Easy-Code", versuche nur die einfachsten Konstrukte zu benutzen, so dass jeder Dorfdepp in meinem Code lesen kann wie in einem Buch. Dafür musste ich mich vom Geschäftsführer einer (von uns verwendeten) führenden ERP-Branchensoftware als "Oldschool-Dinosaurier" bezeichnen lassen müssen. Die Retourekutsche drücke ich ihm jeden Monat wenn seine Jungs und Mädels als "Vollprofis" wieder mal programmiertechnischen Sondermüll abliefern. Wenn professionelle Datenbankspezialisten Funktionen abliefern die 1000x länger brauchen wie die eines "Freizeit-Oldschool-Dinosaurier"-Programmierers, dann sind wohl Nachfragen erlaubt. Genau wie danach, wieso gefixte Bugs nach diversen Updates "plötzlich" wieder auftauchen.....

    Das Thema ist lang....aber

    Zitat von SOLVE-SMART

    In einem Software-Entwicklungsteam mit bspw. Product Owner und Stakeholdern, ist man i.d.R. auch gezwungen Coding Guidelines, Code Conventions etc. einzuführen

    löst imho das eigentliche Problem nicht. Der nach den tollen Code Conventions (ich sag mal "schöne") Code soll in erster Linie fehlerfrei laufen! Was nützt mir ein fehlerbehafteter Code, der nach allen Regeln der Kunst "schick" gemacht ist, aber nicht oder nicht richtig funktioniert. Gerade dieser Code sollte doch am Besten zu debuggen sein, oder etwa nicht?! Dann sollten gerade bei solchem Code die Fixes doch im Handumdrehen gemacht werden können?!

  • Unit Testing in Autoit

    • Andy
    • 17. Februar 2024 um 12:44
    Zitat von water

    Die Schwierigkeit beim Testen sehe ich in der Auswahl der richtigen Testmethode, der Testfälle sowie der Testdaten.

    yepp, genau das meinte ich mit

    Zitat von Andy

    Ich bin ziemlich sicher dass "professionelle" Unit Tester das obere Ende der Fahnenstange in der Programmiererzunft sind.

    Ich sehe die "Unit" als BlackBox, einzig interessant ist was reingeht, und was letztendlich raus kommen soll. Dafür eine Testumgebung zu schreiben ist manchmal sicherlich Aufwendiger wie die Funktion selbst!

    Zitat von water

    Garbage in, Garbage out :)

    Hehe, THIS :thumbup:! Wenn man Code lesen kann wie ein Buch und während des Lesens die Funktion des Codes (ggf. noch anhand der Kommentare) verstehen kann, dann ist das eine Offenbarung! Alles andere ist programmierter Bullshit. Kein Wunder, wenn "große" Softwareprojekte komplett neu geschrieben werden statt sie zu debuggen oder zu verbessern. Das liegt einfach daran dass die Programmierer ihren Job beim ersten Mal nicht richtig gemacht haben,

    Zitat von Schnuffel

    Und wenn sich einer beschwert, **SNIP nicht nur Microsoft^^ *** schiebe ich bei Gelegenheit einen "fix" nach. :rofl:

    Ich sehe darin nicht das Problem! Das Problem ist den "Fix" gar nicht nachschieben zu können, weil man tausende Zeilen Müll produziert hat, in dem keine Sau mehr durchblickt!

    Und hier schließt sich der Kreis. Denn Unit Tests nützen hier nichts! Wäre der "Bug" im Vorfeld aufgefallen, hätte ihn der Programmierer oder spätestens der Unit Tester bemerkt!

    Ich lehne mich mal weit aus dem Fenster mit einer Behauptung: "Schreibe gut wartbaren Code und du kannst dir alle Unit Tests sparen!"

    Zitat von Schnuffel

    Solange es kein Pflichtenheft gibt, ist die Spielwiese eines Code Editors doch unser Königreich. ^^

    ...und genau deswegen werden immer neue Programmiersprachen und esoterische Paradigmen entwickelt...weil kaum einer seinen Job "richtig" macht....weil es sowohl an der Qualifikation hängt, als auch an den Vorgaben:

    Zitat von water

    Sind die Vorgaben (Lastenheft, Design etc.) schlecht, dann kann der Code auch nur schlecht sein

    Und von "richtig machen Wollen" ist hier nicht mal die Rede!

  • Unit Testing in Autoit

    • Andy
    • 17. Februar 2024 um 09:36
    Zitat von BananaJoe

    Ein "aus dem Kopf übersetztes" Zitat: Nicht getesteter Code ist per Definition fehlerhaft.

    Und was hat das mit Unit Tests zu tun?

    Wenn ich eine Funktion schreibe, dann hat die einen Sinn und Zweck! "Getestet" wird (bei mir zumindest) während der Entwicklung. Und zwar so, dass (für mich) alle denkbaren Zustände behandelt werden. Was nicht heißt, dass es nicht irgendwann während des späteren Einsatzes der Funktion doch zu Fehlern kommen kann! Dann wird genau dieser "Fehler" behoben und weiter gehts....

    Unit Tests helfen da KEIN STÜCK! Denn Unit Tests sind nicht dafür da, die absolute Fehlerfreiheit zu garantieren! Die Unit Tests sind dazu da, die vorgegebenen Fälle und Rahmenbedingungen einer Funktion auf deren richtige Ausführung abzuklopfen, auch wenn die Funktion irgendwann verändert oder erweitert wird.

    Und da liegt der Hase im Pfeffer! Wer diese Vorgaben und Rahmenbedingungen einer Funktion oder eines Programms nie oder nur selten verändert, der braucht auch keine Unit Tests.

    Jeder von uns hat schon einmal eine Funktion verändert oder "verbessert" und nach dem Hieb auf F5 eine Fehlermeldung bekommen! Man vergisst, gerade bei umfangreichen Funktionen, welche Querverweise und Abhängigkeiten innerhalb des Codes bestehen. Der Unit Test findet den "Fehler" nicht, da die vom Programmautor vorgegebenen Ergebnisse

    alle "richtig" sind. Bis auf die Fälle, die der Programmautor nicht bedacht hat....:/. Naja, dann wird eben für genau diesen Fall der Unit Test erweitert bzw. angepasst.

    Für mich machen Unit Tests Sinn in professionellem Umfeld, wo ein hauptberuflicher Unit Test Programmierer die Arbeit seiner Kollegen veriifizieren muss. Dabei wird "natürlich" jeder denkbare mögliche und unmögliche "Fehler" versucht abzufangen. Wird der Code dann geändert und die Testumgebung meldet "Funktion arbeitet wie vorgegeben", dann ist die Chance hoch, dass das Programm auch nach diversen Änderungen "fehlerfrei" funktioniert....so lange bis ein "unerwarteter" Fehler auftritt....

    Ich bin ziemlich sicher dass "professionelle" Unit Tester das obere Ende der Fahnenstange in der Programmiererzunft sind. Denn dass eine Funktion innerhalb ihrer Vorgaben ein "richtiges" Ergebnis hervorbringt ist dessen Aufgabe! Spannend wird es erst dann, wenn durch unvorhersehbare und vom Programmierer nicht beachtete Zustände ein "Fehler" gefunden werden muss.

    Ich muss immer schon grinsen, wenn ein Kollege mich mit den Worten anruft "...hast du mal 10 Minuten Zeit, mein Programm läuft nicht und ich weiß nicht warum...". Debuggen von anderer Leute Code ist eine meiner Lieblingsbeschäftigungen. :Glaskugel:Das schult die Analytik und die fördert die Kommunikation. Gleichzeitig unterstützt es die eigene Kreativität, weil man sieht, wie andere Leute ein Problem programmtechnisch angehen! Unit Tests killen meinen Spass:rofl:

  • Richtig debuggen?

    • Andy
    • 17. Februar 2024 um 09:02

    Naja.....Brille nicht aufgehabt?!

    Zitat von OhnePlan

    warning: $PIC_INFO: declared, but not used in func.

    Zitat von OhnePlan

    Local $__PIC_INFO =

    Finde den Fehler im linken Bild.....Wenn man schon Variablennamen von einem "Debuggingtool" angezeigt bekommt, dann sollte man auch nach deren genauen (!) Schreibweise suchen!

    Weiterhin ist übrigens die Stelle im Script auf die dieser Hinweis zeigt, genauestens beschrieben!

    Zitat von OhnePlan

    "P:\AutoIT\LIB\Copyright.au3"(73,73)

    In der Klammer steht die Zeilennummer und die Spalte. Ein Doppelklick auf die in der Konsole angegebene(n) Fehlerzeile(n) führt dazu, dass in Scite an die betreffende Stelle im Script gesprunge wird.

    Debuggen ist in AutoIt/Scite gegenüber selbst einfachen anderen Sprachen generell mühsam. Scite ist ein Editor und keine IDE!

    Mit den vorhandenen Debuggingtools im "Extras"-Menü kommt man aber schon ziemlich weit.

    Ich persönlich bin kein Freund von solchen Zeilen: #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

    Die angezeigten "Fehler" sind zu 99% keine und während der Entwicklung von Programmen behindern sie mich und stören meinen "Flow" und die Kreativität. Imho sind diese Zeilen dazu geeignet, nach (!) der Erstellung eines lauffähigen Script dieses "schön" zu machen. Was mich als Privatanwender (auch wenn ich Scripte sehr oft im beruflichen Leben verwende) einen Scheiss interessiert! Form follows function....

    Für diese Gimmicks habe ich definitiv keine Zeit.....

    Wer jemals auf Programmierwettbewerben war oder online mal zugeschaut hat, der versteht was ich meine. KEINER dieser Jungs und Mädels hat jemals, egal in welcher Programmiersprache gehackt wurde, diese "Tools" im Einsatz. Wenn du 5 Minuten Zeit hast einen Algorithmus zu verzapfen, dann braucht niemand 20 Zeilen "Hinweise" zu programmtechnisch völlig irrelevanten "Vorgaben".


    Was nicht bedeutet, dass ich nicht ein absoluter Freund von "schönem" Code bin! Ich bewundere und respektiere Leute, die sich neben der Funktion eines Programms auch noch um dessen "äußere Form" kümmern! Wobei ich ziemlich sicher bin, dass das "aufhübschen" länger braucht als die eigentliche Programm/Funktionserstellung.....

  • ASCII-Art

    • Andy
    • 4. Februar 2024 um 11:32
    Zitat von Alina

    Danach hatten wir ein Schreibprogramm das unter MS-Dos lief.

    Meinst du WordStar? Das war imho damals genauso krank wie heute etliche Editoren. Wenn man nicht täglich mehrere Stunden damit "gearbeitet" hat, war es unmöglich, sich sämtliche der kryptischen Tastaturbefehle für die Steuerung zu merken.

    Da lobte ich mir mein WordPerfect, dazu gab es schicke Tastaturschablonen, die man sich über die Tastatur legen konnte, auf diesen Schablonen waren dann die am häufigsten verwendeten Befehle.

  • ASCII-Art

    • Andy
    • 3. Februar 2024 um 23:48
    Zitat von Schnuffel

    ich glaube damals gab es 300 kbit oder so als Geschwindigkeit. /oder waren 300 bit :rofl: )

    hehe, ja, das waren tatsächlich 300 bps , also BIT PER SECOND....über den dicken Daumen 35 BYTES pro Sekunde, "netto" gingen da imho eher 30 Bytes pro Sekunde durch eher 25...

    Mit C64 hatte ich nichts am Hut, ein Freund hatte einen Atari XL, den hatten wir in Maschinensprache programmiert, damals (genau wie heute) 1000x schneller als das Basic im ROM

    Mein erster PC war ein (gebrauchter) IBM XT, INTEL 8088 mit 4,77 Mhz....ich glaube ich könnte 10000 Jahre alt werden, diese Zahlen würde ich nie vergessen^^. Das Ding hatte eine 10 MB (ja, MB kein GB^^) Festplatte, 5 1/4 Zoll und ca. 3 Kilo schwer:rofl: . Ich war dann ca. 2 Monate lang jobben neben der Schule (jeden Tag, auch Samstags morgens von 4 bis 7 Brötchen ausfahren mit dem Fahrrad) um mir einen 8087 KOPROZESSOR zu kaufen, der neben den Prozessor eingesteckt wurde um die (sonst vom Prozessor langsam emulierten) mathematischen Befehle (sin, cos, log, tan uswusf) auszuführen, welche im internen Stack und kleinen Speicher des Koprozessors ausgeführt werden konnten, parallel natürlich zum Hauptprozessor!!! Programmiert werden konnte der Kopro nur in einem selbstgeschriebenen Assembler, jedenfalls von mir, ich hatte kein Geld für einen Compiler:party:

    Damit wurde das "Apfelmännchen" (Mandelbrotmenge, ein Fraktal) zig mal schneller berechnet, ich weiß noch das das komplett im Stack des Koprozessors lief! Ausgabe der "Grafik" natürlich EGA 640x350 in 4 Farben oder 320x200 Pixel in 256 Farben. Wenn ich mich richtig erinnere, wurde das Apfelmännchen in unter 1 Sekunde auf den Bildschirm gezaubert, je tiefer man dann eingetaucht ist, wurde es aber auch recht zäh...jedenfalls viel viel schneller als die meisten damals erhältlichen Programme, von denen die schnellsten auch mal einige Minuten für die Handvoll Pixel brauchten....

    Mit diesem Rechner hatte ich auch die ersten "richtigen" Programme geschrieben, schweineschnelle Zuschnittoptimierungen für Stäbe und Platten für Schreinereien und Metallbauunternehmen. Bei IBM gab es damals auch einen Wettbewerb für das "Travelling Salesman Problem", da war ich (weltweit) mit meinem (handoptimierten) Assemblercode unter den TOP 10. Blöd wie ich war, habe ich nichts daraus gemacht.....wäre ich damals bei IBM eingestiegen, wer weiß wo ich heute wäre:part:. Aber der Verein war mir zu versnobt und zu selbstgefällig.....

    286er hatte ich übersprungen, mein nächster Rechner war dann imho ein (wieder gebrauchter) IBM PS/2 386SX @16Mhz (55SX) mit Microchannel (MCA)....DAS System fand ich derartig endgeil!!! Wäre IBM mit ihrer Lizensierungspolitik für Microchannelkarten nicht so dermaßen bescheuert gewesen, es gäbe heute definitiv kein Microsoft (mehr) und Apple erst garnicht....aber das war weder der erste noch der letzte Marketingflop von IBM...die Blödmänner dort haben sich lieber die Millionen in die Tasche gesteckt als die Milliarden, DIE haben dann andere verdient...mit definitiv schlechterer Hardware und auch Software:whistling:. Juhuu, keine 5 1/4 Zoll Disketten mehr, jetzt "richtige" 3 1/2 Zoll^^, und eine ESDI Festplatte, wie groß die war habe ich vergessen, aber es gab "natürlich" noch einen Steckplatz für einen (gebrauchten) 387SX Koprozessor....DAMIT war der "low-end" PC dann in der Lage (entsprechend programmiert) auch mit den "dicken" 386ern und auch den 486sx und dx mitzuhalten!!

    Ich war ein Fan von OS/2, aber keiner der Leute in meiner Umgebung hatte (in Ermangelung einer "orginal" IBM-Maschine) auch dieses Betriebssystem....also musste ich zwangsweise zu Windows oder GEM wechseln...DOS gabs natürlich immer noch....als unglaublich teure, professionelle "Office" Software gab es damals Framework von Ashton Tate, was mir ein Bekannter für ein paar Mark mit Lizenz und Dongle (gebraucht) "besorgt" hatte. Aber wie gesagt, die "IBM-Kompatibel"-Jünger raubkopierten wie die blöden Diskettenweise Software-Müll und konnten/wollten daher auch keine "professionelle" Software nutzen bzw. bezahlen. Billy Gates lacht sich noch heute über diese Leute tot, die Windows raubkopierten und damit der Anfang von all dem Elend seitdem waren!!!! Microsoft Office war zwar (im direkten Vergleich) Welten "schlechter" aber trotz der horrenden Preise immer noch billiger wie "richtige" Software....und lies sich raubkopieren, da nicht verdongelt!!


    Meine Maschinenbau Diplomarbeit schrieb ich 1992 mit WordPerfect, einem der ersten WYSIWYG-Textverarbeitungen...die "Zeichnungen" hatte ich (kein Scheiss!!) in einer Art "Paint" erstellt, ich weiß nicht mehr wie dieses "Malprogramm" hieß, aber ich hatte kein 3D-CAD und ich wollte doch "schöne" 3D-Zeichnungen haben:rofl:. In der Uni gab es damals ME30 von HP, das war ein "richtiges" 2D/3D-CAD-Programm, der Einzelarbeitsplatz mit einem Monochrom 21 Zoll Monitor, Zeichentablet und Rechner mit Software ging für geschmeidige 30.000DM (ja, dreißigtausend) über den Tisch. PLUS Lizenzgebühren....


    Anekdote am Rande:

    Um eine "Zeichnung" in ME30 anzuzeigen, hat man diese "geladen" und ist dann erst mal in die Kaffeeteria....die Grafikkarte war derart langsam, dass man teilweise den Aufbau von einzelnen Linien Pixel für Pixel mitverfolgen konnte. Ich und ein anderer programmierbegeisterter Kommilitone hatten also den Grafiktreiber der Hercules-Grafikkarte analysiert und haarsträubende Programmiertechniken festgestellt, Analyse natürlich in Ermangelung des Sourccodes per Debugger in Maschinencode^^. Der Treiber war ein C-Compilat, der Compiler hatte wohl auch einiges mit der Langsamkeit zu tun, aber die Algorithmen für die Darstellung von Linien- und Bögen waren einfach unter aller Sau.

    Wir hatten also den Grafik-Treiber "gehackt" und einige Algorithmen durch (handoptimierten) Assemblercode ersetzt, das HP-UX hat das nicht leicht gemacht8). Damit reduzierte sich die Wartezeit des Zeichenvorgangs auf ca. 1/10, also 10x schneller. Das war natürlich alles "geheim" und strikt verboten, nur ein Prof. fand das wohl nicht so schlimm und ließ uns gewähren....

    Nach einigen Wochen kam dann HP ins Haus mit einigen Verkäufern und präsentierte die "neue" Version ihrer CAD-Software (und auch Hardware!) . Ende vom Lied und Verkaufsargument Nummer eins war die nun "wesentlich" schnellere Anzeige beim Zeichnen, "fast in Echtzeit"!! Der Preis war natürlich exorbitant, 6 Arbeitsplätze sollten ausgestattet werden. Die Professoren waren beeindruckt und der HP-Verkäufer hatte sich schon über die ca. 20000-30000DM Provision gefreut, da kam unser Prof und lud die Referenzzeichnung mit "unserem" gehackten alten System. Genau so schnell wie das "neue" und ohne exorbitante Kosten! Unser Prof schlug dann vor, noch einige Zeit das "alte, genau so schnelle System zu nutzen, der Dekan willigte natürlich ein und die HP-Delegation ist stinkwütend wieder abgedampft ohne einen einzigen Rechner verkauft zu haben. Ich weiß bis heute nicht, wie HP rausbekommen hat wer für diesen "Hack" verantwortlich war, jedenfalls fuhr ich mit Freunden kurz darauf zur CEBIT nach Hannover, wir hatten Karten vorbestellt, natürlich mit unseren Namen, und als wir in die Nähe des HP-Standes kamen wurden wir plötzlich von etlichen Securityleuten aus der Halle und vom CEBIT-Gelände verwiesen.....Da sind dann Worte wie "Urheberrechtsmißbrauch" und "Staatsanwaltschaft" gefallen, DAS war dann nicht mehr lustig denn bei Urheberrechtsverletzungen sieht § 106 UrhG eine Freiheitsstrafe von bis zu drei Jahren oder eine vergleichbare Geldstrafe vor=O. Je nach Richter und Ankläger nach oben keine Grenze....

    Mir ging der Arsch ziemlich auf Grundeis, aber unser Prof hat das dann auf seine Kappe genommen und mit HP gedealt, dass die "neuen" CAD-Arbeitsplätze "selbstverständlich" wieder von HP bereitgestellt werden dürfen, obwohl es doch auch Wettbewerber gäbe...AutoCAD lief damals auf jedem "kompatiblen" PC und war preiswerter ... der HP-Verkäufer bekam seine Provision ein Jahr später, ich und mein Kumpel blieben auf freiem Fuß und alle waren happy. Seitdem "hacke" ich nicht mehr anderer Leute Rechner und erst recht keine "professionellen" Systeme.8o:saint:

  • ASCII-Art

    • Andy
    • 22. Januar 2024 um 20:46

    Hi,

    "früher"....also GAAAANZ früher...als man sich über 1200bps-Modems per analoger Telefonleitung auf "öffentliche", sog. Boxen aufschalten konnte (so man denn eine freie Leitung dort erwischte) und sich über Textnachrichten auf sog. "Boards" Mitteilungen schickte, waren die Startseiten NATÜRLICH in ASCII-Art.

    Erstens gab es noch reichlich monochrome Monitore, zweitens hatte niemand Zeit, Stundenlang darauf zu warten dass sich ein aus Pixeln bestehendes BILD sich durch die Telefonleitung quetschte. Die Telefonrechnung war die natürliche Bremse für allzu exzessive Nutzung dieser Technologie^^

    Ich war damals u.a. im MausNet unterwegs, aber auch auf anderen Boxen aktiv. In der c´t wurden damals (kein Witz) ganze Seiten mit den Einwahl-Telefonnummern diverser Boxen gedruckt. Eine gut gemachte ASCII-Art-Startseite mit einer schicken (Text-) Menüführung war nötig, um die "Professionalität" dieser Anbieter zu zeigen.

    Bulletin board system - Wikipedia
    en.wikipedia.org


    Und dann gab es noch Textadventures :party:. Teilweise echt klasse gemachte Adventures in Textform, später auch in ASCII-Art. Da ist man dann durch dunkle Dungeons geirrt, wurde von Fledermäusen gejagt und hat gegen Drachen gekämpft. Ohne ein einziges bewegtes Bild auf dem Rechner, nur Text und Ascii-Art.

    Liste von Textadventures – Wikipedia

    Auf diese Liste hatte ich es nicht geschafft, aber ich habe auch mal eines für DR-DOS in Basic geschrieben und bestimmt 20-30 Kopien davon auf 5 1/4Zoll-Diskette in der Schule "getauscht".8o8o

    ASCII-Art war damals eher eine Fleißarbeit, Probleme bei der Darstellung gab es kaum, Schriftarten gab es nur als Monospace aka https://de.wikipedia.org/wiki/Nichtproportionale_Schriftart


    Bissl was monochromes habe ich auch noch gefunden: https://www.asciiart.eu

  • revert im laufenden script.

    • Andy
    • 16. Januar 2024 um 18:55

    Hi,

    Zeig mal dein Script, dann weiß man auch um was es geht.

  • QTWidget fernsteuern ...

    • Andy
    • 10. Januar 2024 um 18:49

    Hi!

    Teste mal bitte, ob die Anwendung ggf. über QTabWidget gesteuert wird, dann kannst du die Steuerung und Auswahl von Controls über die Tastatur vornehmen!

    Wenn über QtabWidget erstellt, ist das machbar!

    Ich gehe davon aus, dass du die folgenden Links aus der Suche abgeklappert und die Scripte dort getestet hast....

    Let Me Google That
    letmegooglethat.com
  • Weihnachtsgrüße

    • Andy
    • 24. Dezember 2023 um 13:10

    Und wie in jedem Jahr :saint:

    Code
    ;struct erstellen
    $struct =dllstructcreate("int;float[5];dword")
    ;struct mit Daten füllen
    dllstructsetdata($struct,1,123456);int
    dllstructsetdata($struct,2,4.52301424904732e+24,1);float
    dllstructsetdata($struct,2,6.34941479652706e+22,2);float
    dllstructsetdata($struct,2,2.74865539637211e+20,3);float
    dllstructsetdata($struct,2,7.21364385566043e+22,4);float
    dllstructsetdata($struct,2,1.19923122576918e-41,5);float
    dllstructsetdata($struct,3,0xDEADBEEF);dword
    
    ;ab offset 4 die Daten wieder lesen
    $struct2=dllstructcreate("char[24]",dllstructgetptr($struct)+4)
    msgbox(0,":o)",dllstructgetdata($struct2,1))
    Alles anzeigen
  • ARGB für GDI+

    • Andy
    • 8. Dezember 2023 um 19:11
    Zitat von Mars

    Mysteriös.

    Alles gut! Willkommen im Club!:theke:

    Zitat von BigRox

    Ich dachte gar nicht, dass es so einfach geht, aber manchmal hat man eben einfach eine Denkblockade.

    Genau dafür ist das Forum da....:rock:

  • ARGB für GDI+

    • Andy
    • 7. Dezember 2023 um 20:18

    Hi,

    Zitat von Mars

    kannst du also "einfach" 0xFF000000 addieren

    so gehts!


    OT-Mode ON:

    Zitat von Mars

    oder (was sicherer ist, da es das Überlaufen in benachbarte Bytes verhindert, falls einzelne Werte größer als 255 sind. Das sollte bei hardgecodeten Werten nicht passieren, wenn die Werte aber berechnet werden und ein Clamp fehlt macht das beim einfachen Addieren die Farben kaputt)

    Holla die Waldfee!;(:/

    Unter uns Klosterschwestern...egal welches Zeugs du dir da eingeworfen hast, LASS ES!8o

    Auf ein Beispiel was du wirklich meinst, wäre ich ECHT gespannt!:love:...und ich bin ziemlich sicher...DU AUCH!:rofl:

    Btw. schickes Script mit den "gemalten Dreiecken":thumbup:

    OT-Mode OFF

  • Sehr große Zahlen addieren führt zum falschen Ergebnis

    • Andy
    • 16. November 2023 um 20:11
    Zitat von AspirinJunkie

    Aber wird ja wie gesagt eh nicht umgesetzt.

    Na dann....

    Zitat von AspirinJunkie

    Die Alternative wäre hingegen in der Doku zu vermerken, dass die Hexnotation nicht für Zahlenwerte genommen wird sondern nur für Bitfolgen.

    Ich hoffe, Tweaky liest hier mit. Dann würde wenigstens in der deutschen Hilfe ein Hinweis stehen! Ggf. mit einer entsprechenden "Umrechnungsfunktion" welche korrekte (erwartbare) Ergebnisse zurrückgibt....

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™