Beiträge von chesstiger
-
-
Noch zur Vollständigkeit:
Dass es keine dateispezifischen Scopes geben kann, wird schnell klar, wenn man überlegt, was bspw. eine Anweisung wie "#include" ist.
Man nennt diesen Typ von Anweisungen auch Präprozessoranweisungen. Was ist das? Ein Präprozessor ist ein Programm, was den Code durchgeht und genau diese Anweisungen ausführt/auswertet, BEVOR alles dann an den Interpreter/Compiler übergeben wird. Das heißt im Falle von Include also, dass der Präprozessor diese Anweisung erkennt, dann die dort angegebene Datei einliest und deren Inhalt anstelle der Include-Anweisung in das Skript einfügt. Diese Anweisung ist nebenbei an den C-Präprozessor angelehnt. Jedenfalls sieht der Interpreter/Compiler später gar nicht mehr, dass das eigentlich mal zwei (drei, vier, N) Dateien waren. Daher kann er auch nachher nicht mehr den Zugriff auf eine Variable verbieten, die nur in einer Datei vorkommt.
-
Das Problem ist recht trivial:
GUICtrlSetBkColor akzeptiert zwei Parameter:
1. Die Control-ID des Controls oder -1 für das zuletzt erstellte Control.
2. Die zu setzende Farbe.
Du hast lediglich die Parameter vertauscht, die entsprechende Zeile muss GUICtrlSetBkColor(-1, 0xF0F0F0) lauten.
-
Hi,
bei uns in der Firma laufen diverse Tools aus meiner Hand, die teilweise als Hauptaufgabe, teilweise als Nebenaufgabe auch etliche verschiedene Berichte in Dokumentenform erzeugen. Nach viel Rumprobieren bin ich bei HTML und wkhtmltopdf gelandet. Somit geben alle meine Tools schöne PDF-Dateien aus, die der Benutzer dann entweder drucken oder per Mail direkt an andere Mitarbeiter oder sogar Kunden schicken kann. Meistens lasse ich die dann einfach nach der Erzeugung mit ShellExecute mit dem Default-PDF-Reader öffnen und gut ist.
-
Das Pattern ist korrekt. Ich nutze zur "Entwicklung" von regulären Ausdrücken fast immer regex101.com. Da muss nichts escaped werden. Für die Verwendung mit AutoIt muss dann entweder das Apostroph oder die Gänsefüßchen maskiert werden, bspw. so:
Hatte ich jetzt gerade beim Posten nicht drüber nachgedacht.

-
Die Flinte nicht so schnell ins Korn werfen. RegEx kann ziemlich viel.

Das Pattern ist jetzt zwar etwas ausgeartet, aber es funktioniert einwandfrei. Zumindest habe ich nichts gefunden, was falsch gematcht wird.
Das ist dann jetzt wie angekündigt eine doppelte Rekursion mit Backreference Match.
Sogar das hier wird korrekt gematcht:
-
Mit ein bisschen RegEx-Magie kann man auch das Nesting abbilden.

