Hi,
naja, vielleicht ist ja noch nicht alles verloren, stell mal 2-3 Bilder online oder schicke sie per PM.
Eine Funktion, welche die Farben bzw die Farbkanäle anpasst ist ja in wenigen Zeilen schnell geschrieben.
Hi,
naja, vielleicht ist ja noch nicht alles verloren, stell mal 2-3 Bilder online oder schicke sie per PM.
Eine Funktion, welche die Farben bzw die Farbkanäle anpasst ist ja in wenigen Zeilen schnell geschrieben.
omfg...das meinst du doch etwa nicht Ernst?
Hier im Forum gibt es hunderte von Scripten welche die einzelnen Farbkanäle bearbeiten oder zumindest zeigen wie man das macht (jedenfalls NICHT per BRUSH! ).....und du schreibst ein Script wo du GLAUBST, dass es funktioniert und lässt das auf deine Orginalfotos los?
Zeig mal bitte dein komplettes Script und auch 2 oder 3 deiner ORGINAL-Fotos (die bearbeiteten). Dann kann man dir vielleicht weiterhelfen!
Btw, wie kommst du zu der Annahme, dass durch einen Alphakanal von 11 die Bilder kleiner werden?
Es ist völlig egal, welchen Wert der Alphakanal annimmt, solange dafür im Bitmap-Format ein Byte reserviert ist, bleibt die Bildgrösse gleich!
oder die Länge des Strings alle 2-3 Sekunden abfragen
[autoit]stringlen()
[/autoit]Hi,
ZitatWarum wertest du allerdings digonale Felder schlechte als horizontal und vertikale Felder, eigentlich müsst es umgekehrt sein, da du mit diagonalen Sprüngen mehr "Weg" zurücklegen kannst also mit einfacher horizontaler bzw. vertikaler Bewegung.
Gute Frage, aber der "Wert" der zurückzulegenden Strecke ist imho die Entfernung. Und die ist bei einem diagonalen Sprung sqrt(2) also ca. 1,4 mal länger als ein horizontaler bzw. vertikaler Sprung. Und das stimmt auch, denn einmal nach rechts laufen und dann nach unten sind 2 Wegstrecke, während einmal diagonal gesprungen nur 1,4 Wegstrecke ist!
Habe aber, damit die "Optik" stimmt, das Script etwas angepasst und auch eine Editierfunktion eingebaut.
Man kann nun die Hindernisse mit einem Klick "löschen" und auch nach der Wegfindung das Labyrinth verändern.
/EDIT/ geändertes Script im ersten Post
Hi,
der Algorithmus ist ausbaufähig bzw.bei der Wegfindung zu beeinflussen.
Es gibt die "schnelle" Lösung, die auch Umwege beinhalten kann, oder eine Lösung, welche den Weg etwas ausführlicher untersucht und daher ggf. kürzere Strecken zum Ziel findet (und damit auch ggf. länger sucht).
In den Zeilen
[autoit]$liste[$listenindex][0] = $kleinster_nachbar + $add + $abstand_zum_ziel ;gesamtgewicht
$liste[$listenindex][0] = $abstand_zum_ziel ;gesamtgewicht
kann man auswählen, welche Daten der einzelnen Wegpunkte in die Liste geschrieben und zur Findung des am nächsten liegenden möglichen Wegpunktes herangezogen werden.
Dort wäre es bspw. auch möglich, "Berge" und "Autobahnen" einzubauen, die den Weg nicht völlig versperren bzw. den Weg zum Ziel verkürzen.
UEZ, mir schwebt da eher eine Speicher/Ladefunktion des Labyrinth´s vor, Buttons dafür hats ja auf der GUI reichlich
ZitatCool wäre es, wenn man schwarze Linien zeichnen könnte
Ich hatte mir schon überlegt, keine Buttons, sondern Pixel als Wegpunkte anzusteuern, dann wird die "Zeichenfunktion" automatisch nötig.
Allerdings kann man hier bei entsprechend kleinen Feldern sehr schön mitverfolgen, wie der Algorithmus funktioniert. Das war die Intention.
Hi,
nachdem ein einzelnes Forenmitglied
eine Nachfrage nach dem a*-Algorithmus gestellt hatte, bekam ich Lust, den Lösungsweg in "schöner" Form in ein Script zu giessen.
Schön ist hier nicht der Code, sondern die Darstellung^^
Man beginnt mit einem leeren Feld, auf dem man den Startpunkt und den Zielpunkt markieren kann.
Entweder man klickt jetzt nochmal auf den Startpunkt und der Algorithmus sucht den kürzesten Weg zum Ziel, oder man klickt auf ein leeres Feld, um dort ein "Hindernis" zu erstellen.
So kann man auch ein Labyrinth erstellen, durch das sich a* den kürzesten Weg zum Ziel sucht....
Viel Spass!
Global $feldgroesse_x = 40
Global $feldgroesse_y = 30
Global $startx, $starty, $zielx, $ziely, $start = 0
Global $listenindex, $ziel_gefunden = 0
Dim $feld[$feldgroesse_x * $feldgroesse_y + 1] ;warum eindimensional? damit man es in eine struct umwandeln kann^^
Dim $liste[$feldgroesse_x * $feldgroesse_y + 1][3] ;liste der besten kandidaten
$w = 1200
$h = 900
$abstand = 1
$hgui = GUICreate("a-star", $w, $h)
[/autoit] [autoit][/autoit] [autoit]$breite = Round(($w - 2 * $abstand - ($feldgroesse_x - 1) * $abstand) / $feldgroesse_x)
$hoehe = Round(($h - 2 * $abstand - ($feldgroesse_y - 1) * $abstand) / $feldgroesse_y)
For $y = 0 To $feldgroesse_y - 1
For $x = 0 To $feldgroesse_x - 1
$feld[$y * $feldgroesse_x + $x] = GUICtrlCreateButton("", $x * ($breite + $abstand) + $abstand, $y * ($hoehe + $abstand) + $abstand, $breite, $hoehe)
If $x = 0 Or $y = 0 Or $x = $feldgroesse_x - 1 Or $y = $feldgroesse_y - 1 Then ;rand einfärben
GUICtrlSetBkColor($feld[$y * $feldgroesse_x + $x], 0x000000) ;Rand schwarz
GUICtrlSetColor($feld[$y * $feldgroesse_x + $x], 0x000000)
GUICtrlSetData($feld[$y * $feldgroesse_x + $x], "X")
EndIf
Next
Next
WinSetTitle($hgui, "", "a* DEMO: Bitte Startpunkt auswählen ")
[/autoit] [autoit][/autoit] [autoit]GUISetState()
[/autoit] [autoit][/autoit] [autoit]$rot = 0xFF0000
$gruen = 0x00FF00
$blau = 0x0000FF
$schwarz = 0x000000
$weiss = 0xFFFFFF
$grau = 0xF6F6F4
$i = 1
[/autoit] [autoit][/autoit] [autoit]While 1
$msg = GUIGetMsg()
Switch $msg
Case -3
ExitLoop
Case $feld[$start] ; a* starten
If $i > 2 Then
If _astar() = 1 Then
WinSetTitle($hgui, "", "a* DEMO: Bitte Hindernisse auswählen und danach auf 'Start' drücken")
$i = 3 ;nochmal
EndIf
EndIf
Case $feld[0] To $feld[$feldgroesse_x * $feldgroesse_y - 1]
$msg -= $feld[0] ;korrektur buttonindex
$xx = Mod($msg, $feldgroesse_x) + 1 ;x-und y- koordinaten des buttons
$yy = Int($msg / $feldgroesse_x) + 1
If $xx > 1 And $yy > 1 And $xx < $feldgroesse_x And $yy < $feldgroesse_y Then ;innerhalb des Randbereichs
Switch $i
Case 1 ;startpunkt ausgewählt
$i += 1
GUICtrlSetBkColor($feld[$msg], $rot) ;startpunkt
GUICtrlSetData($feld[$msg], "Start")
WinSetTitle($hgui, "", "a* DEMO: Bitte Zielpunkt auswählen")
$startx = $xx
$starty = $yy
$start = ($yy - 1) * $feldgroesse_x + ($xx - 1)
Case 2 ;zielpunkt
$i += 1
GUICtrlSetBkColor($feld[$msg], $gruen)
WinSetTitle($hgui, "", "a* DEMO: Bitte Hindernisse auswählen und danach auf 'Start' drücken")
GUICtrlSetData($feld[$msg], "Ziel")
$zielx = $xx
$ziely = $yy
Case 3 To $feldgroesse_x * $feldgroesse_y - 3
$i += 1
If GUICtrlRead($feld[$msg]) = "X" Then ;Hindernis entfernen
GUICtrlSetBkColor($feld[$msg], $grau);hintergrund
GUICtrlSetColor($feld[$msg], $schwarz);schrift
GUICtrlSetData($feld[$msg], "");leer
Else
GUICtrlSetBkColor($feld[$msg], $schwarz)
GUICtrlSetColor($feld[$msg], $weiss)
GUICtrlSetData($feld[$msg], "X")
EndIf
EndSwitch
EndIf
EndSwitch
WEnd
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _astar() ;sucht kürzeste strecke vom start zum ziel
WinSetTitle($hgui, "", "a* DEMO: Berechnung... ")
; $optimum = Sqrt(($startx - $zielx) ^ 2 + ($starty - $ziely) ^ 2)
[/autoit] [autoit][/autoit] [autoit]$index_x = $startx
$index_y = $starty
While 1
[/autoit] [autoit][/autoit] [autoit]suche_nachbar($index_x, $index_y) ;sucht leere nachbarfelder und füllt sie aus mit kleinstem abstand
[/autoit] [autoit][/autoit] [autoit]If $ziel_gefunden = 1 Then
Switch Auf_kuerzestem_Weg_zurueck() ;nochmal?
Case 6 ;Ja
Dim $liste[$feldgroesse_x * $feldgroesse_y + 1][3];liste leeren
$listenindex = 0
$ziel_gefunden = 0
$gesamt = 0
For $i = 1 To $feldgroesse_x * $feldgroesse_y;felder leeren
If Number(GUICtrlRead(($feld[$i]))) <> 0 Then ;keine Buchstaben, nur Ziffern im Feld
GUICtrlSetData($feld[$i], "");inhalt löschen
GUICtrlSetBkColor($feld[$i], $grau);grau
EndIf
Next
Return 1
Case 7 ;abbrechen
Exit
EndSwitch
Exit
EndIf
$kleinstes = 2 ^ 30
For $i = 1 To $listenindex ;kleinster abstand zum ziel suchen
If $liste[$i][0] < $kleinstes Then ;kleinstes gefunden
$kleinstes = $liste[$i][0]
$index = $i ;index kleinster abstand
EndIf
Next
If $kleinstes = 2 ^ 30 Then Exit (MsgBox(0, "a* DEMO", "Ziel nicht gefunden!"))
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $kleinstes = ' & $kleinstes & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$index_x = $liste[$index][1] ;koordinaten für nächsten durchlauf
$index_y = $liste[$index][2] ;koordinaten für nächsten durchlauf
$liste[$index][0] = 2 ^ 30 ;aus liste herausnehmen
;_arraydisplay($liste)
WEnd
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>_astar
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func suche_nachbar($x, $y) ;sucht leere nachbarfelder und füllt sie aus mit kleinstem abstand
[/autoit] [autoit][/autoit] [autoit];abstand gerade = 1
;abstand schräg =1.4 =sqrt(2)
For $yy = $y - 1 To $y + 1 ;3x3 matrix
For $xx = $x - 1 To $x + 1
If $yy = $y And $xx = $x Then ContinueLoop ;mittelpunkt erreicht
$index = ($yy - 1) * $feldgroesse_x + ($xx - 1)
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$inhalt = GUICtrlRead($feld[$index])
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $inhalt = ' & $inhalt & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
If $inhalt = "Ziel" Then
MsgBox(0, "a* DEMO", "Ziel gefunden!!!")
$ziel_gefunden = 1
EndIf
If $inhalt = "" Then ;leeres feld gefunden, dort den kürzesten abstand zu allen angrenzenden mit zahlen ausgefüllten feldern finden
$kleinster_nachbar = 2 ^ 30
$add = 0
For $yyy = $yy - 1 To $yy + 1 ;3x3 matrix
For $xxx = $xx - 1 To $xx + 1
If $yyy = $yy And $xxx = $xx Then ContinueLoop ;mittelpunkt erreicht
$index2 = ($yyy - 1) * $feldgroesse_x + ($xxx - 1)
$inhalt2 = GUICtrlRead($feld[$index2])
If $inhalt2 <> "X" And $inhalt2 <> "" And $inhalt2 <> "Ziel" And $inhalt <> "Start" Then
$inhalt2 = Number($inhalt2)
;MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$inhalt2' & @LF & @LF & 'Return:' & @LF & $inhalt2) ;### Debug MSGBOX
If ($yyy = $yy - 1 And ($xxx = $xx - 1 Or $xxx = $xx + 1)) Or ($yyy = $yy + 1 And ($xxx = $xx - 1 Or $xxx = $xx + 1)) Then ;diagonal
If $inhalt2 < $kleinster_nachbar Then
$kleinster_nachbar = $inhalt2 ;diagonal
$add = 1.16
EndIf
Else
If $inhalt2 < $kleinster_nachbar Then
$kleinster_nachbar = $inhalt2 ;waagrecht und senkrecht
$add = 1
EndIf
EndIf
EndIf
[/autoit] [autoit][/autoit] [autoit]Next
Next
$abstand_zum_ziel = Int(Sqrt(($xx - $zielx) ^ 2 + ($yy - $ziely) ^ 2) * 10) / 10 ;eine nachkommastelle
$listenindex += 1 ;neuen kandidaten gefunden
$liste[$listenindex][0] = $kleinster_nachbar + $add + $abstand_zum_ziel ;gesamtgewicht
; $liste[$listenindex][0] = $abstand_zum_ziel ;gesamtgewicht
$liste[$listenindex][1] = $xx ;koordinaten
$liste[$listenindex][2] = $yy
GUICtrlSetData($feld[$index], $kleinster_nachbar + $add) ;startfeld
EndIf
; MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$inhalt' & @LF & @LF & 'Return:' & @LF & $inhalt) ;### Debug MSGBOX
Next
Next
EndFunc ;==>suche_nachbar
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func Auf_kuerzestem_Weg_zurueck()
$x = $zielx
$y = $ziely
$Kleinster_nachbar_index = 2 ^ 30
$gesamt = 0 ;kürzeste gesamtstrecke
While 1
$kleinster_nachbar = 2 ^ 30
For $yy = $y - 1 To $y + 1 ;3x3 matrix
For $xx = $x - 1 To $x + 1
If $yy = $y And $xx = $x Then ContinueLoop ;mittelpunkt erreicht
$index = ($yy - 1) * $feldgroesse_x + ($xx - 1)
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$inhalt = GUICtrlRead($feld[$index])
If $inhalt = "Start" Then ;am start angekommen
Return MsgBox(4, "a* DEMO", "Kürzeste Strecke = " & $gesamt & @CRLF & @CRLF & "Labyrint ändern?")
EndIf
If $inhalt <> "X" And $inhalt <> "" And $inhalt <> "Ziel" Then ;Zahl gefunden
$abstand = Number($inhalt)
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $abstand = ' & $abstand & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
If $abstand < $kleinster_nachbar Then
$kleinster_nachbar = $abstand
$Kleinster_nachbar_x = $xx
$Kleinster_nachbar_y = $yy
$Kleinster_nachbar_index = $index
EndIf
EndIf
Next
Next
$gesamt += $kleinster_nachbar
$x = $Kleinster_nachbar_x
$y = $Kleinster_nachbar_y
GUICtrlSetBkColor($feld[$Kleinster_nachbar_index], $blau)
;msgbox(0,0,$kleinster_nachbar)
WEnd
EndFunc ;==>Auf_kuerzestem_Weg_zurueck
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]Mit 30x30 Feldern und 1200x900 Pixeln sieht das bspw. so aus:
/EDIT/
Die gemächliche Geschwindigkeit ist dem GuiCtrlSet/GuiCtrlGet/GuiCtrlRead-Gedöns geschuldet. Die reine Rechenzeit liegt im Millisekundenbereich.
Hi,
da scheint was faul zu sein mit AutoIt?!
Sämtliche Beispiele funktionieren nicht mehr, auch das von Gary Frost nicht.
Was ich aber herausgefunden habe:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GUIButton.au3>
$hGUI = GUICreate("Not Hovering...", 400, 400)
;$hButton = _GUICtrlButton_Create($hGUI, "Test", 50, 50, 60, 25)
GUISetState()
sleep(3000)
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
GUIRegisterMsg($WM_MOUSEHOVER, "WM_MOUSEHOVER")
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")
GUIRegisterMsg($WM_MOUSELEAVE, "WM_MOUSELEAVE")
GUIRegisterMsg($WM_NCMOUSEHOVER, "WM_NCMOUSEHOVER")
GUIRegisterMsg($WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE")
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
WinSetTitle($hGUI, "", "Not Hovering...")
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hGUI = ' & timerinit() & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
Return $GUI_RUNDEFMSG
EndFunc
Func WM_MOUSEHOVER($hWnd, $iMsg, $wParam, $lParam)
WinSetTitle($hGUI, "", "Hovering!")
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : HOVERING = ' & timerinit() & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
sleep(200)
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
Return $GUI_RUNDEFMSG
EndFunc
Func WM_MOUSELEAVE($hWnd, $iMsg, $wParam, $lParam)
WinSetTitle($hGUI, "", "LEAVE!")
sleep(200)
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
Return $GUI_RUNDEFMSG
EndFunc
Func WM_NCMOUSEHOVER($hWnd, $iMsg, $wParam, $lParam)
WinSetTitle($hGUI, "", "NC-Hovering!")
sleep(200)
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
Return $GUI_RUNDEFMSG
EndFunc
Func WM_NCMOUSELEAVE($hWnd, $iMsg, $wParam, $lParam)
WinSetTitle($hGUI, "", "NC-LEAVE!")
sleep(200)
If Not _WinAPI_TrackMouseEvent($hGUI, 1) Then Exit
Return $GUI_RUNDEFMSG
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_TrackMouseEvent
; Description....: Posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time.
; Syntax.........: _WinAPI_TrackMouseEvent ( $hWnd, $iFlags [, $iTime] )
; Parameters.....: $hWnd - Handle to the window to track.
; Return values..: $iFlags - The services requested. This parameter can be a combination of the following values.
;
; $TME_CANCEL
; $TME_HOVER
; $TME_LEAVE
; $TME_NONCLIENT
; $TME_QUERY
;
; $iTime - The hover time-out (if $TME_HOVER was specified in $Flags), in milliseconds. Can be (-1), which
; means to use the system default hover time-out.
; Failure - 0 and sets the @error flag to non-zero.
; Author.........: Matt Diesel (Mat)
; Modified.......: Yashied
; Remarks........: None
; Related........:
; Link...........: @@MsdnLink@@ TrackMouseEvent
; Example........: Yes
; ===============================================================================================================================
Func _WinAPI_TrackMouseEvent($hWnd, $iFlags, $iTime = -1)
[/autoit] [autoit][/autoit] [autoit]Local $tTME = DllStructCreate('dword;dword;hwnd;dword')
[/autoit] [autoit][/autoit] [autoit]DllStructSetData($tTME, 1, DllStructGetSize($tTME))
DllStructSetData($tTME, 2, $iFlags)
DllStructSetData($tTME, 3, $hWnd)
DllStructSetData($tTME, 4, -1)
Local $Ret = DllCall('user32.dll', 'int', 'TrackMouseEvent', 'ptr', DllStructGetPtr($tTME))
[/autoit] [autoit][/autoit] [autoit]If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return 1
EndFunc ;==>_WinAPI_TrackMouseEvent
Script starten, Mauscursor in die Titelleiste, Fenster verschieben und anhalten (Maustaste gedrückt lassen), 400ms warten, tadaaaa Hoverevent...aber erst nachdem das WM_NCMOUSELEAVE gefeuert wurde...wtf?!
...hat zwar etwas gedauert, aber jetzt hab auch ich es kapiert ![]()
Hi,
das Gerödel mit _GDIPlus_GraphicsDrawBezier() kann man imho weglassen. Ich würde nur Linien zeichnen, durch die extrem schnelle Abfrage (es ist jetzt schon ein Sleep() im Script! ) wird der Linienzug "fast" zum Bogen^^
Hi zusammen,
HIER kann man die FASM.dll herunterladen. Mit dem angehängten Script erhält man einen aus AutoIt aufrufbaren Assembler.
Es sind, ausser der DLL, keine weiteren Includes nötig!
Der Assemblercode kann sowohl als Text (z.B. aus einer Datei), oder direkt eingegeben werden, wird auf Fehler untersucht und dann sofort per DllCallAddress() ausgeführt. Aufruf aus AutoIt als Einzeiler natürlich ![]()
Bitte mal einfachen 64-Bit-Code testen (ich kann das zzt. nicht), soll dieser Assembler auch können! Aufrufkonventionen beachten!
;fasm.dll hier:
;http://board.flatassembler.net/topic.php?t=6239
;asm-code als string
Global $sourcetext = _ ;pseudo-Random, Rückgabe in EAX
"use32" & @CRLF & _ ;32 bit
"mov ecx,[esp+4]" & @CRLF & _ ;ersten parameter laden
"rdtsc" & @CRLF & _ ;timerticks in EDX:EAX
"rcl eax,cl" & @CRLF & _ ;EAX linksrum rotieren, CL mal
"mov ebx,123433" & @CRLF & _ ;Primzahl laden
"mul ebx" & @CRLF & _ ;und mit EAX multiplizieren
"" & @CRLF & _
"" & @CRLF & _ ;Leerzeilen ![]()
"" & @CRLF & _
"ret 8" & @CRLF & _ ;Aufrufparameter vom Stack löschen und zurück
"" & @CRLF & _
""
;Source,Rückgabetyp,Typ1,Para1,Typ2,Para2....
$return = _FASMdll($sourcetext, "word", "int", 22, "ptr", 33)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $return = ' & $return & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;das wars schon....
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _FASMdll($sourcetext, $Returntype, $Type1 = "", $Param1 = 0, $Type2 = "", $Param2 = 0, $Type3 = "", $Param3 = 0, $Type4 = "", $Param4 = 0, $Type5 = "", $Param5 = 0, $Type6 = "", $Param6 = 0, $Type7 = "", $Param7 = 0, $Type8 = "", $Param8 = 0, $Type9 = "", $Param9 = 0, $Type10 = "", $Param10 = 0, $Type11 = "", $Param11 = 0, $Type12 = "", $Param12 = 0, $Type13 = "", $Param13 = 0, $Type14 = "", $Param14 = 0, $Type15 = "", $Param15 = 0, $Type16 = "", $Param16 = 0, $Type17 = "", $Param17 = 0, $Type18 = "", $Param18 = 0, $Type19 = "", $Param19 = 0, $Type20 = "", $Param20 = 0) ;assembles the code
;Dll öffnen
$FASMdll = DllOpen("fasm.dll")
if @error then exit(Msgbox(0,"FASM.dll","Error loading FASM.dll"))
;Version auslesen
$version = DllCall($FASMdll, "ptr", "fasm_GetVersion")
ConsoleWrite('FASM.dll Version = ' & $version[0] & @CRLF& @CRLF)
;asm-code in speicher schreiben
$struct_source = DllStructCreate("byte [10000]");sollte reichen^^
DllStructSetData($struct_source, 1, StringToBinary($sourcetext))
$ptr_source = DllStructGetPtr($struct_source)
;bytes reservieren für den assembler
$len_mem = 800000
$struct_mem = DllStructCreate("byte [" & $len_mem & "]")
$ptr_mem = DllStructGetPtr($struct_mem)
;FASM_STATE-struct, siehe FASM.ASH
$struct_state = DllStructCreate("dword condition; int output_lenght; ptr error_code;ptr output_data; long error_line", $ptr_mem)
$ptr_state = DllStructGetPtr($struct_state)
;Assembler aufrufen
$ret = DllCall($FASMdll, $Returntype, "fasm_Assemble", "ptr", $ptr_source, "ptr", $ptr_mem, "dword", $len_mem, "dword", 100, "dword", 0)
if @error then
Msgbox(0,"FASM.dll","Error calling FASM.dll (fasm_Assemble)")
DllClose($FASMdll)
Exit
endif
;FASM_STATE-struct auslesen
$err_state_condition = DllStructGetData($struct_state, "condition")
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_condition = ' & $err_state_condition & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$err_state_output_length = DllStructGetData($struct_state, "output_lenght")
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_output_length = ' & $err_state_output_length & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$err_state_error_code = DllStructGetData($struct_state, "error_code")
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_error_code = ' & $err_state_error_code & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$err_state_output_data = DllStructGetData($struct_state, "output_data")
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_output_data = ' & $err_state_output_data & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$err_state_error_line = DllStructGetData($struct_state, "error_line")
;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_error_line = ' & $err_state_error_line & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;
If $err_state_condition = 0 Then ;kein Fehler aufgetreten
;assemblierten code auslesen...
$code_struct = DllStructCreate("byte [" & $err_state_output_length & "]", $err_state_error_code)
$code_ptr = DllStructGetPtr($code_struct)
$code = DllStructGetData($code_struct, 1)
;code anzeigen
ConsoleWrite('$code = ' & $code & @CRLF & @CRLF )
;DllCallAddress() generieren
$scriptstring = "DllCallAddress($Returntype,$code_ptr"
For $n = 1 To @NumParams / 2 - 1
If Eval("Type" & $n) <> "" Then $scriptstring &= ",'" & Eval("Type" & $n) & "'," & Eval("Param" & $n);parameter gefunden
Next
$scriptstring &= ")"
;...und aufrufen
$ret = Execute($scriptstring) ;dllcalladdress aufrufen
If @error Then exit(MsgBox(0, "FASMdll", "Error executing: " & @CRLF & $scriptstring))
;Ergebnis=Rückgabe aus code
Return $ret[0]
Else ;Fehler aufgetreten
;s. FASM.ASH
$struct_LINE_HEADER = DllStructCreate("dword file_path;dword line_number;dword file_offset;dword macro_callin_line; dword macro_line", $err_state_error_code)
$file_path = DllStructGetData($struct_LINE_HEADER, "file_path")
$line_number = DllStructGetData($struct_LINE_HEADER, "line_number")
exit(MsgBox(0, "Fasm.dll", "Fehler " & _fasmdll_errcode($err_state_output_length) & " aufgetreten in Zeile " & $line_number))
EndIf
EndFunc ;==>_FASMdll
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _fasmdll_errcode($errcode)
[/autoit] [autoit][/autoit] [autoit]Local $FASMerrtext = "unknown Error"
[/autoit] [autoit][/autoit] [autoit]Switch $errcode
Case 0
$FASMerrtext = "OK" ;
Case 1
$FASMerrtext = "WORKING" ;
Case 2
$FASMerrtext = "ERROR"
Case -1
$FASMerrtext = "INVALID_PARAMETER";1
Case -2
$FASMerrtext = "OUT_OF_MEMORY" ;2
Case -3
$FASMerrtext = "STACK_OVERFLOW" ;3
Case -4
$FASMerrtext = "SOURCE_NOT_FOUND";4
Case -5
$FASMerrtext = "UNEXPECTED_END_OF_SOURCE";5
Case -6
$FASMerrtext = "CANNOT_GENERATE_CODE";6
Case -7
$FASMerrtext = "FORMAT_LIMITATIONS_EXCEDDED";7
Case -8
$FASMerrtext = "WRITE_FAILED" ;8
; Error codes for FASM_ERROR condition
Case -101
$FASMerrtext = "FILE_NOT_FOUND" ;101
Case -102
$FASMerrtext = "ERROR_READING_FILE";102
Case -103
$FASMerrtext = "INVALID_FILE_FORMAT";103
Case -104
$FASMerrtext = "INVALID_MACRO_ARGUMENTS";104
Case -105
$FASMerrtext = "INCOMPLETE_MACRO";105
Case -106
$FASMerrtext = "UNEXPECTED_CHARACTERS";106
Case -107
$FASMerrtext = "INVALID_ARGUMENT";107
Case -108
$FASMerrtext = "ILLEGAL_INSTRUCTION";108
Case -109
$FASMerrtext = "INVALID_OPERAND";109
Case -110
$FASMerrtext = "INVALID_OPERAND_SIZE";110
Case -111
$FASMerrtext = "OPERAND_SIZE_NOT_SPECIFIED";111
Case -112
$FASMerrtext = "OPERAND_SIZES_DO_NOT_MATCH";112
Case -113
$FASMerrtext = "INVALID_ADDRESS_SIZE";113
Case -114
$FASMerrtext = "ADDRESS_SIZES_DO_NOT_AGREE";114
Case -115
$FASMerrtext = "DISALLOWED_COMBINATION_OF_REGISTERS";115
Case -116
$FASMerrtext = "LONG_IMMEDIATE_NOT_ENCODABLE";116
Case -117
$FASMerrtext = "RELATIVE_JUMP_OUT_OF_RANGE";117
Case -118
$FASMerrtext = "INVALID_EXPRESSION";118
Case -119
$FASMerrtext = "INVALID_ADDRESS";119
Case -120
$FASMerrtext = "INVALID_VALUE" ;120
Case -121
$FASMerrtext = "VALUE_OUT_OF_RANGE";121
Case -122
$FASMerrtext = "UNDEFINED_SYMBOL";122
Case -123
$FASMerrtext = "INVALID_USE_OF_SYMBOL";123
Case -124
$FASMerrtext = "NAME_TOO_LONG" ;124
Case -125
$FASMerrtext = "INVALID_NAME" ;125
Case -126
$FASMerrtext = "RESERVED_WORD_USED_AS_SYMBOL";126
Case -127
$FASMerrtext = "SYMBOL_ALREADY_DEFINED";127
Case -128
$FASMerrtext = "MISSING_END_QUOTE";128
Case -129
$FASMerrtext = "MISSING_END_DIRECTIVE";129
Case -130
$FASMerrtext = "UNEXPECTED_INSTRUCTION";130
Case -131
$FASMerrtext = "EXTRA_CHARACTERS_ON_LINE";131
Case -132
$FASMerrtext = "SECTION_NOT_ALIGNED_ENOUGH";132
Case -133
$FASMerrtext = "SETTING_ALREADY_SPECIFIED";133
Case -134
$FASMerrtext = "DATA_ALREADY_DEFINED";134
Case -135
$FASMerrtext = "TOO_MANY_REPEATS";135
Case -136
$FASMerrtext = "SYMBOL_OUT_OF_SCOPE";136
Case -140
$FASMerrtext = "USER_ERROR" ;140
Case -141
$FASMerrtext = "ASSERTION_FAILED";141
EndSwitch
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $FASMerrtext = ' & $FASMerrtext & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
Return $FASMerrtext
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>_fasmdll_errcode
[/autoit] [autoit][/autoit] [autoit][/autoit]Todo:
- Lt. Beschreibung sollen ausführbare Dateien erstellt werden können, incl. Makros !
Muss ich erst noch implementieren.
- Wer Lust hat, einen Editor (Syntax highlighting ftw) zu integrieren, immer her damit^^
- Debugger aus _AssembleIt() integrieren.
ZitatScheiß Browser, der verheimlicht mir öfter mal was.
Wart´s nur ab, in 10 Jahren wünschen wir uns alle einen Browser, der nicht alles verheimlicht!
Ich befürchte, dann wird es nur noch "Verheimlichungs-Browser" geben....
Hi,
Arrayfunktionen reichen von der Geschwindigkeit her locker aus.
Wenn man das Script mal ausstoppt, stellt man fest, dass DrawImageRect() ca. 100-200ms braucht, in dieser Zeit holt und schreibt man Millionenmal ein Array^^
Also geht es darum, das schreiben in den Grafikspeicher zu beschleunigen, da bietet sich natürlich bitblt() an:
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <Array.au3>
;Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Global Const $W = 700
Global Const $H = 700
Global $hGUI, $hWnd, $hGraphic, $ParticleBitmap, $ParticleBuffer, $Pen, $pen2, $anz
Global $ParticlesX[110]
Global $ParticlesY[110]
Global $Time[1], $Pos, $t, $m
; Create GUI
$GUI = GUICreate("Fading Polygon by XovoxKingdom - #Polygon = 0", $W, $H)
$hWnd = WinGetHandle($hGUI)
GUISetState()
_GDIPlus_Startup()
$IMG = _Image_Create($W, $H)
$BUF = DllStructGetData($IMG, 1)
$DC = _WinAPI_GetDC($GUI)
$GFX = _GDIPlus_GraphicsCreateFromHDC($BUF)
_GDIPlus_GraphicsClear($ParticleBuffer) ;clear buffer
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
; Loop until user exits
Do
_GDIPlus_GraphicsClear($GFX, 0xCF000000) ;clear buffer
;$Pen = _GDIPlus_PenCreate("0xFFFFFFFF", 1)
$Pos = GUIGetCursorInfo()
Sleep(10)
If IsArray($Pos) Then
$ParticlesX[$anz] = $Pos[0]
$ParticlesY[$anz] = $Pos[1]
$anz += 1
$t = TimerInit()
For $i = 3 To $anz - 4 Step 3
$Pen = _GDIPlus_PenCreate("0x" & Hex($i * 2, 2) & "FFFFFF", 1)
_GDIPlus_GraphicsDrawBezier($GFX, $ParticlesX[$i], $ParticlesY[$i], $ParticlesX[$i + 1], $ParticlesY[$i + 1], $ParticlesX[$i + 2], $ParticlesY[$i + 2], $ParticlesX[$i + 3], $ParticlesY[$i + 3], $Pen)
Next
$m = TimerDiff($t)
_WinAPI_BitBlt($DC, 0, 0, $W, $H, $BUF, 0, 0, 0xCC0020)
If $anz > 100 Then ;maximum erreicht
For $t = 1 To $anz ;bögen löschen
$ParticlesX[$t] = $ParticlesX[$t + 3]
$ParticlesY[$t] = $ParticlesY[$t + 3]
Next
$anz -=4
EndIf
EndIf
Until Not True
[/autoit] [autoit][/autoit] [autoit]Func _Exit()
; Clean up resources
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($ParticleBitmap)
_GDIPlus_GraphicsDispose($ParticleBuffer)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit
Func _Image_Create($iW, $iH)
Local $Ptr, $hDC, $hBmp, $tBMI, $aDIB, $vStruct
$hDC = _WinAPI_CreateCompatibleDC(0)
$tBMI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBMI, 'Size', DllStructGetSize($tBMI) - 4)
DllStructSetData($tBMI, 'Width', $iW)
DllStructSetData($tBMI, 'Height', -$iH)
DllStructSetData($tBMI, 'Planes', 1)
DllStructSetData($tBMI, 'BitCount', 32)
$aDIB = DllCall('GDI32.DLL', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hBmp = $aDIB[0]
$Ptr = $aDIB[4]
_WinAPI_SelectObject($hDC, $hBmp)
$vStruct = DllStructCreate('int[5]')
DllStructSetData($vStruct, 1, $hDC, 1)
DllStructSetData($vStruct, 1, $iW, 2)
DllStructSetData($vStruct, 1, $iH, 3)
DllStructSetData($vStruct, 1, $Ptr, 4)
DllStructSetData($vStruct, 1, $hBmp, 5)
Return $vStruct
EndFunc ;==>_Image_Create
ZitatIch programmiere schon seit 9 Jahren und du willst mir etwas über Punkte, Kommata oder sonstige Zeichen erklären?
Was wieder mal deutlich meine These beweist, dass ein Vollspaten, ob Programmierer oder nicht, so dermaßen von sich überzeugt ist, dass er, statt das "Problem" zu debuggen bzw. den Fehler selbstständig zu finden, lieber quiekend und heulend davon ausgeht, dass immer nur andere Fehler machen.
90° bücken, die Arschbacken auseinanderreißen und heulend darauf warten, dass Mama oder Tante Frieda wie in den letzten 20 Jahren Puderzucker reinblasen....und da wundern sich einige, dass Zitate wie :" Völlige Fehlerfreiheit für Software, die eine gewisse Komplexitätsgrenze überschreitet, ist weder erreichbar noch nachweisbar." von genau DIESEN Personen auch noch unisono abgenickt werden! Und der Rest der Menschheit nickt mit...
AspirinJunkie, und wenn du mir jetzt damit kommen willst, dass die "Jugend" das garnicht können kann, weil sie ebensolche "Techniken" (debuggen bzw. Fehler finden) nicht beigebracht bekommt, dann gebe ich dir Recht!
Wir haben uns dermassen daran gewöhnt, dass "reale" gefertigte Produkte wie Fernseher, Handys, Autos, Brot oder Suppenschüsseln nur völlig fehlerfrei akzeptiert werden, während Software per se schon eine Fehlerbehaftung implizit unterstellt wird.
Wenn heute auf der Autobahm 30-40 Autos ineinanderrasen, dann hat das nicht daran gelegen dass die Fahrer mit völlig überhöhter Geschwindigkeit weit jenseits ihres eigenen Reaktionsvermögens unterwegs waren, sondern daran, dass der Abstandswarner nicht funktioniert hat, oder das automatische Bremssystem. In jedem Fall MUSS es ein technisches Problem gewesen sein, denn kein Mensch wäre so blöde im dichten Nebel mit 160km/h 30-40m hinter dem vorrausfahrenden herzudonnern.......oder?
Zitatweswegen man sich dennoch immer im Hinterkopf behalten muss was für Datentypen man denn implizit eigentlich wirklich verwendet und wie sie implizit gecastet werden:
selbst wenn der "Hinterkopf" völlig leer ist, hat man die Möglichkeit, mit programmiertechnischen Mitteln den "Fehler" abzufangen bzw. zu lokalisieren.
[autoit]If VarGetType($xPos)='Double' blablub
[/autoit]ach... ![]()
ZitatDerzeit läuft die Entwicklung etwas langsam, bin in der Firma 110% eingespannt
Willkommen im Club....
Mit Stopfunktion meine ich, den Speicherfresser "auszustoppen".
Wenn kontinuierlich mehr RAM belegt wird, dann kommt das von einer der verwendeten Funktionen. Um diese zu finden, hält man das Script per "Stop"-Funktion (die musst du dir einfach schreiben, ggf nur ne Msgbox) an den relevanten Stellen einfach an.
Wenn zwischen den "Stops" (also zwischen den Funktionsaufrufen) der Speicher sich unvorhergesehen verändert, dann grenzt man weiter ein....uswusf
ZitatMit "das dauert ewig" habe ich mich auf Funktionen aus der Excel UDF bezogen. Die sind nicht wirklich effizient. Darum bin ich ja gerade dran, die UDF neu zu schreiben.
naja, für´s "letzte belegte Zeile finden" hast du schon eine "schnelle" Funktion^^
Ich mache in letzter Zeit viel mit VBA, und muss sagen, genau wie bei AutoIt ist es für 99,9% aller Fälle schnell genug. AutoIt für die "externen" Programme und deren Zusammenspiel mit Excel und VBA dann fürs "eingemachte".
Btw, die "Excel-UDF" habe ich Aufgrund der Einschränkungen nie benutzt, ggf. kannst du mich mit einer "neuen" UDF umstimmen ![]()
Es reicht schon, die Zellen zu formatieren, damit $oExcel.ActiveSheet.UsedRange.Rows.Count "belegte" Zellen zurückgibt...
Definitiv ist in dem Sheet irgendetwas bearbeitet worden.
Btw...
ZitatDann bleibt Dir nichts anderes übrig, als das Worksheet von hinten (sprich Zeile 16384) zu durchsuchen bis Du die erste Zeile/Zelle mit Inhalt findest. Mach das dann aber nicht mit _ExcelCellRead da das ewig dauert.
jaja, die VBA-Spezis wieder....sag mal irgendeine Funktion, die Excel schnell abarbeitet^^
"Durchlaufen" dauert ewig, habe mal ein Beispiel gemacht, da wird mit nur 21 Abfragen die letzte belegte Zeile bei einer Blattgrösse von einer Million Zeilen gefunden..
dim $array[1000000]
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$erste=0 ;erste belegte zelle
$letzte=ubound($array)-1;letzte mögliche zelle
$last=random($erste,$letzte,1) ;letzte gefüllte zelle
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $last = ' & $last & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
;Array bis zu zufälliger Zeile füllen
for $i= 1 to $last
$array[$i]="a"
Next
$letzte_belegt=_findlast($erste,$letzte)
MsgBox(0,"letzte belegte Zelle="&$last,"Suche im Array, letzte belegte Zelle = "&$letzte_belegt)
func _findlast($a,$b)
$m=$a+bitshift($b-$a,1) ;mitte
if $m=$a or $m=$b then return $m ;letzte gefüllte Zelle gefunden
$l=$array[$a];linke grenze
$r=$array[$b];rechte grenze
$mid=$array[$m];die mitte
if $mid<>"" then
$m=_findlast($m,$b) ;von mitte bis rechts
Else
$m=_findlast($a,$m) ;von links bis mitte
endif
return $m
[/autoit] [autoit][/autoit] [autoit]endfunc
[/autoit]Hi,
ZitatIch verwende zum Beispiel in einer Funktion 3 if-abfragen, die alle 3 fast das selbe machen. Wenn ich diese umschreibe und reduziere, kann dies helfen?
Nein, der eigentliche Code im Speicher nimmt nur ein absolutes Minimum an Platz ein.
Überleg mal, mit welchen Zahlen du arbeitest! 1 MB ist ein Megabyte, das sind tausend Kilobyte, hundert MB daher hunderttausend Kilobyte!
Da "hilft" es nicht, indem man einige Zeilen Code oder einige Variablen einspart^^
Relativ viel Speicher wird durch Funktionen belegt, die intern Kopien von Daten anlegen, z.B. einige der Stringfunktionen. Weiterhin "verballern" große Bilder auch häufig viel Platz.
Lass dein Programm mal langsam laufen (Stopfunktionen einbauen), und schau mal nach dem Speicherverbrauch bei bestimmten Funktionen. Einige der AutoIt-Funktionen hatten in der Vergangenheit Memory-Leaks, d.h. bei mehrmaligem Aufrufen wurde immer wieder neu Speicher reserviert. Eine aktuelle AutoIt-Version könnte da Abhilfe schaffen!
Wird der Speicher kontinuierlich gefüllt, z.B. in jeder Sekunde 2KB mehr?
Dann such die Funktion, die das verursacht.
Oscar ,
du hast Recht.
Das dafür genutzte Carryflag kann imho von AutoIt nicht ausgewertet werden, Über- und Unterläufe muss man daher schon vorher abfangen, was die gesamte gewonnene Performance auffrisst.