na klar will ich die Warnhinweise auch sehen, wenn ich nicht mit der Maus im Tray bin,
Wieso vergräbst du dann die _Checks()-Funktion in die Schleife?
Rufe _Checks() einfach direkt nach dem While auf und dann funktioniert das....
na klar will ich die Warnhinweise auch sehen, wenn ich nicht mit der Maus im Tray bin,
Wieso vergräbst du dann die _Checks()-Funktion in die Schleife?
Rufe _Checks() einfach direkt nach dem While auf und dann funktioniert das....
Hi,
unglücklicherweise enthält die Excel Starter Edition nicht den VBA (die "Programmierumgebung" VisualBasicforApplications) Editor bzw. ist das VBA-Modul abgeschaltet. Die Frage ist jetzt, ob AutoIt "an Excel vorbei" überhaupt auf die Objektbibliothek zugreifen kann?!
Ansonsten wäre das Problem mit einigen Zeilen VBA erledigt. Kein Mensch braucht das "Suchen/Ersetzen" Fenster, denn das würde komplett von einem eigenen Fenster mit Scannereingabe und komplettem an deinen Workflow angepassten Arbeitsablauf ersetzt....
Ich war auch nie ein Fan von privat genutztem Excel, da ich aber beruflich seit über 15 Jahren fast ausschließlich per VBA Excel automatisiert hatte, habe ich mir Anfang letzten Jahres für 69 Euro pro Jahr das Office 365 geleistet.
Bist du Selbstständig oder Angestellter?
Auch ein Firmenaccount von Excel bzw. Office 365 kostet nicht die Welt, ich würde allerdings eine der Versionen nehmen, welche Dateien LOKAL verarbeiten kann und nicht nur online mit Dateien auf M$ Onedrive-Servern.
Das nächste wäre die Frage, was sonst noch in Excel verarbeitet werden soll. Die Tabelle besteht aktuell aus einem Tabellenblatt und zwei Spalten. Ist das alles?
Wenn nur die Daten in einer Tabelle liegen müssen, wäre OpenOffice eine Alternative. Kostenlos und mit integriertem Makro-Editor bzw. eigener VBA-ähnlicher Programmierumgebung.
Wenn andere Zugriff auf die Datei haben müssen, kann diese auch von OpenOffice in das Excel-Format exportiert werden.
So, jetzt zu deinem "Problem"
Beschreibe zunächst, was gemacht werden soll. Also der gesamte Workflow. Das Ziel der Arbeitsablaufs und was ggf. mit den Daten weiter passieren soll. NICHT was dein jetziger Arbeitsablauf ist, ich bin mir sicher dass ein XY-Problem vorliegt!
Und wie viel Zeit brauchst du aktuell pro Tag für diesen Arbeitsablauf?
Ggf kann man in Excel schon mit den Formeln etwas "zaubern".
Aber wenn ich nicht im Tray bin kommen die Splashes nicht
So, jetzt mal GAAAANZ langsam
Die Warnhinweise (Splashes?!) erscheinen NUR DANN, wenn dein Mauscurser über dem Trayicon ist und das kleine Fenster mit den Werten angezeigt wird!
Genau SO ist die Schleife von dir programmiert und ich gehe davon aus dass das auch so sein muss
Oder willst du die Warnhinweise auch sehen ohne den Maushover über dem Icon?
Hi,
bei mir (Win10 AutoIt 3.3.16.1 Ryzen 1600) werden die Warnhinweise angezeigt. Ich habe alle vorkommenden Hinweise in eine Variable gepackt und zusammen in ein Splash-Fenster geschrieben. Ist jetzt nur noch eine Funktion. Da kannst du dann einfach nur noch weitere Vergleiche und den entsprechenden Text hinzufügen, der der Rest (Nachrichten und Fenstergröße anpassen) läuft dann automatisch.
Auch hast du im Startpost im Script in Zeile 70 eine falsche Variable verglichen, hab mal alles angepasst, ansonsten funktioniert dein Script hervorragend!
Ram und Prozessor lassen sich zum Testen mit Prime95 auslasten.
#include <GuiToolTip.au3>
#include <TrayConstants.au3>
#include <GuiToolTip.au3>
#include <MemoryConstants.au3>
#include <WinAPISys.au3>
#include <GuiToolTip.au3>
TraySetIcon("authui.dll", -0)
Global $LowRam = 1 ; GB
Global $ChargeLow = 60
Global $ProcLoadHi = 90
Global $NewFreeRam, $NewBatState, $conDat, $NewProcLoad, $NewfltDriveFreeSpace, $aData
Global $strDrive = "C:\", _
$PreviousfltDriveFreeSpace = GetDriveFreeSpace($strDrive), _
$fltDriveLowSpace = 20 ; GB
$sPreviousFreeRam = GetFreeRam()
$sPreviousBatState = _BatteryStatus()
$sPreviousconState = _AcCON()
$sPreviousProcLoad = GetCPUavg()
ManageTrayIcon()
Func ManageTrayIcon()
TraySetToolTip($sPreviousFreeRam & " GB" & " Free RAM" & @CRLF & "Aufgeladen: " & $sPreviousBatState & "%" & @CRLF & "Prozessor Auslastung :" & $sPreviousProcLoad & " %" & @CRLF & $sPreviousconState & @CRLF & "SytemDrive free on '" & $strDrive & "' : " & $PreviousfltDriveFreeSpace & " GB")
While True
$a = WinList("[CLASS:tooltips_class32]")
For $i = 1 To UBound($a) - 1
If WinGetTitle($a[$i][1]) = $sPreviousFreeRam Then
$NewfltDriveFreeSpace = GetDriveFreeSpace($strDrive)
$NewFreeRam = GetFreeRam()
$NewBatState = _BatteryStatus()
$NewConState = _AcCON()
$NewProcLoad = GetCPUavg()
$NewTitle = "Health Status"
If $NewFreeRam <> $sPreviousFreeRam Then
ConsoleWrite(WinGetTitle($a[$i][1]) & @CRLF&@crlf)
TraySetToolTip($NewFreeRam & " GB" & " Free RAM" & @CRLF & "Aufgeladen: " & $NewBatState & "%" & @CRLF & "Prozessor Auslastung :" & $NewProcLoad & " %" & @CRLF & $NewConState & @CRLF & "SytemDrive free on '" & $strDrive & "' : " & $NewfltDriveFreeSpace & " GB")
_checks()
WinSetTitle($a[$i][1], "", $NewFreeRam)
ControlSetText($a[$i][1], "", "", $NewFreeRam)
_GUIToolTip_Update($a[$i][1])
$sPreviousFreeRam = $NewFreeRam
EndIf
EndIf
Next
; Sleep(10)
WEnd
EndFunc ;==>ManageTrayIcon
Func _checks()
$warntext = "" ;es gibt keine warnung(en)
;oder doch?!
;RAM LEVEL
If ($NewFreeRam <= $LowRam) Then
$warntext &= "RAM wird knapp" & @CRLF
EndIf
;SPACE Level
If $NewfltDriveFreeSpace < $fltDriveLowSpace Then
$warntext &= "Speicherplatz auf dem SystemDrive wird knapp" & @CRLF
EndIf
;Charge Level
If $NewBatState <= $ChargeLow And ($conDat = 0) Then
$warntext &= "Batterie wird knapp, bitte laden!!!" & @CRLF
EndIf
;Last Level
If $NewProcLoad > $ProcLoadHi Then
$warntext &= "Sehr hohe Prozessor Auslastung!!!" & @CRLF
EndIf
If $warntext <> "" Then
StringReplace($warntext, @CRLF, @CRLF) ;gibt in @extended die Anzahl der Zeilen zurück
SplashTextOn("Splash", $warntext, 450, 15+30 * @extended, 1400, 1000, 1, "Verdana",12)
Sleep(5000)
SplashOff()
EndIf
EndFunc ;==>_checks
Func _BatteryStatus()
$aData = _WinAPI_GetSystemPowerStatus() ; Array mit Batterie Werten einlesen
$ChargeDat = $aData[2]
Return $ChargeDat
EndFunc ;==>_BatteryStatus
Func _AcCON()
$bData = _WinAPI_GetSystemPowerStatus() ; Array mit Batterie Werten einlesen
$conDat = $aData[0]
If $conDat = 0 Then
$ConDatR = "Kein Netzteil"
Else
$ConDatR = "Netzteil angeschlossen"
EndIf
Return $ConDatR
EndFunc ;==>_AcCON
Func GetFreeRam() ; verfügbarern RAM ermitteln
$aMemStats = MemGetStats()
Return Round($aMemStats[$MEM_AVAILPHYSRAM] / 1024 / 1024, 2)
EndFunc ;==>GetFreeRam
Func GetDriveFreeSpace($strDrive)
Return Round((DriveSpaceFree($strDrive) / 1024), 1)
EndFunc ;==>GetDriveFreeSpace
Func GetCPUavg()
Local $objWMIService, $objProcessList, $objProcess, $iLoad
$iLoad = 0
$objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
$objProcessList = $objWMIService.ExecQuery("SELECT * FROM Win32_Processor")
For $objProcess In $objProcessList
$iLoad = $iLoad + $objProcess.LoadPercentage
Next
Return $iLoad
EndFunc ;==>GetCPUavg
Alles anzeigen
Allerdings ist deine While Schleife nicht gerade CPU freundlich 😔 . Du solltest bei $a = WinList("[CLASS:tooltips_class32]") darauf prüfen, ob du überhaupt ein Array zurück bekommst und falls nicht irgendetwas tun (aus der Schleife springen etc.).
Nein. Wenn $a kein Array ist, dann gibts auch kein Ubound und die Schleife endet.
Denn ansonsten läuft dein Skript ohne Auswertung (von RAM, Batterie etc.) einfach weiter und dann bekommst du auch kein Splash Text angezeigt.
Das ist doch Sinn und Zweck! Nur wenn das TrayFenster sichtbar ist, wird der Splashtext angezeigt!
Hi,
für "richtiges" SFTP (zugriff über SSH) würde ich an deiner Stelle erstmal abklären, ob der Provider überhaupt Zugriff per SSH zulässt!
Viele FTP-Hoster bieten das erst im erweiterten Modus kostenpflichtig an.
Weiterhin benötigst du dafür auch SFTP in AutoIt, du benutzt aber die "Standard" FTP-Funktionen. Es gibt eine SFTP-UDF.
Ich würde zuerst per CMD als Administrator versuchen per SFTP-Befehl eine Verbindung mit dem Host herzustellen, wenn das klappt, versuche die SFTP-UDF.
Ansonsten leg mal einen Testuser auf deinem FTP-Account mit einer Beispieldatei zum Download an und stelle hier die Login-Daten zur Verfügung.
Es gibt so viele Adaptionen des Agile/Scrum-Manifests, dass es unweigerlich zu Problemen bei dem einen oder anderen Team kommen muss.
Du weißt ja, wie man TEAM definiert?! Tu´s Ein Anderer Mal!
Dies ist absolut hilfreich für INI-Unerfahrene
Ich hatte, auch hier im Forum, schon reichlich Scripte gesehen, bei denen INI-Dateien (falsch, die AutoIt´schen INI-Funktionen) missbraucht wurden, weil die Scripter schlicht nicht in der Lage sind/waren einfachste Textdateien zu bearbeiten bzw. die String-Bearbeitungsfunktionen zu benutzen.
Da werden/wurden dann die INI-Funktionen als FileWrite() bzw. FileRead()-Ersatz genutzt. Mir dreht sich da der Magen um...aber wenn es funktioniert...
Ja, pack die letzte Zeile und auch den restlichen Text der notifications einfach in Variablen:
$Notification_Text=$Fileversion & @crlf & $Vendor & @crlf & $Model & blablub
#include <AutoItConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Form1", 616, 300, 610, 151)
$Edit1 = GUICtrlCreateEdit("", 40, 32, 553, 250, $ES_READONLY)
GUICtrlSetData(-1, "")
GUICtrlSetFont(-1, 12, 800, 0, "Arial")
GUISetState()
DllCall("user32.dll", "int", "HideCaret", "int", 0)
$Label1 = GUICtrlCreateLabel("Im Eingabe Feld sollte ein Balken kreiseln...", 40, 8, 208, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Global $i = 0, $n
Global $bExitLoop = False ; Abbruchbedingung damit die While Wend schleife in _Balken beendet werden kann
Global $hint_text = "please be patient until preparations are done... "
Global $Notifications = "Fileversion: bla" & @CRLF & "Vendor: blub" & @CRLF & "Model: tralala" & @CRLF & "Device: hoppsassa " & @CRLF & @CRLF
;_Balken()
Opt("GUIOnEventMode", 1) ;für das Beispiel
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit", $Form1_1)
While 1
;~ $nMsg = GUIGetMsg()
;~ Switch $nMsg
;~ Case $GUI_EVENT_CLOSE
;~ Exit
;~ EndSwitch
_blablub()
;programmablauf
For $r = 1 To 5
ConsoleWrite("Programmablauf....Schritt: " & $r & @CRLF)
Sleep(500)
Next
WEnd
Func _Balken()
;~ ### Auflistung der Zeichencodes für $n ###
;~ "|" ;124 Unicode = 02502
;~ "/" ;47 Unicode = 02571
;~ "-" ;45, long 151 Unicode = 02500
;~ "\" ;92 Unicode = 02572
;~ ### END Liste ###
$i = $i + 1
Switch $i
Case $i = 1
$n = 0x2502
Case $i = 2
$n = 0x2571
Case $i = 3
$n = 0x2500
Case $i = 4
$n = 0x2572
Case $i > 4
$i = 1
EndSwitch
GUICtrlSetData($Edit1, $Notifications & @CRLF & $hint_text & ChrW($n))
EndFunc ;==>_Balken
Func _blablub()
ConsoleWrite("innerhalb _blablub" & @CRLF)
;bla=run(blub....)
$i = 0 ;globaler Zähler
AdlibRegister("_Balken", 300)
;auswertung
Sleep(3000) ;hier läuft dein Code, alle 300ms wird _Balken aufgerufen
;
AdlibUnRegister("_Balken")
GUICtrlSetData($Edit1, $Notifications & @CRLF & "Preparations DONE!")
Sleep(1000)
ConsoleWrite("Ende _blablub" & @CRLF)
EndFunc ;==>_blablub
Func _Exit()
Exit
EndFunc ;==>_Exit
Alles anzeigen
Wenn du weitere Infos nacheinander anzeigen willst, dann musst du nur die Variable $Notifications entsprechend erweitern mit zusätzlichem Text
Ich nutze INI´s u.a. um in Programmen die komplette Lokalisierung einzustellen, ohne dafür den Programmcode ändern zu müssen.
Dabei gibt es in der INI u.a. Abschnitte, welche die komplette Beschriftung der Buttons, Menüs, Labels, Hilfetexte usw. enthalten.
Die Sprachauswahl erfolgt über das Traymenü des Programms, welches sich (ohne Programmneustart) aktualisiert, sobald es per Rechtsklick aufgerufen wird.
Wir setzen im Unternehmen in der Produktion auch Leiharbeiter ein, die dazu auch noch oft als "Springer" an den verschiedensten Arbeitsplätzen aktiv sind. Diese Mitarbeiter kommen aus allen möglichen Ländern und haben entsprechend ihre eigene (Mutter-)Sprache. Viele sprechen deutsch, bei den Fachbegriffen ist es dann aber schwierig.
Meine Erfahrung hat gezeigt, dass es bei der Einarbeitung wesentlich einfacher ist, dem Mitarbeiter in seiner Muttersprache einen Vorgang/Begriff deutlich zu machen.
Um eine "neue" Sprache in der INI anzulegen, wird der deutschsprachige Bereich der Lokalisierung kopiert und in die neue Sprache übersetzt. Sobald die INI gespeichert wurde, ist die neue "Sprache" auf allen Rechnern im Netz ohne Programmneustart per Rechtsklick im Tray verfügbar.
Dieses Verfahren setze ich nicht nur in AutoIt ein, sondern auch in VBA. Da VBA so etwas wie #include nicht kennt, benutze ich Textdateien in verschiedensten Bereichen.
Der mMn. positivste Nebeneffekt dabei ist, dass man sich als Programmierer Gedanken macht, warum und ob bestimmte Programminteraktionen überhaupt nötig sind und wie man diese dann eliminieren kann. Das führt zu WESENTLICH geringerer Fehlerquote und einem schnelleren Arbeitsablauf.
Das fließt natürlich auch in meine Neuprogrammierung ein, was seitens externer Programmierer, die bei uns ab und zu reinschauen (und sich anfangs über meine, als "Nebenbeiprogrammierer" benutzte "oldschool"-Programmierung lustig machten), schon zu reichlich Überraschungen gesorgt hat.
Mich hatte einmal der Geschäftsführer einer Branchensoftware in Begleitung seiner TOP 5 Programmierer gefragt, wieso ich (mittels AutoIt) einige neue Buttons in SEINE Software eingefügt hatte.
Daraufhin fragte ich ihn, welcher seiner Mitarbeite JEMALS mit SEINER Software konstruktiv gearbeitet hatte! Unverständnis pur^^. Daraufhin hatte ich in SEINER Software demonstriert, dass es 19 (neunzehn) Interaktionen, d.h. Tastatureingaben/Mausklicks bedarf, um den aktuell bearbeiteten Vorgang als Begleitpapier auf dem Drucker auszudrucken. Das was jeder unserer 12 Mitarbeiter in diesem Bereich ca. 20x bis 30x am Tag ausführen muss. Benötigte Zeit dafür (je nach Server/Datenbank/Netzwerklast) 60-80 Sekunden. Stattdessen nur EIN Klick auf den "neuen" Button in der Buttonleiste, und 20 Sekunden später liegt das Papier im Drucker...
Einsparung pro Jahr: 0,5 Stunden pro Mitarbeiter pro Tag mal 12 Mitarbeiter mal 200 Arbeitstage im Jahr sind 1200 Stunden aka 30 Mann-Wochen pro Jahr! Das ist fast ein kompletter Mitarbeiter, dessen Ressourcen freigeschaufelt werden konnten, so dass er "wichtige" Aufgaben erledigen kann!
Daraufhin meine Frage an die anwesenden "Profis": Wieso muss ich als Anwender mir Gedanken über die Optimierung bzw. den Ablauf einer Software machen und warum wird das nicht von vornherein von den Programmierern erledigt?!
Statt sich weltweit auf SCRUM-Events rumzutreiben und sich mit "agiler" Softwareentwicklung selbstzubeweihräuchern, sollten sich Programmierer doch eigentlich (was einer der Grundsätze der Agilität ist!) um die Kundenwünsche/anforderungen und deren unkomplizierte Umsetzung als Ziel einer Softwareentwicklung kümmern?!
Etliche Vorgänge könn(t)en durch einfachste Mittel verbessert werden, gut gemachte INI-Dateien sind die Grundlage für gute Programme mit unterschiedlichsten, ggf. sogar vom Anwender steuerbaren, Konfigurationen.
Und zum Thema INI sei "oldschool" (heutzutage fliegt ja alles in eine Datenbank). Wenn mein Programm nicht per se schon eine Datenbankanwendung ist/hat, dann sollte man für einige Handvoll Parameter nicht unbedingt eine anlegen....
Nutzer, der Anwendung (wie Dritte, Außenstehende (Stakeholder bspw.)), kennen sich mit dem Programm und dessen Code nicht aus, wollen jedoch dennoch etwas am Programm beeinflussen/ändern.
Dies wäre eine Verwendung von Konfigurationsdateien, wie einer INI.
Eine weitere Verwendung ist ein Deployment der Anwendung auf verschiedene Server/Maschinen mit verschiedenen Konfigurationen.
THIS!
Ich habe mich dafür entschieden $Transform.einstellung, oder $Transform.information zu verwenden anstatt jede einzelne Sache in eine Funktion zu wrappen. Es ist meines Erachtens nach dumm 10 Funktionen zu schreiben, wenn man die Werte sowieso direkt setzen kann. Wenn man wissen will was alles einstellbar ist muss man eben in _GDIPlus_TransformCreate nachlesen was es alles gibt und was es alles macht.
Genau so hatte ich mir das vorgestellt. So kann man auch, je nach individueller Anforderung, eigene $Transform.-Parameter/Variablen erzeugen, die dann im $Transform-"Namespace" liegen.
Ich hatte keine Ahnung, dass das nur mit den Hex-Zahlen geht. Ich probierte es mit den DEZ zahlen und da kam nur Murks.
Hexadezimal und Dezimal oder auch Binär sind nur unterschiedliche Darstellungsformen für ein- und dieselbe Zahl!
Ob du nun $n=0x2571 schreibst oder $n=9585 ist unerheblich! Leider unterstützt AutoIt nicht nativ das Binärformat, sonst könnte man diese Zahl auch als 0b10010101110001 schreiben.
In meiner Funktion Ftsstat(), würde ich gerne den Satz
"GUICtrlSetData($Edit1, "Please be patient until preparations are done...!" & @CRLF & @CRLF, 1)"
gegen Eintrag mit dem drehenden Balken austauschen.Wie gehe ich da am besten vor?
So?
#include <AutoItConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Form1", 616, 144, 610, 151)
$Edit1 = GUICtrlCreateEdit("", 40, 32, 553, 50, $ES_READONLY)
GUICtrlSetData(-1, "")
GUICtrlSetFont(-1, 12, 800, 0, "Arial")
GUISetState()
DllCall("user32.dll", "int", "HideCaret", "int", 0)
$Label1 = GUICtrlCreateLabel("Im Eingabe Feld sollte ein Balken kreiseln...", 40, 8, 208, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Global $i = 0,$n
Global $bExitLoop = False ; Abbruchbedingung damit die While Wend schleife in _Balken beendet werden kann
_Balken()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
_blablub()
;programmablauf
for $r=1 to 5
consolewrite("Programmablauf....Schritt: "&$r&@crlf)
sleep(500)
Next
WEnd
Func _Balken()
;~ ### Auflistung der Zeichencodes für $n ###
;~ "|" ;124 Unicode = 02502
;~ "/" ;47 Unicode = 02571
;~ "-" ;45, long 151 Unicode = 02500
;~ "\" ;92 Unicode = 02572
;~ ### END Liste ###
$i = $i + 1
Switch $i
Case $i = 1
$n = 0x2502
Case $i = 2
$n = 0x2571
Case $i = 3
$n = 0x2500
Case $i = 4
$n = 0x2572
Case $i > 4
$i = 1
EndSwitch
GUICtrlSetData($Edit1, "please be patient until preparations are done... " & Chrw($n))
EndFunc ;==>_Balken
func _blablub()
consolewrite("innerhalb _blablub"&@crlf)
;bla=run(blub....)
$i=0 ;globaler Zähler
Adlibregister("_Balken",300)
;auswertung
Sleep(3000) ;hier läuft dein Code, alle 300ms wird _Balken aufgerufen
;
Adlibunregister("_Balken")
GUICtrlSetData($Edit1, "DONE!")
sleep(1000)
consolewrite("Ende _blablub"&@crlf)
endfunc
Alles anzeigen
Sehr schön!
Ich würde aber noch, innerhalb von $Transform, sämtliche Ergebnisse der Funktion _WinAPI_Mouse_Event() und/oder GUIGetCursorInfo() dem User zur Verfügung stellen.
Dann stehen sämtliche mausspezifischen Events bzw. deren Ergebnisse, in einer Variablen ($Transform)
aber ich will erstmal schauen was man ohne diese Hilfsmittel rausholen kann.
Hatte ich oben ja bereits beschrieben....gesetzt den Fall, du optimierst die Schleifen auf die Hälfte der Zeit, das GDI-Gedöns beschleunigst du nicht. Da werden dann aus 4 FPS wegen mir 8 FPS...?!
Allerdings ist JEDE Optimierung im noch so langsamen Code eine Verbesserung in der Ablaufgeschwindigkeit, und schlägt somit voll auch bei einer ggf. compilierten Variante durch!
Wenn du deinen Code "schnell" machst, dann ist auch das Programm "schnell", SO zum Beispiel...
Ein paar inner loops sind doof gelöst weil dort eigentlich nur der Mittelpunkt berechnet wird (z.B. in EndEscene -> Mittelpunkte berechnen & Sortieren), das kann man doppelt so schnell anderweitig lösen, oder 5x so schnell approximativ^^
...was aber (im Bezug auf AutoIt! )den Kohl auch nicht wirklich fett macht^^
Und DANN baue ich einen "richtigen" Kugelgenerator (mit GUI und ganz vielen Slidern, sodass man nicht mehr von Hand im Code arbeiten muss wenn man seine Kugel designen will).
Mach das doch mal zuerst! Ich vermute, auf dem Weg dahin findet sich die eine oder andere Verbesserung ganz automatisch ein, weiterhin findet sich bestimmt jemand (sic), der für die Berechnungen hochperformanten SSE/AVX-Code (dafür gibts in C(++) die intrinsics(!) ) basteln könnte....ich mein ja nur....
verweigert Autoit die Aufgabe ohne Meldung.
Du kannst nach der _ScreenCapture_Capture()- Zeile auf @error prüfen, um den Grund zu erfahren.
Die Fehler sind in der Help-Datei nicht beschrieben, erschließen sich aber mit Blick in die Funktion(en). In Scite den Cursor auf den Funktionsnamen und dann CTRL-J springt in diese Funktion.
Neben den von Musashi und Moombas beschriebenen Syntaxfehlern ist darauf zu achten, dass in dem ausgewählten Verzeichnis Schreibrechte bestehen!
Zunächst einmal Mars....sehr schön!
Wieder ein Mitglied im Bereich "Brotlose Kunst" ( für die Insider )
GDI+ wird leider das Speed Limit bleiben...
Das ist sicher richtig.... aber:
Wie so oft, sind die Berechnungen innerhalb der Schleifen der Geschwindigkeitstechnische "Supergau" bei AutoIt.
Profiling des Scriptes hat bei mir (4 FPS) ergeben:
- In der While-Schleife liegen die Zeiten der Zeilen bis zu Draw($Sphere) bei je 1ms, also (zunächst) unerheblich.
- Draw($Sphere) bzw. die eigentliche Funktion __A3D_GeometryDraw() dauert 150ms, davon ca. 30ms in der ersten For/Next, bei der ausschließlich bissl addiert und subtrahiert wird.
Die anderen 120ms werden in der zweiten For/Next "verbraten" in der, man mag es kaum glauben, auch nur bissl addiert wird. In der Summe mit den kaskadierenden OR´s je CASE ist das für einen Interpreter der schon angesprochene Supergau...
- In der Funktion _A3D_EndScene() dauert die erste verschachtelte For/Next 85ms, bei der ausschließlich bissl addiert und dividiert wird.
In der zweiten For/Next (mit den CASE) werden in 60ms ca.1900 Schleifendurchgänge mit jeweils ZWEI GDI(+)-Funktionen aufgerufen. Also SO schlecht ist da GDI nicht!!
Zusammengefasst:
Das was das Script so "langsam" macht, sind (wie so oft) die Berechnungen innerhalb der Schleifen.
Es lohnt sich also definitiv, diese Berechnungen auszulagern, bspw. in eine DLL.
Ich reite jetzt bestimmt nicht wieder auf Assembler rum ( Mars bekäme das sicher auch mit AVE/SSE unter Ausreizung aller vom Prozessor verfügbaren Möglichkeiten incl. Multithreating (das auch in AutoIt!) hin), aber jeder beliebige Compiler schafft die Berechnungen heutzutage mit mindestens dem Faktor 1000 schneller! UEZ würde da FreeBasic nutzen!
Also mal angenommen, die o.g. Berechnungs-Schleifen würden in Summe je 1ms brauchen (also vernachlässigbar), dann bleiben je Haupt-Schleifendurchlauf die 60ms für die 3800 GDI-Funktions-Aufrufe. Ob DAS ein Compiler auch nur Faktor 5-10 schneller macht, wage ich zu bezweifeln! Aber Versuch macht kluch!
Letztendlich führen die in einen Assembler/Compiler ausgelagerten Berechnungs-Funktionen zu einer Beschleunigung des Scripts um ca. Faktor 3-4, bei mir würden da doch ansprechende 15FPS rauskommen. Und zwar UNABHÄNGIG von der Anzahl der Polygone!
Das Script komplett 1:1 in FreeBasic umgesetzt schätze ich mal erreichbare 25-30FPS mit GDI(+). Die Verwendung von D3D wäre allerdings, abhhängig von der Grafikkarte, unendlich viel schneller....
Fazit:
Die "brotlose Kunst" ist LEIDER nicht die Stärke von AutoIt, um aber mal fix bissl Grafikgedöns hinzuzaubern, immer gut .
Daher
Wie water schon anmerkte, ist Scriptomatic das Tool der Wahl! Dann passiert
leider zeigt er mir nur den ersten gefundenen Eintrah sn mit
das auch nicht....
Ich hatte in Scriptomatic noch einen Filter(button) integriert, damit man nicht ellenlang durch die Liste scrollen muss.
Übrigens kann man auch, nachdem man auf den Pfeil im rechten Dropdown geklickt hat und die Liste sieht, ein Leerzeichen eingeben und es wird ein "leeres" Abfragengerüst erstellt! Die (SQL)Abfrage muss dann nur noch ergänzt werden...
Die erstellten Abfragescripte sind natürlich ohne Scriptomatic lauffähig, sie befinden sich als Datei im TEMP-Ordner und werden von Scriptomatic nach deren Ausführung gelöscht.
Um weitere Ideen in bestehende Scripte einfließen zu lassen und diese umzuschreiben und auf eigene/andere Bedürfnisse anzupassen, dafür ist ja ein Forum bzw. die Community da!
Auch BugFix hat sich mit dem Thema beschäftigt!
Man muss also nicht (auch wenn es ab und zu Spass macht^^) das Rad neu erfinden!
auch 'ne Möglichkeit 👍 . Kannte ich noch nicht und führt sicherlich zum gleichem Ziel. Ist für mich persönlich nicht relevant, da ich seit Jahren nur noch mit VSCode arbeite und nicht mit Scite, dennoch Danke für die Ergänzung 🤝 .
Würde mich SEHR stark wundern, wenn ein x-beliebiger Editor (der seinen Namen verdient) das nicht seit Jahren könnte...
Es soll sogar Editoren geben, welche "intelligent" Backups anlegen (können) Wobei ich mich jetzt frage, wieso Scite das nicht kann...
Ein Werkzeug ist eben nur so gut wie die Aufgabe die dazu passt .Aber das gehört in den anderen aktuellen Thread
Kurz: Wir interessieren uns für Lösungen des eigentlichen Problems - nicht für Workarounds.
So ist das...
Wenn durch eine Methodenänderung/Umstrukturierung/Umprogrammierung der Faktor 2 erreicht werden kann, dann wird mir als hauptberuflicher Optimierer schon warm ums Herz
Die Frage ist, ob der Dev davon wissen will, und ob er Problem- oder Lösungsorientiert arbeitet!? Ich jedenfalls bin immer froh, wenn ich Rückmeldung erhalte wenn etwas NICHT funktioniert, bzw. jemand eine gute oder bessere (als meine) Idee hat. Nur so kann man sich und den Ablauf verbessern. Das übliche ist aber, wenn problemorientierte Leute dann ein riesen Fass aufmachen, um von einem Ablauf, der bei 95% Erfolgsquote läuft, noch 0,2% "MEHR" rauszuholen....wobei eigentlich jeder wissen sollte dass es immer schwieriger wird, einen bereits optimierten Prozess weiter zu verbessern. Wenn überproportional viel Ressourcen, Manpower und Equipment benötigt wird, dann lohnt der Aufwand einfach nicht.
Ich bin da pragmatisch: funktioniert, ist schnell, einfach und gut umzusetzen--->MACHEN! Ansonsten ans Ende der Prioritätenliste
Das Problem mit den Array-Indizes ist ein klares Beispiel für den Fall, dass die Software weit entfernt ist von einer möglichst optimalen Ausnutzung der vorhandenen Hardwareleistung.
Das gilt nicht nur für die Array-Indizes! Wobei ich ganz klar sagen muss, dass AutoIt, obwohl seit Jahren nicht mehr "weiterentwickelt" (ich rede nicht von dem immer mal implementierten Spielkram, siehe Thema ^^) wurde, ziemlich gut und "relativ" bugfrei läuft. "Richtige" Bugs habe ich jedenfalls schon seit Jahren nicht mehr gemeldet....und den Rest spare ich mir, um meine Nerven zu schonen
Ist aber nur eine Vermutung - in die inneren Abläufe können wir ja leider nicht reinschauen.
Hehe....ob ich das überhaupt will?! Nicht vorzustellen was passieren würde, sollte jemand sich näher damit befassen und entsprechend "atemberaubende" Änderungen aufzeigen....mimimimimi....
Die Devs haben dazu damals gesagt, dass das eben so ist weil es intern aus irgendwelchen Gründen so gemacht wird.
Naja, dann ist das eben so^^....genau wie das kopieren von (Text-) Variableninhalten bei sämtlichen "internen" Funktionen. Leg mal einen mehrere hundert MB großen Text an und lass auf diesen dann die durchaus schnellen Text/Stringfunktionen los und beobachte die Speicherauslastung....dabei hatte ich festgestellt, dass die Ausführungsgeschwindigkeit der Funktionen teilweise höher ist als die Zeit, den Speicherbereich zu kopieren...auch so kann man ein Programm "verlangsamen"
Was logisch erscheint, sind doch die "blauen" aka internen Funktionen nichts weiter als gewrapperte C(++)-Funktionen aus den standardisierten Bibliotheken. Da erfindet niemand das Rad neu! Die Laufzeit "innerhalb" der Funktion ist also identisch mit der eines kompilierten Programms!
Was die Zeit frisst, ist der "selbstgestrickte" Overhead. Und mit Sicherheit die Art und Weise der Programmierung. Ja, was mir schon vor beinahe 40 Jahren Ärger mit HP einbrachte, als ich denen als "dummer" Maschinenbaustudent einen Auftrag von mehreren hunderttausend DM versaute, weil ich einen Grafiktreiber eines CAD-Systems (damals ME30) umgeschrieben und so um mehrere Faktoren beschleunigt hatte. So bestand für die Hochschule auch kein Grund, die "neuen" (und schnelleren) Systeme zu kaufen. Damals war ich noch stolz darauf, bis ich bei der folgenden CBIT hochkant vom HP-Messestand flog, mit Geleitschutz wie ein Schwerverbrecher....
Was musste ich auch die Schnauze aufreißen und sagen, dass ein langsames und "schlechtes" Programm auch nicht schneller und besser wird, wenn man es durch einen "neuen" C-Compiler jagt....Es führt den "schlechten" Code nur schneller aus^^
Für Arrays gilt: Lesender Zugriff -> Index wird 1x evaluiert, Schreibender Zugriff -> Index wird 2x evaluiert (glaube ich).
Wenn dann noch, wie bei den Strings, die Variablen aka der komplette Array-Speicherbereich vor jeder Operation kopiert werden, dann braucht man sich nicht wundern...ByRef ftw!
Bzgl. "was der Unterschied zu gestern ist" kann ich nur zu GIT bei deinem Projekt raten.
Scite speichert *.bak-files in beliebiger Iterationstiefe ab, einstellbar in Scite-Config (CTRL-1) auf dem ersten Reiter (Backup Strategy)!
Racer, das ist doch ein wirklich schönes, kleines, strukturiertes Programm, und du willst mir allen Ernstes erzählen, dass du nicht innerhalb weniger Minuten mit DEBUG-MESSAGEBOXEN (Scite CTRL-SHIFT-D) die Zeile mit dem declare-Fehler findest?
Was ich anhand deiner Variablennamen eher vermute, ist ein Fehler beim Aufruf einer Unterfunktion, ggf. auch in einer der UDF, bei der dieser Variablenname gelöscht bzw. mit anderem Typ (array?!) besetzt wird.
Leider gibt es in Scite im Tools-Menü kein "Add Tracelines" welche Messageboxen statt Konsolenausgaben verwenden.
Dann musst du diese Debug-Messageboxen per CTRL_SHIFT_D von Hand setzen
Da ja die GUI angezeigt wird und erst danach die Fehlermeldung kommt, habe ich an an verschiedenen Stellen im Script ein "exit" eingebaut um zu sehen wie weit es läuft. Auch das hat mich nicht wirklich weiter gebracht.
Wieso? Du kennst doch den Ablauf in deinem Programm am besten?! Setze Debug-Zeilen jeweils vor und hinter die Funktionsaufrufe, wenn du die Funktion die den Fehler wirft dann lokalisiert hast, machst du das Prozedere innerhalb der Funktion weiter....so lange, bis vor der "fehlerhaften" Zeile im Code eine Messagebox erscheint, und wenn du diese dann wegklickst, die Fehlermeldung.
Btw könntest du auch die Tracelines verwenden und im Script dann global alle "Consolewrite" mit einer eigenen (Log-)Funktion ersetzen, die statt die Zeile in die Konsole in eine Datei schreibt. Dann hast du in der letzten Zeile der log-Datei deinen Fehler