GDIPlus code als Funktion - Bitte um Hilfe.

  • Guten Morgen allerseits.
    Ich habe mir vor einiger Zeit ein Skript zusammen gebastelt, dass die aktuelle Uhrzeit und das Datum

    zusammen mit einem benutzerdefinierten Bild als Wallpaper verwendet.


    Zusammengebastelt deshalb, weil der GDIPlus Teil mehr hingeklotzt ist, als sonst was, da mir GDIPlus seit je her ein Rätsel ist,

    dass mir einfach nicht in die Birne gehn will, egal wie lange ich mich damit auseinander setz.

    Nun, das Skript funktioniert soweit super und tut genau das was es soll, sieht halt an manschen Stellen nur aus wie Hund...
    Da ich das Skript im Umfang noch erweitern will und es mit einigen anderen Skripten zusammen schließen will,
    würde ich den GDIPlus Teil gerne etwas verbessern.

    Hier aber erstmal der Code:

    Spoiler anzeigen


    Es geht mir hier um die Funktion _SetWallpaper.
    Aktuell wird ja erst die Zeit, dann das Datum auf das Bild gesetzt.
    Und genau das hätte ich gerne in einer gesonderten Funktion.
    Der Code für Zeit und Datum sind ja sehr gleich und wenn jetzt noch ein dritter oder vierter
    Text dazu kommen soll, müsste ich, so wie es aktuell ist diesen Code noch weitere male verwenden.
    Genau dafür ist ja ne Funktion da, um eben unnötige Wiederholungen im Code zu vermeiden.

    Leider schaffe ich es aber nicht, das ganze in eine Funktion zu pressen.
    Deshalb wäre ich Euch sehr dankbar, wenn Ihr mir da etwas bei helfen könntet.

    Anstatt den Code für jeden Text zu wiederholen, möchte ich einfach eine Funktion aufrufen in dem ich alle Parameter wie Text, Font, Größe, Position u.s.w. übergebe.

    Hoffe Ihr könnt mir da etwas helfen.

    Liebe Grüße
    Micha

  • ungetestet:

    Tipp:

    AutoIt
    Func _openOptions()
    ;    Run("notepad.exe " & $sOptionsFile);notepad.exe ist unnötig, wenn es das Standardprogramm zum öffnen für ini Dateien ist, dann reicht auch:
        Shellexecute($sOptionsFile)
    EndFunc

    4 Mal editiert, zuletzt von Moombas (29. Juli 2022 um 09:30) aus folgendem Grund: Dispose eingefügt.

  • AutoIt
    Local Const    $hFont    = _GDIPlus_FontCreate ($hFamily, $sSize, 0) 
    Local Const    $hFormat  = _GDIPlus_StringFormatCreate (0x4000)
    Local Const    $hBrush   = _GDIPlus_BrushCreateSolid (0xff000000) 
    Local Const    $hPen     = _GDIPlus_PenCreate (0xC4000000, 1)

    Das würde ich so nicht empfehlen.

    Wenn die Handle im lokalen Kontext der Funktion geführt werden sollten diese nach dem Zeichnen in der Funktion zwingend mit den entsprechenden ..Dispose-Befehlen gelöscht werden.

    Um so die Variablen nicht ständig zu deklarieren und zu löschen würde ich diese Global definieren und und in der Funktion nur jeweils neu setzen. In einer Exit-Routine beim Skript Beenden können dann die ..Dispose-Befehle eingefügt werden.

  • BugFix Habe nur aufzeigen wollen, was er dafür "separieren" muss und wie. Da sind so einige Sachen, sie ich in seinem Skript etwas anders machen würde bzgl. Lokal und Global bzw. Const. Aber da ich mir da bei einigen Post die Finger diesbezüglich wundschreiben würde wollte ich hier den Fokus auf das wesentliche legen. aber genrell gebe ich dir recht und habe es mal eingefügt.

    Edit: Und ich selber versuche so wenig wie möglich Global zu setzen, alles was man nur Lokal braucht, gehört für mich nur in einen Lokalen Kontext. Was es zudem zumindest für $hFont schwierig macht, da der Inhalt dynamisch ist. Die anderen drei könnte man jedoch durchaus als globale Konstanten setzen, da immer gleich. Jedoch müsste GDIPlus dann direkt bei Programmstart mitgestartet und erst beim beenden geschlossen werden, was für mich auch ein Grund wäre bei der lokalen Variante zu bleiben.

    Einmal editiert, zuletzt von Moombas (29. Juli 2022 um 11:13)

  • Und ich selber versuche so wenig wie möglich Global zu setzen, alles was man nur Lokal braucht, gehört für mich nur in einen Lokalen Kontext.

    Da würde ich definitiv wiedersprechen. Konstanten gehören niemals lokal. Außerdem sollte GDIPlus beim Programmstart gestartet und beim beenden geschlossen werden, wenn die Funktionen öfter benutzt werden. Es erzeugt performance mäßig einfach viel zu viel overhead, ständig zu laden und wieder freizugeben.

    Ich würde immer die Performance als erstes sehen, weil das vom Nutzer am ehesten bemerkt wird. Dann den Speicherverbrauch. Ist heutzutage nicht mehr ein ganz so großes Problem, deshalb wirds nicht allzu schnell auffallen. Und später kommt irgendwann Stil, also wenn möglich lokal,... (Natürlich alles im Rahmen, wenn es nicht anders geht muss man kompromisse eingehen.) Wenn es zu viele Globale Variablen werden, sodass es unübersichtlich wird, muss man halt auf mehrere Scripte aufteilen.

    Lokal gehören nur alle temporären Variablen, die nur während eines Funktionsdurchlaufes verwendet werden. Bei denen macht es keinen Sinn, sie Global anzulegen.

    Hier wüde ich sagen hängt es davon ab, wie oft das Wallpaper geändert werden soll. Wenn es manuell hin und wieder gewechselt wird würde für mich der Speicher evtl. wichtiger sein, weils eh nur alle paar Tage aufgerufen wird => Performance ist weniger wichtig (sollte aber auch nicht wenige Sekunden überschreiten). => Lokal anlegen und wieder freigeben.

    Wenn es automatisch alle X Sekunden/Minuten wechselt sollte für Performance optimiert werden. => Global anlegen

    Wobei ich vmtl. hier einfach nur auf Performance gehen würde und eher Global allokieren würde, weil der Speicherverbrauch so gering ist, dass er nicht ins gewicht fällt. Bei GBs an RAM sind nen paar KB egal.

  • Puhh, ok, ich muss zugeben dass ich weniger als die Hälfte von dem verstehe über das Ihr da diskutiert.
    Aber sei es drum, ich werde jetzt erstmal versuchen den Code von Moombas zu implementieren und gebe Euch dann nochmal Rückmeldung.

    Vielen Dank auf jeden Fall schonmal für die Hilfe :)

  • So.
    Hab versucht den Code zu implementieren und kleinere Fehler zu beheben.
    Das Problem ist aber, jetzt wird nur der Text im fertigen Wallpaper angezeigt, der als letztes über die Funktion eingefügt wurde.

    Hier der Code:

    Spoiler anzeigen

    Weiß leider nich genau was da schief läuft.


    EDIT:
    Hab nochmal etwas dran gebastelt, jetzt funktioniert es wie gewünscht

    Spoiler anzeigen

    Einmal editiert, zuletzt von Michi91 (31. Juli 2022 um 23:56)

  • Hi, ich hatte mir deinen Code gestern angesehen und fand es unglücklich, dass du jede Minute ein neues Bild erstellst, es als Datei speicherst und dann als Hintergrund setzt.

    Das ist eine echt gute Methode, wie du sehr schnell deine Festplatte kaputt schreibst. Bei mir ist das Hintergrundbild (2x4K und 2xFHD Bildschirm) ca. 11MB groß...

    Das wären ~15.840MB => ~16GB in 24 Stunden, die dort geschrieben werden...

    Deshalb hab ich mir gestern ein paar Stunden angeschaut, wie genau die Fenster vom Desktop funktionieren und hab eine UDF geschrieben, mit der man auf den Desktop zeichnen kann.

    Ich hab dein Script mal mit der UDF umgesetzt. Das würde dann so ausschauen:

    Ich hab noch die Sekunden hinzugefügt, weil warum nicht :D

    Edit: Link zur UDF: Wallpaper UDF

    Edit2: _getMaxRect() removed


  • In Zeile 73 (mein letzter Post) wird doch das Bild nachdem es als Wallpaper gesetzt wurde gelöscht.
    Der Speicherverbrauch sollte eigl. minimal sein und in der Zeit von TB Festplatten nicht mehr ins Gewicht fallen.