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

Beiträge von chesstiger

  • Externe IP ermitteln

    • chesstiger
    • 10. Oktober 2019 um 09:22

    *hust*

    Code
    #include <Inet.au3>
    MsgBox(0, 0, _GetIP())
  • Lokale Variablen auf 1 Script beschränken

    • chesstiger
    • 10. August 2019 um 00:04

    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.

  • "gestapelte" Controls - Problem bei der Bk-Farbgebung

    • chesstiger
    • 3. August 2019 um 02:37

    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.

  • Drucken TXT Datei mit formatiertem Text.

    • chesstiger
    • 15. Juli 2019 um 22:22

    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.

  • Funktionsname inkl. Parameter mit RegEx filtern

    • chesstiger
    • 15. Mai 2019 um 01:29

    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:

    Code
    ^Func\h*(\w+\h*(\((((''|")((((?!\5).)*)|(?4))*\5)|([^()]*)|(?2))*\)))\h*(;.*)?\h*\R*$

    Hatte ich jetzt gerade beim Posten nicht drüber nachgedacht. ^^

  • Funktionsname inkl. Parameter mit RegEx filtern

    • chesstiger
    • 15. Mai 2019 um 01:14

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

    Das Pattern ist jetzt zwar etwas ausgeartet, aber es funktioniert einwandfrei. Zumindest habe ich nichts gefunden, was falsch gematcht wird.

    Code
    ^Func\h*(\w+\h*(\(((('|")((((?!\5).)*)|(?4))*\5)|([^()]*)|(?2))*\)))\h*(;.*)?\h*\R*$

    Das ist dann jetzt wie angekündigt eine doppelte Rekursion mit Backreference Match.

    Sogar das hier wird korrekt gematcht:

    Code
    _Strip(11, "Func _SciTE_ShowFuncName('Das hier ist ""böse"". ;)')")
  • Funktionsname inkl. Parameter mit RegEx filtern

    • chesstiger
    • 15. Mai 2019 um 00:36

    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:

    Code
    ^Func\h*(\w+\h*(\(((?:[^()]*)|(?2))*\)))\h*(;.*)?\h*\R*$

    Ergebnis:

    Code
    - 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)]))'
    Alles anzeigen

    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.

  • FontShow - Schriftzug in verschiedenen Schriftarten darstellen

    • chesstiger
    • 12. Mai 2019 um 16:27

    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. :thumbup:

    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.

    screen.png

    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.

    Dateien

    FontShow.zip 5,33 kB – 781 Downloads
  • Erzeugen von komplexeren, formatierten Tabellen

    • chesstiger
    • 5. Mai 2019 um 19:04

    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.

  • 3 verschiedene Farben auf bestimmten Koordinaten erkennen und Meldung ausgeben

    • chesstiger
    • 30. April 2019 um 02:35

    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?

  • Erste Versuche mit WinHTTP, Verständnisprobleme

    • chesstiger
    • 26. Dezember 2018 um 13:10
    Zitat von tippex

    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.

  • Zu : Funktion _Number() von BugFix

    • chesstiger
    • 12. Dezember 2018 um 22:19

    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:

    Code
    try {
    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.

  • Subclassing und AutoIts interne Nachrichtenverarbeitung

    • chesstiger
    • 6. Dezember 2018 um 00:18
    Zitat von Bitnugger

    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.

  • AutoIt: Passwort verschlüsselt in Skript/Programm ablegen

    • chesstiger
    • 5. Dezember 2018 um 22:59

    Dazu fällt mir dieser Thread hier ein:

    Script mit Login versehen

  • Bytemuster zum testen der Laufwerksgeschwindigkeit

    • chesstiger
    • 4. Dezember 2018 um 21:58

    Einmal die SSD, eine Samsung 850 EVO M.2:

    Code
    ASM-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/s
    Alles anzeigen

    Und einmal die Hybridplatte Seagate FireCuda 2TB über SATA (ST2000LX001):

    Code
    ASM-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/s
    Alles anzeigen

    Mit den verschieden komplexen Bytemustern würde mich jetzt auch interessieren.

  • Sehr schnell in GUI schreiben

    • chesstiger
    • 25. November 2018 um 20:46

    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
    #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
    Alles anzeigen
  • Den Namen der aktiven (oder aufrufenden) Function ermitteln

    • chesstiger
    • 25. November 2018 um 02:20

    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
    #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   ;==>rollDice
    Alles anzeigen
    Code
    !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
    #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
    Alles anzeigen
  • Den Namen der aktiven (oder aufrufenden) Function ermitteln

    • chesstiger
    • 23. November 2018 um 23:47

    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
    #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
    Alles anzeigen
  • DPI Einstellungen bekommen

    • chesstiger
    • 22. November 2018 um 07:47

    Oder einfach ProcessSetDpiAware aus der User32.dll aufrufen. Sofern du keine komplexen GUIs hast, geht das out of the Box.

  • JSON-UDF

    • chesstiger
    • 21. November 2018 um 22:04

    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
    {
     "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"
     }
     ]
    }
    Alles anzeigen

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™