Ich habe mal alpines' Pattern als Basis genommen. Würde allerdings statt \s definitiv \h bevorzugen. Vertikale Whitespaces sind an diesen Stellen nämlich nicht zulässig.
Pattern:
Ergebnis:
Code
Alles anzeigen- 0 StringRegExpReplace : '_CloseInputGUI(_Test(), _Test ( ) )' > 0 StringRegExp : '_CloseInputGUI(_Test(), _Test ( ) )' - 1 StringRegExpReplace : '_SciTE_ShowFuncName()' > 1 StringRegExp : '_SciTE_ShowFuncName()' - 2 StringRegExpReplace : '_SciTE_ShowFuncName ( )' > 2 StringRegExp : '_SciTE_ShowFuncName ( )' - 3 StringRegExpReplace : '_SciTE_ShowFuncName (";")' > 3 StringRegExp : '_SciTE_ShowFuncName (";")' - 4 StringRegExpReplace : '_SciTE_ShowFuncName (";")' > 4 StringRegExp : '_SciTE_ShowFuncName (";")' - 5 StringRegExpReplace : '_SciTE_ShowFuncName (";")' > 5 StringRegExp : '_SciTE_ShowFuncName (";")' - 6 StringRegExpReplace : '_SciTE_ShowFuncName()' > 6 StringRegExp : '_SciTE_ShowFuncName()' - 7 StringRegExpReplace : '_SciTE_ShowFuncName(1)' > 7 StringRegExp : '_SciTE_ShowFuncName(1)' - 8 StringRegExpReplace : '_SciTE_ShowFuncName()' > 8 StringRegExp : '_SciTE_ShowFuncName()' - 9 StringRegExpReplace : '_SciTE_ShowFuncName(_AddComment(";" & $aComment[Random(0, 1, 1)]))' > 9 StringRegExp : '_SciTE_ShowFuncName(_AddComment(";" & $aComment[Random(0, 1, 1)]))'Aber ganz unrecht hat alpines trotzdem nicht. An gewissen Stellen geht auch das "kaputt". Man füge mal zu dem Test-Skript folgendes hinzu: _Strip(10, 'Func _SciTE_ShowFuncName("Das hier ist böse. ;)")')...
Das könnte man eventuell mit einer Art Doppel-Rekursion lösen (außen Klammern, innen Anführungszeichen). Wobei bei den Anführungszeichen dann wieder eine Backreference nötig wäre, um " und ' gerecht zu werden. Da wäre es fast einfacher, vorher alle Strings rauszuparsen.
-
Hiho,
in der letzten Woche ist bei mir aus einem beruflichen Bedürfnis heraus eine kleine Software entstanden.
Schon seit etlichen Jahren arbeiten wir mit einem eigenen Folienplotter zwecks Beschriftung mit dem Schwerpunkt Fahrzeuge. Vor kurzem ist dann noch eine Textilpresse (Beschriftung von Kleidungsstücken) sowie ein HP-Latex-Drucker hinzugekommen, sodass wir mittlerweile mit diversen Werbetechnik-Unternehmen mithalten können, obwohl dies nicht unser Schwerpunkt ist. Früher hat das alles mein Vater nebenbei gemacht, mittlerweile bin ich eher dafür zuständig.
Oftmals sind die Kunden am Design-Prozess beteiligt. Mir ist aufgefallen, dass eines der größten Probleme beim Entwurf das Finden der richtigen Schriftart ist. Teilweise kommt dann als Auftrag auch nur so eine Aussag wie "Ja, der Schriftzug 'Dorfjugend Blabla' auf den Rücken bitte", ohne Angabe einer Schriftart. Auf der einen Seite kann man sich dann natürlich kreativ austoben, aber meistens endet das in einem ewigen Hin- und Her. Und selbst beim kreativen Austoben ist es eine große Hilfe, einfach mal alle Möglichkeiten vor sich zu sehen.
Daher habe ich mir ein kleines Skript gebastelt, welches einen beliebigen Schriftzug in allen installierten Schriftarten in einer beliebigen Größe darstellt. Auf Wunsch kann das Ergebnis dann als PDF exportiert werden, um es dem Kunden bspw. per Mail zukommen zu lassen. Die ersten beiden Kunden, mit denen ich das getestet habe, haben schon gezeigt, dass die Idee goldrichtig war.

Auf technischer Seite ist das insgesamt der dritte Versuch. Der erste war ein ListView mit OWNERDRAW, der zweite mehrere Labels in einer Child GUI mit Scroll-UDF. Das war beides - gelinde gesagt - Mist. Die Lösung über ein Embedded IE ist wesentlich einfacher und eleganter. Außerdem ist so der PDF-Export (über wkhtmltopdf) ziemlich leicht realisierbar gewesen. Erwähnenswert ist noch, dass ich mein eigenes Projekt (SynSug - Syntaktischer Zucker für AutoIt (Update v1.1.0 Dictionaries)) zur Umsetzung genutzt habe, konkret für die mehrzeiligen Strings in NowDoc/HereDoc-Syntax. Im angehängten ZIP-Archiv finden sich daher zwei Au3-Dateien, einmal mit "Syntactic Sugar" und einmal in purem AutoIt. Die wkhtmltopdf.exe muss bei Nutzung der Export-Funktion selber unter https://wkhtmltopdf.org/downloads.html heruntergeladen werden, da sie mit knapp 40 MB jedes Limit hier im Forum übersteigt.
Nun, das war's eigentlich schon. Vielleicht kann ja außer mir noch jemand was damit anfangen.

