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

  • Defrag - Programm mit AutoIT schreiben...

    • Andy
    • 14. Januar 2012 um 08:44

    Hi,
    da man mit AutoIt ohne weiteres Daten Sektorweise (LINK1 LINK2) lesen kann, ist ein "Defragmentierer" kein großes Thema.
    Das Problem der Geschwindigkeit wird dich aber über kurz oder lang einholen bzw überholen^^.

    Mit Arrays wirst du nicht weit kommen, eine Alternative wären Listen, die AspirinJunkie hier beschrieben hat.

    Alles in allem eine feine Aufgabe :thumbup: , ich würde mich über ein funktionierendes Script (dass bis Weihnachten in diesem Jahr eine 750Gig-Platte nicht defragmentieren dürfte^^) freuen!

  • Bilderkennung

    • Andy
    • 9. Januar 2012 um 22:03

    Hi,
    AdlibEnable() ist die "alte" Funktion, die aktuelle heisst

    [autoit]

    AdlibRegister()

    [/autoit]
    Zitat

    Und muss die Funktion die man AddlibRegister übergibt im gleichen Skript definiert sein, oder kann man auch eine externe Funktion aus einem anderen Skript, welches aber mit include eingebunden ist, verwenden?

    Ja, die Funktion sollte im Script (oder in einer der Includes) sein.
    Die Zeit sollte nicht zu kurz gewählt werden, um das Hauptscript nicht abzuwürgen bzw. auszubremsen.
    Denn den Timern ist es egal, ob die Funktion , die von AdlibRegister() aufgerufen wird, schon regulär beendet wurde! Im Zweifelsfall ruft Adlibregister() die Funktion sogar wieder neu auf, obwohl sie noch nicht beendet wurde....

  • Bilderkennung

    • Andy
    • 8. Januar 2012 um 18:48

    Hi,
    Adlibregister ruft eine Funktion alle x Millisekunden auf

    Beispiel:
    Du erstellst per PtB eine Datei "buttontest.bmp" mit dem Inhalt deines Buttons.
    Achtung, wenn schon mehrere dieser Dateinahmen bestehen, erstellt PtB automatisch eine Folge, also z.B. "buttontest_0001.bmp", dann ggf anpassen/umbenennen anderen Namen wählen.

    Beispielscript starten.

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <GDIPlusConstants.au3>
    #include <ScreenCapture.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>
    ;#include <prospeed30.au3>
    #include <WindowsConstants.au3>
    #include-once

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

    ;**********example***************
    _GDIPlus_Startup()
    If FileExists("prospeed.dll") Then $prospeed_dll = DllOpen("prospeed.dll")
    AdlibRegister("_findbutton", 100) ;alle 100ms Funktion aufrufen

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

    While 1 ;hauptprogramm
    Sleep(100)
    WEnd

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

    Func _findbutton()
    Local $coord = _PtB_ClickBMP("buttontest.bmp", "FULLSCREEN");bild im kompletten screen suchen
    If IsArray($coord) Then
    MsgBox(0, "_findbutton()", "Button gefunden an x=" & $coord[0] & " y=" & $coord[1], 3)
    Return $coord
    EndIf
    EndFunc ;==>_findbutton
    ;***********example end**************

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

    ;funktionen im zipfile

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


    Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Wenn der Button auf dem Bildschirm sichtbar ist, wird er gefunden, der Mauszeiger wird zum Button bewegt und eine Messagebox mit den Koordinaten des Buttons erscheint. Diese Msgbox bleibt 3 Sekunden sichtbar, dann wird die Suche erneut durchgeführt, so lange, bis das Script beendet wird. In der Hauptschleife while/wend können die Koordinaten dann ausgewertet werden.
    Die Bewegung des Mauszeigers zum gefundenen Button kann man einfach unterbinden, indem das mousemove() auskommentiert wird.

    Dateien

    ptb_clickbmp_DEMO2.zip 6,31 kB – 390 Downloads
  • Bilderkennung

    • Andy
    • 8. Januar 2012 um 18:11

    Hi,
    Adlibregister ruft eine Funktion alle x Millisekunden auf

    Beispiel:
    Du erstellst per PtB eine Datei "buttontest.bmp" mit dem Inhalt deines Buttons.
    Achtung, wenn schon mehrere dieser Dateinahmen bestehen, erstellt PtB automatisch eine Folge, also z.B. "buttontest_0001.bmp", dann ggf anpassen/umbenennen anderen Namen wählen.

    Beispielscript starten.

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <GDIPlusConstants.au3>
    #include <ScreenCapture.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>
    ;#include <prospeed30.au3>
    #include <WindowsConstants.au3>
    #include-once

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

    ;**********example***************
    _GDIPlus_Startup()
    If FileExists("prospeed.dll") Then $prospeed_dll = DllOpen("prospeed.dll")
    AdlibRegister("_findbutton", 100) ;alle 100ms Funktion aufrufen

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

    While 1 ;hauptprogramm
    Sleep(100)
    WEnd

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

    Func _findbutton()
    Local $coord = _PtB_ClickBMP("buttontest.bmp", "FULLSCREEN");bild im kompletten screen suchen
    If IsArray($coord) Then
    MsgBox(0, "_findbutton()", "Button gefunden an x=" & $coord[0] & " y=" & $coord[1], 3)
    Return $coord
    EndIf
    EndFunc ;==>_findbutton
    ;***********example end**************

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _PtB_clickBMP (needs prospeed.dll from http://frabbing.bplaced.net/ for fast search in memory)
    ; Description ...: searches a Bitmap in the full Screen or in a Window and clicks at the found position of the Bitmap
    ; It is recommended to use the PushTheButton-Program (http://www.AutoIt.de) for the creation of the Bitmap
    ; Syntax.........: _PtB_clickBMP($bitmapfile[, $hWin = "FULLSCREEN"[,$sMouseButton="left"[, $iClicks=1 ]]]]])
    ; Parameters ....: $bitmapfile - Name of the Bitmap-File to search for
    ; $hWin - Title/Handle of the window to search in, or "FULLSCREEN", or "" for active window
    ; $MouseButton - The button to click: "left", "right", "middle", "main", "menu", "primary", "secondary".
    ; $iClick - The number of times to click the mouse. Default is 1. 0 is possible^^
    ; Return values .: Success - Array with coordinates of the Mouseclick x=array[0] y=array[1]
    ; - if "FULLSCREEN" then coordinates are absolute screen coordinates
    ; - otherwise relative coords to the active window
    ; Failure - @error is set to 1
    ; Author ........: Andy @ http://www.autoit.de
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    ;
    ;TODO: wenn vertikale scrollbalken im fenster/fullscreen sind, scrollen erlauben und nur scrollbalken auf bewegung checken

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

    ;untersucht, ob Bitmap2 in Bitmap1 enthalten ist
    ;Originalfunc by JunkEW , modified by Andy@ http://www.autoit.de, finds the exact match
    Func _PtB_ClickBMP($bitmapfile, $hWin = "FULLSCREEN", $sMousebutton = "left", $iClicks = 0) ;rückgabe x- und y-position des gefundenen hotspots in einem array [0]und[1]

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

    Dim $aresult[2] ;return array x- and y-coords
    Local $gefunden = 0, $maxanzahlpixel = 50, $exitflag = 0, $check, $pixel, $px, $py, $dx, $dy
    Local $window_height, $window_width, $xy, $pix, $prozent

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

    If $hWin = "" Then $hWin = "[ACTIVE]" ;
    If $hWin = Default Then $hWin = "FULLSCREEN" ;suche im gesamten Bildschirminhalt
    If $sMousebutton = Default Then $sMousebutton = "left"
    If $iClicks = Default Then $iClicks = 1
    Local $opt_1 = Opt("mouseclickdelay") ;sichern der Optionen, werden am ende der Funktion wieder hergestellt
    Local $opt_2 = Opt("mouseclickdowndelay")
    Local $opt_3 = Opt("MouseCoordMode")
    Local $opt_4 = Opt("PixelCoordMode")
    Local $PtBfile = StringTrimRight($bitmapfile, StringLen($bitmapfile) - StringInStr($bitmapfile, ".") + 1) & ".ptb"
    Opt("mouseclickdelay", 1)
    Opt("mouseclickdowndelay", 1)
    ;im ptbfile sind Parameter für das Suchen der Bitmaps abgelegt
    Local $file = FileOpen($PtBfile, 0) ;daten lesen
    If $file = -1 Then ;fehler beim datenlesen, oder ptb-Datei nicht vorhanden
    If FileExists($bitmapfile) Then ;wenn es aber eine Bitmap gibt, dann kann man auch nur mit der
    $Anzahl_bestpixel = 500 ;bitmapsuche suchen
    Else ;wenn es weder Bitmap noch *.ptb-file gibt, fällt die Suche aus^^
    MsgBox(262144 + 1, "Fehler in Funktion _PtB_ClickBMP()", "Keine Bitmap und keine *.ptb-Datei mit Informationen zur Suche gefunden!" & @CRLF & "Bitte benutzen Sie das Programm PushTheButton, um eine Bitmap zu erzeugen!")
    SetError(1, 0, 1)
    Return -1
    EndIf
    Else ;ansonsten daten aus der *.ptb-Datei einlesen
    $check = FileReadLine($file, 1) ;pixelchecksum
    $pixel = FileReadLine($file, 2) ;pixelfarbe in hex RGB
    $Anzahl_bestpixel = Number(FileReadLine($file, 3)) ;niedrigste Anzahl der gesuchten Pixel
    $px = FileReadLine($file, 4) ;x-Versatz des Hotspots innerhalb des pics
    $py = FileReadLine($file, 5) ;y-Versatz des Hotspots innerhalb des pics
    $dx = FileReadLine($file, 6) ;breite in pixel
    $dy = FileReadLine($file, 7) ;hoehe in pixel
    FileClose($PtBfile)
    EndIf
    If $hWin = "FULLSCREEN" Then
    Opt("PixelCoordmode", 1) ; für Fullscreen setzen
    Opt("MouseCoordMode", 1) ;gesamter screen
    ;thx an Funkey
    Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78) ;sm_virtualwidth
    $window_width = $VirtualDesktopWidth[0]
    Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79) ;sm_virtualheight
    $window_height = $VirtualDesktopHeight[0]
    Else
    Opt("PixelCoordmode", 0) ;für lokales Fenster setzen
    Opt("MouseCoordMode", 0) ;aktives Fenster
    $xy = WinGetPos($hWin) ;breite und höhe des Fensters
    $window_width = $xy[2]
    $window_height = $xy[3]
    EndIf

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

    If $Anzahl_bestpixel > $maxanzahlpixel Then ;wenn wenige passende farbige pixel auf dem Bildschirm sind...
    ConsoleWrite("Verfahren mit Bitmapsuche gewählt" & @CRLF) ;dann strings suchen (Bitmap2 in Bitmap1 suchen)
    If FileExists(@ScriptDir & "\ProSpeed.dll") Then
    $aresult = _FindBMP($hWin, $bitmapfile) ;suchen per stringfunktion in der Bitmap
    Else
    $aresult = _FindBMP_slow($hWin, $bitmapfile) ;suchen per stringfunktion in der Bitmap
    EndIf
    If IsArray($aresult) Then $gefunden = 1

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

    Else ;wenn es nur wenige Pixel in der angegebenen Farbe gibt, ist diese Variante mit pixelsearxch schneller
    ConsoleWrite("Verfahren mit Pixelsuche gewählt" & @CRLF)
    Local $x = 0, $y = 0
    While 1
    $pix = PixelSearch($x, $y, $window_width, $window_height, Dec($pixel)) ;pixelfarbe suchen
    If @error Or $exitflag Then ExitLoop ;nicht gefunden oder esc gedrückt, dann pagedown
    ;msgbox(0,"pix gefunden an",$pix[0]&" "&$pix[1])
    While 1
    $x = $pix[0] ;x- und y-koordinaten des gefundenen pixels (hotspot)
    $y = $pix[1]
    ;$prozent = ($y * $window_width + $x) * 100 / $window_width / $window_height
    ;ToolTip(StringFormat("Suche läuft : %.0f%%", $prozent), $window_width / 2, $window_height / 2)
    Local $p1x = $x - $px, $p1y = $y - $py ;umrechnen der hotspotkoordinaten für checksum
    Local $p2x = $p1x + $dx - 1, $p2y = $p1y + $dy - 1
    ; msgbox(0,"pixel mit farbe "&$pixel,$p1x&" "&$p1y&@crlf&$p2x&" "&$p2y&@crlf&PixelChecksum($p1x,$p1y,$p2x,$p2y))
    If PixelChecksum($p1x, $p1y, $p2x, $p2y) = $check Then ;wenn pixelchecksum gleich der gespeicherten pixelchecksum ist, dann gefunden
    $gefunden = 1
    $aresult[0] = $x
    $aresult[1] = $y
    ExitLoop
    EndIf
    $x += 1 ;ein pixel weiter in der zeile
    $pix = PixelSearch($x, $y, $window_width, $y, Dec($pixel)) ;pixel suchen
    If @error Or $exitflag Then ExitLoop ;wenn in der zeile kein pixel mehr, dann raus
    WEnd
    If $gefunden = 1 Then ExitLoop
    $x = 0 ;neue spalte
    $y += 1 ;neue zeile
    WEnd
    EndIf
    $exitflag = 0
    ;ToolTip("")
    If $gefunden = 0 Then ;gesuchte Pixel nicht gefunden
    SetError(1, 0, 1)
    Return -1
    Else ;gefunden
    MouseMove($aresult[0], $aresult[1], 0) ;maus schnellstmöglich zur Position
    For $i = 1 To $iClicks ;anzahl der klicks
    MouseDown($sMousebutton) ;es wird die maustaste betätigt
    MouseUp($sMousebutton)
    Next
    SetError(0, 0, 0)
    Opt("mouseclickdelay", $opt_1)
    Opt("mouseclickdowndelay", $opt_2)
    Opt("MouseCoordMode", $opt_3)
    Opt("PixelCoordMode", $opt_4)
    Return $aresult ;array mit den hotspot-koordinaten zurückgeben
    EndIf
    EndFunc ;==>_PtB_ClickBMP

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

    ;untersucht, ob Bitmap2 in Bitmap1 enthalten ist
    ;Originalfunc by JunkEW , modified by Andy@ http://www.autoit.de, finds the exact match
    ;modified by Andy November,6,2011
    Func _FindBMP($BMP1, $BMP2)
    Dim $BMP1Data = "", $BMP1Width = 0, $BMP1Height = 0, $BMP1LineWidth = 0, $pbitmap1 = 0, $bitmapinfo1
    Dim $BMP2Data = "", $BMP2Width = 0, $BMP2Height = 0, $BMP2LineWidth = 0, $pbitmap2 = 0, $bitmapinfo2
    Dim $koord[2]
    Local $searchFor, $line, $iPos = 1, $imgBytes = 3, $exit
    Local $ptr1, $ptr2, $struct_bmp1, $struct_bmp2, $struct_1, $struct_2
    Local $string_1, $string_2, $prozent, $flag, $a, $b, $xy
    Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78) ;sm_virtualwidth
    Local $DesktopWidth = $VirtualDesktopWidth[0]
    Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79) ;sm_virtualheight
    Local $DesktopHeight = $VirtualDesktopHeight[0]

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

    $ptr1 = _GetImage($BMP1, $BMP1Data, $BMP1Width, $BMP1Height, $BMP1LineWidth, $pbitmap1, $bitmapinfo1) ;holt alle Infos aus der Bitmap (Fullscreen, Fenster oder File)
    $ptr2 = _GetImage($BMP2, $BMP2Data, $BMP2Width, $BMP2Height, $BMP2LineWidth, $pbitmap2, $bitmapinfo2)

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

    If $BMP2Height = 0 Then
    SetError(1, 0, 0)
    Return False
    EndIf

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

    $exit = DllStructGetSize($ptr1) + 1 ;letzte mögliche bildschirm(fenster) position)
    $struct_2 = DllStructCreate("ubyte[" & ($BMP2Width * 3) & "]");erste zeile der 2. bitmap, nach dieser Position wird gin der ersten Bitmap gesucht
    DllStructSetData($struct_2, 1, $BMP2Data)

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

    ;erste Zeile der Bitmap2 in Bitmap1 suchen
    $iPos = FindBytes(DllStructGetPtr($ptr1), 0, DllStructGetSize($ptr1) - DllStructGetSize($struct_2) - (($BMP2Height - 1) * $BMP1LineWidth), DllStructGetPtr($struct_2), DllStructGetSize($struct_2)) + 1
    ;zeilenweises vergleichen der beiden bitmaps, ist bitmap2 in bitmap1 enthalten?
    While 1
    If $iPos <> 0 And $iPos <> $exit Then ;nur, wenn es eine übereinstimmung gibt weitermachen
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iPos = ' & $iPos & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    Local $e = Mod(($iPos - 1), $BMP1LineWidth) ;position innerhalb des Strings
    ;~ If $e / $imgBytes = Int($e / $imgBytes) Then ;prüfen ob ipos am anfang eines farbbits steht, wenn nicht, nächste zeile suchen
    ;~ $prozent = $iPos / 3 * 100 / $BMP1Width / $BMP1Height
    ;~ ToolTip(StringFormat("Suche läuft : %.0f%%", $prozent) & @CRLF & "Zeile " & Int($iPos / $imgBytes / $BMP1Width), $BMP1Width / 2, $BMP1Height / 2)
    $flag = 0
    For $i = 0 To $BMP2Height - 1 ;zeilenweise die Bitmaps vergleichen
    $a = DllStructGetPtr($ptr1) + $iPos - 1 + $i * $BMP1LineWidth ;pointer auf die position in der struct, an der die erste übereinstimmung ist
    $b = DllStructGetPtr($ptr2) + $i * $BMP2LineWidth ;pointer auf die zeile
    If CompareBytes($a, $b, 3 * $BMP2Width, 0) <> 0 Then ;wenn keine Übereinstimmung, dann nächste suchen
    $flag = 1
    ExitLoop
    EndIf
    Next
    If $flag = 0 Then ;alle zeilen haben übereingestimmt, BMP2 ist in BMP1 enthalten! $koord[0] = Mod(($iPos - 1), $BMP1LineWidth) / $imgBytes ;koordinaten auf dem screen
    $koord[0] = Mod(($iPos - 1), $BMP1LineWidth) / $imgBytes ;koordinaten auf dem screen
    $koord[1] = Int(($iPos - 1) / $BMP1LineWidth)
    $BMP1Data = 0 ;strukturen löschen, Speicher freigeben
    $BMP2Data = 0
    $struct_2 = 0
    $ptr1 = 0
    $ptr2 = 0
    _GDIPlus_BitmapUnlockBits($pbitmap1, $bitmapinfo1)
    _GDIPlus_BitmapUnlockBits($pbitmap2, $bitmapinfo2)
    _GDIPlus_ImageDispose($pbitmap1) ;Bitmaps löschen
    _GDIPlus_ImageDispose($pbitmap2)
    Return $koord
    EndIf

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

    $iPos = FindBytes(DllStructGetPtr($ptr1), $iPos + $imgBytes, DllStructGetSize($ptr1) - DllStructGetSize($struct_bmp2) - (($BMP2Height - 1) * $BMP1LineWidth) - $iPos, DllStructGetPtr($struct_2), DllStructGetSize($struct_2)) + 1
    If $iPos = 0 Or $iPos = $exit Then ExitLoop ;nicht gefunden
    ;~ Else ;ipos ist innerhalb eines farbbits und nicht am anfang
    ;~ $iPos = FindBytes(DllStructGetPtr($ptr1), $iPos + 1, DllStructGetSize($ptr1) - DllStructGetSize($struct_bmp2) - (($BMP2Height - 1) * $BMP1LineWidth) - $iPos, DllStructGetPtr($struct_2), DllStructGetSize($struct_2)) + 1
    ;~ If $iPos = 0 Or $iPos = $exit Then ExitLoop
    ;~ EndIf
    Else
    ExitLoop
    EndIf
    WEnd
    $BMP1Data = 0 ;strukturen löschen, Speicher freigeben
    $BMP2Data = 0
    $struct_2 = 0
    $ptr1 = 0
    $ptr2 = 0
    _GDIPlus_BitmapUnlockBits($pbitmap1, $bitmapinfo1)
    _GDIPlus_BitmapUnlockBits($pbitmap2, $bitmapinfo2)
    _GDIPlus_ImageDispose($pbitmap1) ;Bitmaps löschen
    _GDIPlus_ImageDispose($pbitmap2)
    SetError(1, 0, 1)
    Return 0 ;
    EndFunc ;==>_FindBMP

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

    ;aus einer Datei oder einem Screenshot die Pixeldaten im BGR-Format in einen String schreiben
    ;Originalfunc by JunkEW , modified by Andy@ http://www.autoit.de, gets the Bitmapdata as BGR-String
    Func _GetImage($bmpfile, ByRef $BMPDataStart, ByRef $Width, ByRef $Height, ByRef $Stride, ByRef $pBitmap, ByRef $BitmapData)

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

    Local $Scan0, $hbScreen, $handle, $imgBytes = 3, $pixeldata, $pixeldata2, $xy
    Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78) ;sm_virtualwidth
    Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79) ;sm_virtualheight

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

    ; Load the bitmap to search in
    If StringUpper($bmpfile) = "FULLSCREEN" Then
    $hbScreen = _ScreenCapture_Capture("", 0, 0, $VirtualDesktopWidth[0], $VirtualDesktopHeight[0], False)
    If @error Then MsgBox(0, "", "Fehler Screencapture FULLSCREEN")
    $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap
    If @error Then MsgBox(0, "", "Fehler Bitmapcreate_FromHBITMAP Screen")
    Else
    ;try to get a handle
    $handle = WinGetHandle($bmpfile)
    If @error Then
    ;Assume its an unknown handle so correct filename should be given
    $hbScreen = _GDIPlus_BitmapCreateFromFile($bmpfile)
    $pBitmap = $hbScreen
    If @error Then MsgBox(0, "", "Fehler BitmapCreateFromFile")
    Else ;aktuelles fenster
    $xy = WinGetPos($bmpfile)
    $hbScreen = _ScreenCapture_CaptureWnd("", $handle, 0, 0, $xy[2], $xy[3], False)
    If @error Then MsgBox(0, "", "Fehler Screencapturewnd")
    $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap
    If @error Then MsgBox(0, "", "Fehler BitmapCreateFromHBITMAP File")
    EndIf
    EndIf

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

    ;_GDIPlus_BitmapLockBits gibt $tagGDIPBITMAPDATA-Struktur zurück
    $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB)
    If @error Then MsgBox(0, "", "Error locking region " & @error)
    $Stride = DllStructGetData($BitmapData, "Stride") ;Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
    $Width = DllStructGetData($BitmapData, "Width") ;Image width - Number of pixels in one scan line of the bitmap.
    $Height = DllStructGetData($BitmapData, "Height") ;Image height - Number of scan lines in the bitmap.
    ;$pixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap
    $Scan0 = DllStructGetData($BitmapData, "Scan0") ;Scan0 - Pointer to the first (index 0) scan line of the bitmap.
    $pixeldata = DllStructCreate("byte[" & (Abs($Stride) * ($Height)) & "]", $Scan0)
    $BMPDataStart = DllStructGetData($pixeldata, 1) ;string im Struct-format, d.h. Byte+nulByte, in dem die pixeldaten im BGR-Format stehen
    ; _GDIPlus_BitmapUnlockBits($pbitmap, $BitmapData)
    ;_GDIPlus_ImageDispose($pBitmap) zerstört die pixeldatastruct, daher erst später!!!
    _WinAPI_DeleteObject($hbScreen)
    Return $pixeldata
    EndFunc ;==>_GetImage

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

    Func _findbytes($string_1, $string_2, $startpos) ;string2 im string1 finden, erst ab sehr grossen strings schneller als stringinstr()
    Local $struct_1 = DllStructCreate("ubyte[" & (StringLen($string_1) + StringLen($string_2)) & "]")
    Local $struct_2 = DllStructCreate("ubyte[" & StringLen($string_2) & "]")
    DllStructSetData($struct_1, 1, $string_1 & $string_2)
    DllStructSetData($struct_2, 1, $string_2)
    Local $t = TimerInit()
    Local $pos = FindBytes(DllStructGetPtr($struct_1), $startpos, DllStructGetSize($struct_1), DllStructGetPtr($struct_2), DllStructGetSize($struct_2)) + 1
    Local $findbytes = TimerDiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $findbytes = ' & $findbytes & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ; MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$pos' & @LF & @LF & 'Return:' & @LF & $pos) ;### Debug MSGBOX
    $struct_1 = 0
    $struct_2 = 0

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

    If $pos = -1 Or $pos = StringLen($string_1) + 1 Then Return 0
    Return $pos
    EndFunc ;==>_findbytes

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

    Func CompareBytes($S_MemoryPointer1, $S_MemoryPointer2, $S_ByteSize, $S_Tolerance)
    Local $C_Compare = DllCall($prospeed_dll, "long", "CompareBytes", _
    "long", $S_MemoryPointer1, _
    "long", $S_MemoryPointer2, _
    "long", $S_ByteSize, _
    "long", $S_Tolerance)
    Return $C_Compare[0]
    EndFunc ;==>CompareBytes

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

    Func FindBytes($b, $O, $a, $S, $L)
    Local $S_FindBytes = DllCall($prospeed_dll, "long", "FindBytes", _
    "long", $b, _
    "long", $O, _
    "long", $a, _
    "long", $S, _
    "long", $L)
    Return $S_FindBytes[0]
    EndFunc ;==>FindBytes

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

    Func _FindBMP_slow($BMP1, $BMP2)
    Dim $BMP1Data = "", $BMP1Width = 0, $BMP1Height = 0, $BMP1LineWidth = 0, $pbitmap1 = 0, $bitmapinfo1
    Dim $BMP2Data = "", $BMP2Width = 0, $BMP2Height = 0, $BMP2LineWidth = 0, $pbitmap2 = 0, $bitmapinfo2
    Dim $koord[2]
    Local $searchFor, $line, $iPos = 1, $imgBytes = 3, $prozent, $ptr1, $ptr2
    Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78) ;sm_virtualwidth
    Local $DesktopWidth = $VirtualDesktopWidth[0]
    Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79) ;sm_virtualheight
    Local $DesktopHeight = $VirtualDesktopHeight[0]

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

    ; Load the bitmap to search in
    $ptr1 = _GetImage($BMP1, $BMP1Data, $BMP1Width, $BMP1Height, $BMP1LineWidth, $pbitmap1, $bitmapinfo1)
    $BMP1Data = BinaryToString($BMP1Data)
    $ptr2 = _GetImage($BMP2, $BMP2Data, $BMP2Width, $BMP2Height, $BMP2LineWidth, $pbitmap2, $bitmapinfo2)
    $BMP2Data = BinaryToString($BMP2Data)
    If $BMP2Height = 0 Then
    SetError(1, 0, 0)
    Return False
    EndIf
    Local $searchFor1 = StringMid($BMP2Data, 1, ($BMP2Width * $imgBytes)) ;1. pixel-zeile in der bitmap2 (string)
    $iPos = StringInStr($BMP1Data, $searchFor1, 2, 1) ;1. fundstelle des strings in Bitmap2
    ;zeilenweises vergleichen der beiden bitmaps, ist bitmap2 in bitmap1 enthalten?
    While 1
    Local $flag = 0
    If $iPos <> 0 Then
    If ($iPos - 1) / $imgBytes = Int(($iPos - 1) / $imgBytes) Then ;;prüfen ob ipos am anfang eines farbbits steht
    $prozent = $iPos / 3 * 100 / $DesktopWidth / $DesktopHeight
    ToolTip(StringFormat("Suche läuft : %.0f%%", $prozent) & @CRLF & "Zeile " & Int($iPos / $imgBytes / $DesktopWidth), $DesktopWidth / 2, $DesktopHeight / 2)
    For $S = 2 To $BMP2Height ;zeilenweise das suchbild mit dem screen vergleichen
    $searchFor = StringMid($BMP2Data, 1 + (($S - 1) * $BMP2LineWidth), $BMP2Width * $imgBytes) ; s-te zeile aus dem ausschnitt
    $line = StringMid($BMP1Data, $iPos + (($S - 1) * $BMP1LineWidth), $BMP2Width * $imgBytes) ;zeile "unter" der gefundenen zeile im screen
    If $searchFor <> $line Then ;zeilen nicht gleich,
    $flag = 1
    ExitLoop ;exit for/next
    EndIf
    Next
    If $flag = 0 Then ;alle zeilen haben übereingestimmt, BMP2 ist in BMP1 enthalten! $koord[0] = Mod(($iPos - 1), $BMP1LineWidth) / $imgBytes ;koordinaten auf dem screen
    $koord[0] = Mod(($iPos - 1), $BMP1LineWidth) / $imgBytes ;koordinaten auf dem screen
    $koord[1] = Int(($iPos - 1) / $BMP1LineWidth)
    $BMP1Data = 0 ;strukturen löschen, Speicher freigeben
    $BMP2Data = 0
    $ptr1 = 0
    $ptr2 = 0
    _GDIPlus_BitmapUnlockBits($pbitmap1, $bitmapinfo1)
    _GDIPlus_BitmapUnlockBits($pbitmap2, $bitmapinfo2)
    _GDIPlus_ImageDispose($pbitmap1) ;Bitmaps löschen
    _GDIPlus_ImageDispose($pbitmap2)
    ToolTip("")
    Return $koord
    EndIf
    $iPos = StringInStr($BMP1Data, $searchFor1, 2, 1, $iPos + $imgBytes)
    If $iPos = 0 Then ExitLoop ;nicht gefunden
    Else ;ipos ist innerhalb eines farbbits und nicht am anfang
    $iPos = StringInStr($BMP1Data, $searchFor1, 2, 1, $iPos + 1)
    If $iPos = 0 Then ExitLoop
    EndIf
    Else
    ExitLoop
    EndIf
    WEnd
    $BMP1Data = 0 ;strukturen löschen, Speicher freigeben
    $BMP2Data = 0
    $ptr1 = 0
    $ptr2 = 0
    _GDIPlus_BitmapUnlockBits($pbitmap1, $bitmapinfo1)
    _GDIPlus_BitmapUnlockBits($pbitmap2, $bitmapinfo2)
    _GDIPlus_ImageDispose($pbitmap1) ;Bitmaps löschen
    _GDIPlus_ImageDispose($pbitmap2)
    ToolTip("")
    SetError(1, 0, 0)
    Return 0 ;
    EndFunc ;==>_FindBMP_slow

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


    // edit, na toll, script zu lang....ich zippe es//


    Wenn der Button auf dem Bildschirm sichtbar ist, wird er gefunden, der Mauszeiger wird zum Button bewegt und eine Messagebox mit den Koordinaten des Buttons erscheint. Diese Msgbox bleibt 3 Sekunden sichtbar, dann wird die Suche erneut durchgeführt, so lange, bis das Script beendet wird. In der Hauptschleife while/wend können die Koordinaten dann ausgewertet werden.
    Die Bewegung des Mauszeigers zum gefundenen Button kann man einfach unterbinden, indem das mousemove() auskommentiert wird.

  • Bilderkennung

    • Andy
    • 8. Januar 2012 um 17:01
    Zitat

    also so dass das Skript weiterläuft im Hintergrund aber immer nach einem bestimmen Bild gesucht wird.

    Auch das ist per PtB natürlich möglich.Genau dafür wurde das Programm ja erstellt^^
    Da die Suchzeit so minimal ist, kann z.B. per Adlib alle 10-20ms der komplette Bildschirm durchsucht werden. In dieser Zeit läuft das Hauptprogramm natürlich weiter.....

  • Bilderkennung

    • Andy
    • 8. Januar 2012 um 13:26

    Hi,
    sowohl um ein Bild zu erstellen, als auch dieses "Bild" auf dem Screen zu finden und ggf. anzuklicken, gibt es "PushTheButton". Ideal also, um z.B. in Browsern Buttons anzuklicken, die man sonst nicht erreicht.
    Die Suche erfolgt entweder in AutoIt-code, dann wird das Bild in ca. 30-40ms auf einem HD-Screen gefunden, wenn die prospeed.dll im Verzeichnis liegt, wird für die Suche eine Assemblerroutine benutzt, dann findet PushTheButton das Bild in einigen Millisekunden.
    Buttons die beim Mouseover "highlighten", kann man ebenso finden wie animierte Buttons oder sich bewegende Grafiken, wie z.B. der folgende Smilie :rofl:
    Alle Funktionen sind einstellbar im Taskmenü, die Anleitung (auch dort) sollte man durchlesen.

  • Png, Jpg in Menü einfügen?

    • Andy
    • 7. Januar 2012 um 11:00

    Hi,
    mal nur zur Info....

    Zitat

    Wie bekomme ich ein Png oder ein Jpg in mein Menü?

    PNG und JPG sind DATEIFORMATE, die müssen sowieso immer in eine BITMAP bzw. HBITMAP umgewandelt werden um sie in Windows weiterzuverarbeiten.

    Zitat

    Schade, dann muss ich wohl bmp´s verwenden.

    Auch nicht :D , BMP ist wiederum ein DATEIFORMAT und hat mit BITMAP nur indirekt zu tun...

    Spoiler anzeigen
    [autoit]

    #include <GuiMenu.au3>
    #include <WinAPI.au3>
    #include <GUIConstantsEx.au3>
    #include <GDIPlus.au3>

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

    Opt('MustDeclareVars', 1)

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

    Global $iMemo
    _GDIPlus_Startup()

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

    _Main()

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

    Func _Main()
    Local $hGUI, $hFile, $hEdit, $hHelp, $hMain, $hBmp1, $hBmp2, $hbmp3
    Local Enum $idNew = 1000, $idOpen, $idSave, $idExit, $idCut, $idCopy, $idPaste, $idAbout

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

    ; Erstellt eine GUI
    $hGUI = GUICreate("Menu", 400, 300)

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

    ; Erstellt den Menüpunkt "Datei"
    $hFile = _GUICtrlMenu_CreateMenu()
    _GUICtrlMenu_InsertMenuItem($hFile, 0, "&Neu", $idNew)
    _GUICtrlMenu_InsertMenuItem($hFile, 1, "&Öffnen", $idOpen)
    _GUICtrlMenu_InsertMenuItem($hFile, 2, "&Speichern", $idSave)
    _GUICtrlMenu_InsertMenuItem($hFile, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem($hFile, 4, "B&earbeiten", $idExit)

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

    ; Erstellt den Menüpunkt "Bearbeiten"
    $hEdit = _GUICtrlMenu_CreateMenu()
    _GUICtrlMenu_InsertMenuItem($hEdit, 0, "&Ausschneiden", $idCut)
    _GUICtrlMenu_InsertMenuItem($hEdit, 1, "K&opieren", $idCopy)
    _GUICtrlMenu_InsertMenuItem($hEdit, 2, "&Einfügen", $idPaste)

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

    ; Erstellt den Menüpunkt "Hilfe"
    $hHelp = _GUICtrlMenu_CreateMenu()
    _GUICtrlMenu_InsertMenuItem($hHelp, 0, "&Über", $idAbout)

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

    ; Erstellt das Hauptmenü
    $hMain = _GUICtrlMenu_CreateMenu()
    _GUICtrlMenu_InsertMenuItem($hMain, 0, "&Datei", 0, $hFile)
    _GUICtrlMenu_InsertMenuItem($hMain, 1, "&Bearbeiten", 0, $hEdit)
    _GUICtrlMenu_InsertMenuItem($hMain, 2, "&Hilfe", 0, $hHelp)

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

    ; Setzt das neue Menü
    _GUICtrlMenu_SetMenu($hGUI, $hMain)

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

    ; Erstellt ein Memo Control
    $iMemo = GUICtrlCreateEdit("", 2, 2, 396, 276, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

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

    ; Sezt die Datei Menü checked/unchecked Bitmaps
    $hBmp1 = _WinAPI_CreateSolidBitmap($hGUI, 0xFF0000, 11, 11)
    $hBmp2 = _WinAPI_CreateSolidBitmap($hGUI, 0x00FF00, 11, 11)

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

    ;********************************************************************************************************
    $hbmp3 = _GDIPlus_BitmapCreateFromFile("avatar_autoit16x16.jpg")
    local $hbitmap =_GDIPlus_BitmapCreateHBITMAPFromBitmap($hbmp3)
    ;********************************************************************************************************

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

    _GUICtrlMenu_SetItemBitmaps($hFile, 0, $hBmp1, $hbmp3)
    _GUICtrlMenu_SetItemBitmaps($hFile, 1, $hbitmap, $hBmp2)
    _GUICtrlMenu_SetItemBitmaps($hFile, 2, $hBmp1, $hBmp2)

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

    ; Überprüft das Öffnen Menü Item
    _GUICtrlMenu_CheckMenuItem($hFile, 1)

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

    ; Zeigt ob das Bitmap Handle übereinstimmt
    MemoWrite("Handle Status ausgewählt ......: 0x" & Hex($hBmp1))
    MemoWrite("Handle Status nicht ausgewählt ....: 0x" & Hex($hBmp2))
    MemoWrite("Handle Bild ausgewählt .: 0x" & Hex(_GUICtrlMenu_GetItemBmpChecked($hFile, 0)))
    MemoWrite("Handle Bild nicht ausgewählt: 0x" & Hex(_GUICtrlMenu_GetItemBmpUnchecked($hFile, 0)))

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

    ; Die Schleife wiederholt sich, bis der Benutzer die Beenden-Aktion der GUI auslöst
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    EndFunc ;==>_Main

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

    ; Schreibt eine Nachricht in das Memo
    Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
    EndFunc ;==>MemoWrite

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


    z.b. zu verwenden mit diesem Bildchen
    Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    Dateien

    AVATAR_AUTOIT16x16.zip 1,01 kB – 177 Downloads
  • Neue AutoIt STABLE!! v3.3.8.0

    • Andy
    • 2. Januar 2012 um 23:09

    Hi,

    Zitat

    Hallo ihr lieben, anscheinend haben wir alle es verpennt.

    :D ich glaub, du bist der einzige der es erst jetzt bemerkt hat^^
    Btw. gibts schon reichlich Threads zum Thema....

  • Zeilennummern in kompilierten Scripts auch mit Obfuscator nicht nachvollziehbar

    • Andy
    • 2. Januar 2012 um 13:25

    Hi,

    Zitat

    als was würdest du es dann bezeichnen, wenn ich den Obfuscator umfunktioniere und dazu verwende, globale, ungenutzte Variablen zu entfernen

    als unglückliche Wahl eines Hilfsmittels! Oder würdest du von Hamburg aus mit einem Traktor an die Adria fahren nur weil das möglich ist?
    Um ungenutzte Variablen zu entfernen gibt es bereits Scripte!
    Tipp mal bei google ein:
    ungenutzte variablen entfernen site:https://autoit.de/www.autoit.de

    Zitat

    Includes +mein Script in eine Datei zu werfen?

    OrganizeIncludes, schau mal links bei Downloads

    Weiterhin ist es besser, Fehler dort abzufangen, wo sie entstehen, und nicht irgendwelche kryptischen Fehlermeldungen vom System/Compiler/Interpreter generieren zu lassen!
    Ich jedenfalls habe wesentlich mehr von einer Fehlermeldung:
    "Fehler in Modul 'Grafikfunktionen', in Funktion '_Objekt_Rotate()', Fehlercode: 'Variable $var kein Array'
    "Fehler wurde in Logdatei geschrieben"

    als etwa
    "Error 48000002315 in Line #32654".
    Kein Nutzer/Anwender schreibt diesen Fehlercode und und die Zeilennummer auf, und bei schwer nachzuvollziehbaren Bugs sucht man sich (wie du ja schon festgestellt hast) dumm und dämlich.....

  • Fehler im Script....ohne Fehlermeldung ?!

    • Andy
    • 31. Dezember 2011 um 07:27

    Hi,
    das Script beendet sich sehr wohl mit einer Fehlermeldung....

    Btw., die einfachste Abfrage der Variableninhalte hätte wieder mal einen Thread gespart :thumbdown:

    Spoiler anzeigen
    [autoit]

    Case $nMsg = $Brows
    $auswahl = FileOpenDialog("Wählen Sie die .mp3 Datei",@WindowsDir & "",".mp3-Dateien (*.mp3)",1 + 2)
    $filename = FileGetLongName($auswahl,".mp3")
    $filenames = StringSplit($filename,"\",2)
    _arraydisplay($filenames)
    $numbers = UBound($filenames)
    MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$numbers' & @lf & @lf & 'Return:' & @lf & $numbers) ;### Debug MSGBOX
    GUICtrlSetData($Edit1,$filenames[$numbers])

    [/autoit]


    fällt da was auf^^?

  • Ansatz um zusammenhängende Zahlen zu erkennen

    • Andy
    • 28. Dezember 2011 um 23:18

    Hi,
    schreibe die Zahlen in ein Array, welches du dann sortieren kannst

    [autoit]

    _arraysort()

    [/autoit]


    Dann durchsuche das Array nach den Lücken.

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $a[1]
    While 1
    $w = InputBox("Zahl eingeben", "Zahlen zw. 1 und 14", "")
    If $w = "" Or @error Then ExitLoop
    ReDim $a[UBound($a) + 1]
    $a[UBound($a) - 1] = Int(Number($w))
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $w = ' & $w & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    WEnd

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

    _ArrayDisplay($a)
    _ArraySort($a)
    _ArrayDisplay($a)
    _ArrayUnique($a)
    _ArrayDisplay($a)

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

    $string = $a[0]
    For $i = 1 To UBound($a) - 1
    If $a[$i] - 1 = $a[$i - 1] Then
    $string &= $a[$i] & " "
    Else
    $string &= " Lücke " & $a[$i] & " "
    EndIf
    Next
    MsgBox(0, 0, $string)

    [/autoit]
  • Nicht linearer mehrdimensionaler Gleichungslöser nach Newton

    • Andy
    • 28. Dezember 2011 um 16:44

    Das Newton-Verfahren hat den Nachteil, daß bei bestimmten Funktionen (beispielsweise Spiralen, trigonometrischen Funktionen) eine Lösung sehr weit vom Startpunkt entfernt gefunden wird (wenn überhaupt....). Wenn es dumm läuft, konvergiert die Folge nicht, oder schlimmer, oszilliert, und dann gilt es, neue Startpunkte zu finden....

    Meistens braucht man ja (alle) Lösungen innerhalb eines bestimmten Intervalls, da bietet sich dann die schnöde Intervallteilung an, bzw das schrittweise "ablaufen" der x-Achse mit kleinen Schritten und Suche nach Nulldurchgang zwischen y(n) und y(n+1) mit anschließender Intervallteilung.
    Da werden (mit Bezug auf die gewählte Schrittweite) dann auch "alle" Nullstellen gefunden, bei hyperbolischen Spiralen steigt dieses Verfahren natürlich auch irgendwann aus^^

    Jedenfalls macht es Sinn, den Funktionsverlauf grafisch darzustellen, wenn man überhaupt keine Ahnung hat, wie die Funktion überhaupt aussieht. Dann vermeidet man auch Aussagen wie "keine Nullstelle im Intervall", nur weil der Rechner keine gefunden hat :D

  • DLLStructGetSize Problem

    • Andy
    • 28. Dezember 2011 um 15:38
    Zitat

    Andy: So weit ich weiß, verwendet AutoIt malloc oder etwas vergleichbares zum Allokieren des Speichers.

    Ja, da bin ich mir sicher.

    Zitat

    die Angabe align 16 bezieht sich auf die strukturinterne Zählung

    hmm, das würde bedeuten, dass das "align" nur für das Auffüllen von Füllbytes (padding) innerhalb der Struct gut wäre, aber nicht für das Ausrichten an Speicheradressen.
    Wobei zugegebenermaßen ein align 16 recht selten vorkommt.

  • DLLStructGetSize Problem

    • Andy
    • 27. Dezember 2011 um 21:04

    Hi,
    bitte beachten, daß "align 16" KEINE korrekten Adressen zurückliefert!
    Bei Verwendung von Assembler- und C++-Programmen (sowohl "inline" als auch als DLL) in Kombination mit AutoIt hatte ich dieses Problem schon öfter!
    Beim Laden eines SSE-Registers (z.B. MOVDQA ) wird zwingend eine durch 16 teilbare Speicheradresse vorrausgesetzt. Ist das nicht so, führt das zu einem Absturz bzw Exception.

    /EDIT/Der Grund ist, wie von prog@andy vorzüglich erklärt :thumbup: , das Layout des Arbeitsspeichers.

    Testscript:

    [autoit]

    Dim $a[1100]

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

    For $i = 1 To 1000
    $a[$i] = DllStructCreate("align 16;int64["&$i&"]");verschieden große structs erzeugen
    $ptr = Number(DllStructGetPtr($a[$i]))
    If Mod($ptr, 16)<>0 Then;adresse aligned?
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr <> align16 ' & $ptr & " " & $i & " " & Mod($ptr, 16) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    EndIf
    Next

    [/autoit]


    Btw ist es egal, welcher Datentyp beim Erstellen der struct verwendet wird!

    Demnach ist der folgende Satz aus der Hilfe zu dllstructcreate() definitiv nicht zutreffend:
    Erlaubte Werte sind 1, 2, 4, 8 und 16. Die Ausrichtung eines Elements wird entweder an der Grenze eines Vielfachen von n oder an der eines Vielfachen der Größe eines Elements sein, je nach dem welches kleiner ist. Dies ist wie bei der "#pragma pack option" mit dem Microsoft Visual C++ Compiler.

    Die #pragma pack option aller (von mir ausprobierten ) C-Compiler funktioniert selbstverständlich einwandfrei!

    Abhilfe für 16-Byte alignment:

    Spoiler anzeigen
    [autoit]

    #include <Memory.au3>
    #include <MemoryConstants.au3>

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

    Dim $a[1100]

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

    ;~ For $i = 1 To 1000
    ;~ $a[$i] = DllStructCreate("align 16;int64["&$i&"]");verschieden große structs erzeugen
    ;~ $ptr = Number(DllStructGetPtr($a[$i]))
    ;~ If Mod($ptr, 16)<>0 Then;adresse aligned?
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr <> align16 ' & $ptr & " " & $i & " " & Mod($ptr, 16) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;~ EndIf
    ;~ Next

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

    ;~ msgbox(0,0,"...jetzt mit 16Byte-alignment")

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

    For $i = 1 To 1000
    $a[$i] = _DllStructCreate16("int64["&$i&"]");verschieden große structs erzeugen
    $ptr = number(DllStructGetPtr($a[$i]))
    If Mod($ptr, 16)=0 Then;adresse aligned?
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = align16 ' & $ptr & " " & $i & " " & Mod($ptr, 16) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    EndIf
    Next

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

    Func _dllstructcreate16($struct) ;align auf 16-byte adresse
    local $temp = DllStructCreate($struct)
    local $tempsize = DllStructGetSize($temp) + 16
    $temp = 0;struct löschen
    local $mem = _MemGlobalAlloc($tempsize + 16, BitOR($GMEM_FIXED, $GMEM_ZEROINIT)) ;pointer auf speicher
    ;rest div 16 adresse = offset
    return DllStructCreate($struct, (Number($mem) - Mod(Number($mem), 16) + 16)) ;auf 16 alingned pointer
    EndFunc ;==>_dllstructcreate16

    [/autoit]
  • DllStruct Funktionen für Autoit

    • Andy
    • 26. Dezember 2011 um 11:54

    Hi,
    größtenteils ist es sehr sinnvoll, die Hilfe zu den einzelnen Befehlen zu lesen^^

    [autoit]

    $a=dllstructcreate(blablub)

    [/autoit]

    in $a steht nur das "handle" für die folgenden dllstruct()-Funktionen
    Da macht es also wenig Sinn, dieses Handle per TCP zu veschicken....

    Im Deskstream habe ich diese little/big-Endian-Geschichte abgehandelt. Wenn man weiss, wie man die einzelnen Datentypen ineinander umwandelt, ist das auch garkein Problem :D

    Eine extra "Endian"-Funktion ist übrigens völlig unnötig, da die Daten in TCP genau so ankommen, wie sie abgeschickt wurden!
    Nur wenn man einen "int" ( 4 Byte) byteweise ausliest (von "vorne nach hinten") dann ist das relevant.
    Übrigens hat diese "Endianess" schon für reichlich graue Haare bei der Umwandlung von ARGB (Bitmap dword) in die einzelnen Farben gesorgt, stimmts Shadow? :rofl:

  • DllStruct Funktionen für Autoit

    • Andy
    • 25. Dezember 2011 um 00:59
    Zitat

    Und ist es auch so das es Dll´s gibt, die man nicht mitDdllCall sondern mit DllStruct Funktionen aufrufen muß ?

    eher nicht....obwohl ich langsam ahne, auf was du hinauswillst...
    Man kann im Speicherbereich eines fremden Threads eine Struct an der Position einer geladenen DLL erstellen, in der Struct (und somit der DLL-Funktion) Veränderungen durchführen und somit das "fremde" Programm beeinflussen bzw Daten lesen/umleiten.
    Aber dafür gibts ein extra AutoIt-Forum ;)

  • DllStruct Funktionen für Autoit

    • Andy
    • 25. Dezember 2011 um 00:45
    Zitat

    und mit Struktur ist glaub ich die calling convesion gemeint oder ?

    zwei völlig verschiedene Paar Schuhe :D

    Zitat

    Mit GUI´s habe ich seit meiner 1 Jährigen Autoit Karriere so gut wie noch nie mit gearbeitet. die Laufen unter einer Dauerschleife und machen Autoit langsmer richtig ?

    auch falsch^^

    Zitat

    und dann könnte man mit dem richtigen Autoit DllStruct dazu die externe Dll gezielt ansprechen ?

    FALLS die Dll mit Structs arbeitet oder nicht die Daten selbst, sondern einen Pointer (Zeiger im Speicher auf die Daten) als Übergabeparameter verwendet, DANN benötigst du Structs, ansonsten brauchst du auch für einen Dllcall keine Struct.

  • DllStruct Funktionen für Autoit

    • Andy
    • 25. Dezember 2011 um 00:40
    Zitat

    Nochmal Autoit wurde doch erstellt um möglichst einfach zu sein

    yepp, und die Erde war am Anfang auch eine Scheibe ;)
    Mittlerweile gibt es in AutoIt bis auf extrem wenige Ausnahmen nichts, was man programmtechnisch nicht realisieren könnte.
    Und für einige Sachen benötigt man zwangsläufig Structs.
    Ob man das in AutoIt machen muß oder besser gleich eine "geeignetere" Sprache verwendet, bleibt jedem selbst überlassen.

  • Maussperre

    • Andy
    • 25. Dezember 2011 um 00:16

    Hi,
    schau dir mal die Funktion

    [autoit]

    _mousetrap()

    [/autoit]

    an

  • DllStruct Funktionen für Autoit

    • Andy
    • 25. Dezember 2011 um 00:08
    Zitat

    String bleibt String

    wzbw^^

    [autoit]

    $struct_float=dllstructcreate("float[5]");5 floatzahlen
    dllstructsetdata($struct_float,1,4.52301424904732e+024,1);floatzahlen in Speicher eintragen
    dllstructsetdata($struct_float,1,6.34941479652706e+022,2)
    dllstructsetdata($struct_float,1,2.74865539637211e+020,3)
    dllstructsetdata($struct_float,1,7.21364385566043e+022,4)
    dllstructsetdata($struct_float,1,1.19923122576918e-041,5)
    $struct_char=dllstructcreate("char[20]",dllstructgetptr($struct_float));struct erstellen an Position der Floatzahlen
    Msgbox(0,"",dllstructgetdata($struct_char,1));Speicher auslesen

    [/autoit]

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™