Denkbar wäre in Zukunft noch, dass man noch mehr CSS-Schrifteinstellungen einstellbar macht, um z.B. den Zeichenabstand zu verändern oder andere Schrifteffekte umzusetzen.
-
Witzig, dass du das fragst. Ich habe in letzter Zeit auch versucht, in einer AutoIt-GUI eine sehr bunt formatierte Tabelle unterzubekommen. Bei mir war der konkrete Anwendungszweck, einen Schriftzug in wählbarer Größe in allen vorhandenen Schriftarten darzustellen.
Selbst bei maximaler Fenstergröße benötigt dieser Anwendungszweck eine Art Scroll-Mechanismus. Ich habe insgesamt vier Ansätze gehabt:
1. ListView-UDF mit OwnerDraw.
2. RichEdit-UDF mit ES_READONLY.
3. Native Labels auf Child-GUI mit Scrollbar-UDF.
4. Embedded IE.
Die im Endeffekt simpelste Methode für deinen Anwendungszweck wird vermutlich der Embedded IE sein. Einfacher als per HTML/CSS kriegst du die Tabelle nicht hin.
Performanter wären ListView und Label, allerdings beide deutlich aufwendiger zu implementieren. ListView ginge vermutlich noch einfacher, man kann in der Ownerdraw-Funktion für jedes (Sub-)Item eigene Styles definieren. RichEdits zu guter letzt können mit Tabellen umgehen - aber die AutoIt-UDF sieht dies nicht vor.
-
Eine Sache ist mir noch nicht ganz klar. Du schreibst von einem webbasiertem Monitoring-System. Wenn es nicht gerade eine uralte Flash- oder Java-Webanwendung ist, wäre es doch deutlich eleganter, den Status über die IE.au3 oder noch besser per TCP/HTTP abzufragen. Mit Pixel-Farben zu hantieren ist immer irgendwie Mist und neigt zur Fehleranfälligkeit und Unzuverlässigkeit. Hast du das schon versucht?
-
You don't have permission to access /https://www.meineseite.de/61974798815668285678766617929415361842483865,merkzettel.html on this server.
Das klingt so, als würdest du in der GET-Anfrage eine komplette URL mit Server übermitteln. Das ist falsch. Du übermittelst an den Host http://www.meineseite.de die Anfrage nach /61974798815668285678766617929415361842483865,merkzettel.html. Sprich, du darfst nur einen Teil der URL angeben. Wenn ich gerade nicht völlig falsch bin.
-
Kurz mal als Blick über den Tellerrand: In diversen Programmiersprachen gibt es ganz andere Konzepte, um Fehler zu erkennen und abzufangen.
Das, was wir hier haben, ist die althergebrachte Methode, wie sie auch in purem C zum Einsatz kommt. Eine Funktion gibt "Null" (das ist ein englisches Wort) bzw. "0" zurück, was beides im Endeffekt auf den Zahlenwert 0 hinausläuft. Eine typische Fehlerüberprüfung in C sieht dann also so aus: if(myVal == NULL) { ....
Da hier zurecht Verwechslungsgefahr besteht, existiert in der Standardbibliothek noch die globale Variable errno. Eine Funktion setzt diese bei einem Fehler auf einen situationsabhängigen Zahlenwert (ungleich 0). Damit wären wir dann bei einer Fehlerabfrage a la if(errno) { .... Das kommt einem AutoIt-Programmierer jetzt vermutlich bekannt vor.
Nachtrag: Es gibt tatsächlich auch Sprachen, die schlicht NULL und 0 als unterschiedliche Werte betrachten. "0" ist bspw. eine Instanz der Klasse Integer, "NULL" ist tatsächlich 0.
Das Problem hierbei ist, dass Fehlerbehandlung optional wird. Der Programmierer kann Fehler abfangen - muss es aber nicht. Das kann aus Faulheit, aus Unwissenheit oder einfach durch Vergessen geschehen, ist aber eine sehr große Fehlerquelle. Darüber hinaus ist die Fehlerbehandlung syntaktisch auch nicht vom wirklichen Anwendungscode unterscheidbar.
In modernen Hochsprachen wird daher meist ein eigenes Sprachelement für diese Fehlerbehandlung genutzt, oftmals Exception (dtsch. Ausnahme) genannt. Dabei unterscheidet man bspw. bei Java zwischen einer checked und einer unchecked Exception. Beide haben gemein, dass sie mittels eines try-catch-Blockes abgefangen werden. Eine unchecked Exception kann ich abfangen, eine checked Exception muss ich abfangen. Im try-Bereich steht der Code, der eventuell einen Fehler auslösen könnte. Im catch-Bereich steht der Code, der den Fehler beim Auftreten behandelt. In Java sähe unser Beispiel mit Number() irgendwie so aus:
Codetry { myVal = Integer.parseInt(myString); } catch(NumberFormatException nfe) { System.out.println("Invalid Number"); }Damit ist der normale Ablauf (try) strikt vom Fehlerfall (catch) getrennt. Außerdem können Ausnahmen bei verschachtelten Aufrufen auch nach oben "durchgereicht" werden.
Sowas wäre der moderne Weg, Fehler abzufangen. Aber leeeider bietet AutoIt uns das nicht.
-
Ja, bin sehr erstaunt, dass es mit WndProc nicht (mehr) geht...
So, ich hab's gelöst. Des Rätsels Lösung liegt im GWL_USERDATA-Feld. AutoIt scheint dort Informationen zu speichern. Um den Zugriff auf globale Variablen zu vermeiden, hatte ich in meinem Minimalbeispiel die Adresse der alten WNDPROC in diesem Feld abgelegt. Ohne funktioniert's.
-
Dazu fällt mir dieser Thread hier ein:
-
Einmal die SSD, eine Samsung 850 EVO M.2:
Code
Alles anzeigenASM-Code-Size: 34 Bytes Schreibe Datei: "c:\temp\0001.ft" Zeit: 1823 ms Schreibrate: 588.9 MB/s Schreibe Datei: "c:\temp\0002.ft" Zeit: 2186 ms Schreibrate: 491.1 MB/s Schreibe Datei: "c:\temp\0003.ft" Zeit: 2281 ms Schreibrate: 470.6 MB/s Schreibe Datei: "c:\temp\0004.ft" Zeit: 3766 ms Schreibrate: 285.1 MB/sUnd einmal die Hybridplatte Seagate FireCuda 2TB über SATA (ST2000LX001):
Code
Alles anzeigenASM-Code-Size: 34 Bytes Schreibe Datei: "d:\temp\0001.ft" Zeit: 9067 ms Schreibrate: 118.4 MB/s Schreibe Datei: "d:\temp\0002.ft" Zeit: 14395 ms Schreibrate: 74.6 MB/s Schreibe Datei: "d:\temp\0003.ft" Zeit: 16070 ms Schreibrate: 66.8 MB/s Schreibe Datei: "d:\temp\0004.ft" Zeit: 18653 ms Schreibrate: 57.6 MB/sMit den verschieden komplexen Bytemustern würde mich jetzt auch interessieren.
-
Ich habe jetzt nicht weiter rumprobiert, aber es kann durchaus sein, dass du da an die Grenzen von normalen GUI-Controls kommst. Evtl. müsstest du für so schnelles Zeichnen auf GDIPlus (ö.Ä.) ausweichen.
Ich hab mal für ein Theaterstück einen Countdown bis zum Beginn programmiert. Das war aber so eine "Es geht in einer halben Stunde los, kriegen wir das noch hin?"-Aktion, daher... Keine Resourcenfreigabe oder so. Bitte so nicht produktiv verwenden!
C
Alles anzeigen#include <GDIPlus.au3> #include <WindowsConstants.au3> Global Const $PI = 3.141592654 Opt("GUIOnEventMode", True) DllCall("User32.dll","bool","SetProcessDPIAware") _GDIPlus_Startup() ;changeable $iWndW = @DesktopWidth $iWndH = @DesktopHeight ;end changeable $hWnd = GUICreate("", $iWndW, $iWndH, 0, 0, $WS_POPUP, $WS_EX_TOPMOST) GUISetOnEvent(-3, OnCloseClick) ;basic graphics $hGfx = _GDIPlus_GraphicsCreateFromHWND($hWnd) $hBmp = _GDIPlus_BitmapCreateFromGraphics($iWndW, $iWndH, $hGfx) $hBuf = _GDIPlus_ImageGetGraphicsContext($hBmp) _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) _GDIPlus_GraphicsSetSmoothingMode($hBuf, 2) ;generate watch base image $hWatchBmp = _GDIPlus_BitmapCreateFromScan0(500, 500) ;fix, resize later $hWatchGfx = _GDIPlus_ImageGetGraphicsContext($hWatchBmp) _GDIPlus_GraphicsSetSmoothingMode($hWatchGfx, 2) $hWatchPen = _GDIPlus_PenCreate(0xffffffff, 10) ;better use solid color... $hWatchBrush = _GDIPlus_BrushCreateSolid(0xffffffff) $hDotPen = _GDIPlus_PenCreate(0xffdddddd, 5) ;better use solid color... _GDIPlus_GraphicsDrawEllipse($hWatchGfx, 10, 10, 480, 480, $hWatchPen) $iInnerR = 200 $iOuterR = 240 For $i = 0 To 59 ;60 minute dots $iOuterX = 250 + Cos((2 * $PI / 60) * $i) * ($iOuterR - 20) $iOuterY = 250 + Sin((2 * $PI / 60) * $i) * ($iOuterR - 20) _GDIPlus_GraphicsDrawEllipse($hWatchGfx, $iOuterX - 2, $iOuterY - 2, 4, 4, $hDotPen) Next For $i = 0 To 11 ;12 hour lines $iInnerX = 250 + Cos((2 * $PI / 12) * $i) * $iInnerR $iInnerY = 250 + Sin((2 * $PI / 12) * $i) * $iInnerR $iOuterX = 250 + Cos((2 * $PI / 12) * $i) * $iOuterR $iOuterY = 250 + Sin((2 * $PI / 12) * $i) * $iOuterR _GDIPlus_GraphicsDrawLine($hWatchGfx, $iInnerX, $iInnerY, $iOuterX, $iOuterY, $hWatchPen) Next GUISetState() $hPenHour = _GDIPlus_PenCreate(0xffffffff, 15) $hPenMinute = _GDIPlus_PenCreate(0xffffffff, $hPenSecond = _GDIPlus_PenCreate(0xffffffff, 3) $hTimer = TimerInit() While True _GDIPlus_GraphicsClear($hBuf) ;input values $iTime = TimerDiff($hTimer) $nMilliSecond = Mod($iTime, 1000) $nSecond = Mod($iTime / (1000), 60) $nMinute = Mod($iTime / (1000 * 60), 60) $nHour = $iTime / (1000 * 60 * 60) ;draw static watch image _GDIPlus_GraphicsDrawImageRect($hBuf, $hWatchBmp, $iWndW / 2 - 250, $iWndH / 2 - 250, 500, 500) ;calculate and draw pointer $iCenterX = $iWndW / 2 $iCenterY = $iWndH / 2 $iHourX = $iCenterX + Cos((2 * $PI / 12) * Mod($nHour, 12) - ($PI / 2)) * 150 $iHourY = $iCenterY + Sin((2 * $PI / 12) * Mod($nHour, 12) - ($PI / 2)) * 150 _GDIPlus_GraphicsDrawLine($hBuf, $iCenterX, $iCenterY, $iHourX, $iHourY, $hPenHour) $iMinuteX = $iCenterX + Cos((2 * $PI / 60) * $nMinute - ($PI / 2)) * 190 $iMinuteY = $iCenterY + Sin((2 * $PI / 60) * $nMinute - ($PI / 2)) * 190 _GDIPlus_GraphicsDrawLine($hBuf, $iCenterX, $iCenterY, $iMinuteX, $iMinuteY, $hPenMinute) $iSecondX = $iCenterX + Cos((2 * $PI / 60) * $nSecond - ($PI / 2)) * 230 $iSecondY = $iCenterY + Sin((2 * $PI / 60) * $nSecond - ($PI / 2)) * 230 _GDIPlus_GraphicsDrawLine($hBuf, $iCenterX, $iCenterY, $iSecondX, $iSecondY, $hPenSecond) ;draw center circle _GDIPlus_GraphicsFillEllipse($hBuf, $iCenterX - 15, $iCenterY - 15, 30, 30, $hWatchBrush) ;draw current time in decimals $sTime = StringFormat("%02d : %02d : %02d . %03d", $nHour, $nMinute, $nSecond, $nMilliSecond) _GDIPlus_GraphicsDrawStringBox($hBuf, $sTime, 0, 0, "Segoe UI", 36, 0xffffffff, 1, $iWndW) _GDIPlus_GraphicsDrawImage($hGfx, $hBmp, 0, 0) WEnd Func OnCloseClick() Exit EndFunc Func _GDIPlus_GraphicsDrawStringBox($hGraphics, $sString, $nX, $nY, $sFont = "Arial", $nSize = 10, $iColor = 0xFF000000, $iAlignX = 0, $nW = 0.0, $iAlignY = 0, $nH = 0.0) Local $hBrush = _GDIPlus_BrushCreateSolid($iColor) Local $hFormat = _GDIPlus_StringFormatCreate(0) _GDIPlus_StringFormatSetAlign($hFormat, $iAlignX) _GDIPlus_StringFormatSetLineAlign($hFormat, $iAlignY) Local $hFamily = _GDIPlus_FontFamilyCreate($sFont) Local $hFont = _GDIPlus_FontCreate($hFamily, $nSize) Local $tLayout = _GDIPlus_RectFCreate($nX, $nY, $nW, $nH) Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat) If @error Then Return SetError(@error, @extended, 0) Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hFormat, $hBrush) Local $iError = @error, $iExtended = @extended _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) Return SetError($iError, $iExtended, $aResult) EndFunc ;==>_GDIPlus_GraphicsDrawStringBox -
Wenn du es gern komfortabler hättest... Ich habe mal Musashis Idee aufgegriffen und die Tracing-Funktion durch modifizieren des Skriptes in mein SynSug (Syntaktischer Zucker für AutoIt) integriert. Daher kannst du jetzt ohne zusätzlichen Aufwand Tracing nutzen, indem du nach der Installation in SciTE kurz Strg+Umschalt+F5 drückst. Einfacher geht's eigentlich kaum. Geht etwas am Sinn des Projektes vorbei, aber da war halt schon ein Integrationsskript für SciTE und ein Parser vorhanden, daher war der Rest ziemlich schnell programmiert. Alles grundsätzliche zu SynSug im Thread, der neue Code mit Tracing im git-Repo.
Thread: SynSug - Syntaktischer Zucker für AutoIt (Update v1.1.0 Dictionaries)
Das folgende Testskript erzeugt dann den nachstehenden Output:
C
Alles anzeigen#SynSug_Enable=yes #SynSug_ConsoleTracing=yes #include <Array.au3> $aDices = rollDices(3) $sDices = _ArrayToString($aDices, ", ") MsgBox(0, "Dices", "Rolled: " & @CRLF & $sDices) Func rollDices($nDices) Local $aDices[$nDices] For $i = 0 To $nDices - 1 $aDices[$i] = rollDice() Next Return $aDices EndFunc ;==>rollDices Func rollDice() Return Random(1, 6, True) EndFunc ;==>rollDiceCode!TRACE> Entered function ROLLDICES(). !TRACE-> Entered function ROLLDICE(). !TRACE-> Leaved function ROLLDICE() after 0.0492307782073214 ms. !TRACE-> Entered function ROLLDICE(). !TRACE-> Leaved function ROLLDICE() after 0.0185982939894325 ms. !TRACE-> Entered function ROLLDICE(). !TRACE-> Leaved function ROLLDICE() after 0.0178689491271018 ms. !TRACE> Leaved function ROLLDICES() after 0.257458736402733 ms.Man kann sich jetzt über Tools > Syntactic Sugar (Debug to File) auch anschauen, was mein Parser daraus baut. Der relevante Ausschnitt:
Code
Alles anzeigen#include <Array.au3> $aDices = rollDices(3) $sDices = _ArrayToString($aDices, ", ") MsgBox(0, "Dices", "Rolled: " & @CRLF & $sDices) Func rollDices($nDices) Local $__SYNSUG_TRACE = __SynSug_TraceEnterFunc(rollDices) Local $aDices[$nDices] For $i = 0 To $nDices - 1 $aDices[$i] = rollDice() Next Return __SynSug_TraceLeaveFunc($__SYNSUG_TRACE, $aDices) __SynSug_TraceLeaveFunc($__SYNSUG_TRACE, Null) EndFunc ;==>rollDices Func rollDice() Local $__SYNSUG_TRACE = __SynSug_TraceEnterFunc(rollDice) Return __SynSug_TraceLeaveFunc($__SYNSUG_TRACE, Random(1, 6, True)) __SynSug_TraceLeaveFunc($__SYNSUG_TRACE, Null) EndFunc ;==>rollDice -
Ich würde das Pferd mal von hinten aufzäumen. In der Funktion ist dir nicht bekannt, wie der aktuelle Scope benannt ist. Beim Aufruf aber schon. Also würde ich schon den UDF-Aufruf über eine Zwischenfunktion erledigen, innerhalb derer ich diverse Debug-Daten ausgeben kann. Statt eines myFunc(1, $b) schreibe ich dann in meinem Beispiel c(myFunc, 1, $b).
Die Zwischenfunktion muss leider so umständlich geschrieben werden, da AutoIt keine VarArgs-Definitionen unterstützt. Außerdem können so keine ByRef-Parameter oder Standardwerte für Parameter genutzt werden. Aber immerhin etwas.
Code
Alles anzeigen#include <Array.au3> ;~ $aDices = rollDices(3) $aDices = c(rollDices, 3) $sDices = _ArrayToString($aDices, ", ") MsgBox(0, "Dices", "Rolled: " & @CRLF & $sDices) Func rollDices($nDices) Local $aDices[$nDices] For $i = 0 To $nDices - 1 $aDices[$i] = c(rollDice) Next Return $aDices EndFunc Func rollDice() Return Random(1, 6, True) EndFunc ;trace function Func c($f, $a1 = Null, $a2 = Null, $a3 = Null, $a4 = Null, $a5 = Null, $a6 = Null, $a7 = Null, $a8 = Null, $a9 = Null, $a10 = Null) Local $vRet, $iErr, $iExt, $aParams[@NumParams] Local $hTimer Local Static $nLevel = 0 $aParams[0] = "CallArgArray" If @NumParams > 1 Then $aParams[1] = $a1 If @NumParams > 2 Then $aParams[2] = $a2 If @NumParams > 3 Then $aParams[3] = $a3 If @NumParams > 4 Then $aParams[4] = $a4 If @NumParams > 5 Then $aParams[5] = $a5 If @NumParams > 6 Then $aParams[6] = $a6 If @NumParams > 7 Then $aParams[7] = $a7 If @NumParams > 8 Then $aParams[8] = $a8 If @NumParams > 9 Then $aParams[9] = $a9 If @NumParams > 10 Then $aParams[10] = $a10 ConsoleWrite("!CT> ") For $i = 1 To $nLevel ConsoleWrite(@TAB) Next $nLevel += 1 ConsoleWrite("Entered " & FuncName($f) & "() with " & (@NumParams - 1) & " args." & @CRLF) $hTimer = TimerInit() $vRet = Call($f, $aParams) $vErr = @error $vExt = @extended ConsoleWrite("!CT> ") $nLevel -= 1 For $i = 1 To $nLevel ConsoleWrite(@TAB) Next ConsoleWrite("Leaved " & FuncName($f) & "() after " & TimerDiff($hTimer) & " ms." & @CRLF) Return SetError($iErr, $iExt, $vRet) EndFunc -
Oder einfach ProcessSetDpiAware aus der User32.dll aufrufen. Sofern du keine komplexen GUIs hast, geht das out of the Box.
-
Hi,
ich finde deine JSON-UDF grundsätzlich super und habe sie auch schon bei mehreren Gelegenheiten (Parsing von Web-Services) verwendet. Ich bin jetzt aber auf einen JSON-String gestoßen, der (laut Augenschein und Internet) standardkonform ist, aber die UDF zum Abschmieren bringt. Ist auch nicht sonderlich komplex, scheint an dem Array zu liegen:
Code
Alles anzeigen{ "name": "Sonderpreisliste", "description": "Sonderpreislistenformatierung", "exportSource": "Stammdaten / Preislisten-Definition", "autoDiscover": "???", "dataSql": "SELECT * FROM data", "templates": { "coverPageFile": "some.html", "tableBodyFile": "template.html" }, "variables": [ { "name": "title", "type": "sql", "data": "SELECT `Artikel-Nr.` FROM data" } ] }