Flackerndes GUI bei Aktualisierung der Label

  • Liebe AutoIt-Gemeinde, liebe Experten,

    ich bin relativ neu im AutoIt-Gewerbe. Falls ich also etwas Offensichtliches übersehen haben sollte, so bitte ich um Nachsicht.

    Vorab: Als Testumgebung nutze ich noch Windows XP (SP3) - und kann dies auch nicht unmittelbar ändern (falls dies eine Rolle spielen sollt.

    Ich schreibe mir selbst einen Countdown-Timer (unter Zuhilfenahme verschiedener Programmierbeispiele aus AutoIt-Foren). Diese Countdown-Uhr soll mit transparentem Hintergrund unbeweglich in der rechten, unteren Ecke des Bildschirms liegen (TOPMOST, aber inaktiv als Fenster) und eine voreingestellte Anzahl an Minuten herunterzählen, um beim Erreichen von 0 Minuten und Sekunden zu verschwinden.

    Das funktioniert soweit ganz gut, aber ich habe bei jedem Ändern der Sekunden/Minuten/Stunden ein kurzes Flackern, das ich einfach nicht wegbekomme.

    Hier der - der Übersichtlichkeit halber etwas vereinfachte - Code:

    [autoit]

    #include <GuiConstants.au3>
    #include <GuiconstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $nowmins, $nowhours, $nowsecs
    Dim $countmins, $counthours, $countsecs
    Dim $timermins, $timerhours, $timersecs
    Dim $endtime, $jetztzeit, $startzeit, $nettozeit
    Dim $relzeit, $relseconds, $relminutes, $relhours
    Dim $greenhx

    [/autoit][autoit][/autoit][autoit]

    $greenhx = 0x72C45C
    $timerhours = 0
    $timermins = 5
    $timersecs = 0

    [/autoit][autoit][/autoit][autoit]

    $nowhours = @HOUR
    $nowmins = @Min
    $nowsecs = @SEC

    [/autoit][autoit][/autoit][autoit]

    $countsecs = $nowsecs + $timersecs
    $countmins = $nowmins + $timermins
    $counthours = $nowhours + $timerhours

    [/autoit][autoit][/autoit][autoit]

    If $countsecs > 59 Then
    $countsecs = $countsecs - 60
    $countmins = $countmins + 1
    EndIf

    [/autoit][autoit][/autoit][autoit]

    If $countmins > 59 Then
    $countmins = $countmins - 60
    $counthours = $counthours + 1
    EndIf

    [/autoit][autoit][/autoit][autoit]

    If $counthours > 23 Then
    Exit
    EndIf

    [/autoit][autoit][/autoit][autoit]

    $startzeit = ($nowhours * 3600) + ($nowmins * 60) + $nowsecs
    $endtime = ($counthours * 3600) + ($countmins * 60) + $countsecs
    $nettozeit = ($timerhours * 3600) + ($timermins * 60) + $timersecs

    [/autoit][autoit][/autoit][autoit]

    $Form1 = GUICreate("Form1", 120, 35, @DesktopWidth -120, @DesktopHeight -35, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))

    [/autoit][autoit][/autoit][autoit]

    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($Form1, 0xABCDEF, 255)

    [/autoit][autoit][/autoit][autoit]

    $jetztzeit = (@HOUR * 3600) + (@Min * 60) + @Sec
    $relhours = Floor(($endtime - $jetztzeit) / 3600)
    $relminutes = Floor((($endtime - $jetztzeit) - ($relhours * 3600)) /60)
    $relseconds = Floor(($endtime - $jetztzeit) - ($relhours * 3600) - ($relminutes * 60))
    $Label_3 = GUICtrlCreateLabel(StringFormat("%02u", $relminutes), 38, 0, 100, 30)
    $Label_4 = GUICtrlCreateLabel(":", 66, 0, 100, 30)
    $Label_5 = GUICtrlCreateLabel(StringFormat("%02u", $relseconds), 76, 0, 100, 30)
    GUICtrlSetFont ( $Label_3, 20, 800, 0, "Arial")
    GUICtrlSetColor( $Label_3, $greenhx)
    GUICtrlSetFont ( $Label_4, 20, 800, 0, "Arial")
    GUICtrlSetColor( $Label_4, $greenhx)
    GUICtrlSetFont ( $Label_5, 20, 800, 0, "Arial")
    GUICtrlSetColor( $Label_5, $greenhx)

    [/autoit][autoit][/autoit][autoit]

    GUISetState()

    [/autoit][autoit][/autoit][autoit]

    While ( $jetztzeit <= $endtime)
    $msg = GUIGetMsg()
    Select Case $msg = $GUI_EVENT_CLOSE
    ExitLoop
    Case Else
    $relzeit = $endtime - $jetztzeit
    GUICtrlSetData($Label_3, StringFormat("%02u", $relminutes))
    GUICtrlSetColor( $Label_3, $greenhx)
    GUICtrlSetFont ( $Label_3, 20, 800, 0, "Arial")
    GUICtrlSetData($Label_5, StringFormat("%02u", $relseconds))
    GUICtrlSetColor( $Label_5, $greenhx)
    GUICtrlSetFont ( $Label_5, 20, 800, 0, "Arial")

    [/autoit][autoit][/autoit][autoit]

    GuiSetState()
    Sleep(100) ; 100 gesetzt, um das Flackern deutlich zu machen
    $jetztzeit = (@HOUR * 3600) + (@Min * 60) + @Sec
    $relhours = Floor(($endtime - $jetztzeit) / 3600)
    $relminutes = Floor((($endtime - $jetztzeit) - ($relhours * 3600)) /60)
    $relseconds = Floor(($endtime - $jetztzeit) - ($relhours * 3600) - ($relminutes * 60))
    EndSelect
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Exit

    [/autoit]


    Die Vereinfachungen betreffen u.a. die Anzeige der Stunden, einen Farbwechsel bei Erreichen einer Restzeit x, das Ermitteln des aktiven Fensters vor GUICreate und Rückgabe der Aktivierung an dasselbe Fenster danach, die Übergabe der Zeit per Kommandozeile, etc... also alles schnickschnack, der nichts zur Problemlösung beiträgt, aber das Skript schwerer lesbar macht.

    Das Problem ist: Jede Aktualisierung der Zahlen lässt die GUI "flackern".

    Kann mir jemand hier helfen? Wie bekomme ich dieses Flackern weg ohne sonstige Funktionalität zu verlieren?

    Danke vielmals vorab.

    Oliver

    EDIT: CrLf im Code hinzugefügt...

    2 Mal editiert, zuletzt von rossini (17. Januar 2013 um 20:09)

  • Nicht jeder hat Lust die verlorengegangenen Zeilenumbrüche in deinem Script manuell wieder einzufügen ;).
    Kannst du nochmal versuchen das zu posten (eventuell mit einem anderen Browser)? Sonst könntest du es auch als Datei anhängen. Dann erleichterst du usns die Arbeit ein wenig.

  • Danke für den Hinweis... ich habe den Code von Hand im Editor angepasst.
    Sollte jetzt lesbarer sein...

    Oliver

  • Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GuiconstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $nowmins, $nowhours, $nowsecs
    Dim $countmins, $counthours, $countsecs
    Dim $timermins, $timerhours, $timersecs
    Dim $endtime, $jetztzeit, $startzeit, $nettozeit
    Dim $relzeit, $relseconds, $relminutes, $relhours
    Dim $greenhx

    [/autoit] [autoit][/autoit] [autoit]

    $greenhx = 0x72C45C
    $timerhours = 0
    $timermins = 5
    $timersecs = 0

    [/autoit] [autoit][/autoit] [autoit]

    $nowhours = @HOUR
    $nowmins = @MIN
    $nowsecs = @SEC

    [/autoit] [autoit][/autoit] [autoit]

    $countsecs = $nowsecs + $timersecs
    $countmins = $nowmins + $timermins
    $counthours = $nowhours + $timerhours

    [/autoit] [autoit][/autoit] [autoit]

    If $countsecs > 59 Then
    $countsecs = $countsecs - 60
    $countmins = $countmins + 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $countmins > 59 Then
    $countmins = $countmins - 60
    $counthours = $counthours + 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $counthours > 23 Then
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $startzeit = ($nowhours * 3600) + ($nowmins * 60) + $nowsecs
    $endtime = ($counthours * 3600) + ($countmins * 60) + $countsecs
    $nettozeit = ($timerhours * 3600) + ($timermins * 60) + $timersecs

    [/autoit] [autoit][/autoit] [autoit]

    $Form1 = GUICreate("Form1", 120, 35, @DesktopWidth - 120, @DesktopHeight - 35, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))

    [/autoit] [autoit][/autoit] [autoit]

    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($Form1, 0xABCDEF, 255)

    [/autoit] [autoit][/autoit] [autoit]

    $jetztzeit = (@HOUR * 3600) + (@MIN * 60) + @SEC
    $relhours = Floor(($endtime - $jetztzeit) / 3600)
    $relminutes = Floor((($endtime - $jetztzeit) - ($relhours * 3600)) / 60)
    $relseconds = Floor(($endtime - $jetztzeit) - ($relhours * 3600) - ($relminutes * 60))
    $Label_3 = GUICtrlCreateLabel(StringFormat("%02u", $relminutes), 38, 0, 100, 30)
    $Label_4 = GUICtrlCreateLabel(":", 66, 0, 100, 30)
    $Label_5 = GUICtrlCreateLabel(StringFormat("%02u", $relseconds), 76, 0, 100, 30)
    GUICtrlSetFont($Label_3, 20, 800, 0, "Arial")
    GUICtrlSetColor($Label_3, $greenhx)
    GUICtrlSetFont($Label_4, 20, 800, 0, "Arial")
    GUICtrlSetColor($Label_4, $greenhx)
    GUICtrlSetFont($Label_5, 20, 800, 0, "Arial")
    GUICtrlSetColor($Label_5, $greenhx)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_Update", 100)

    [/autoit] [autoit][/autoit] [autoit]

    While ($jetztzeit <= $endtime)
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    AdlibUnRegister()
    Exit
    EndSelect
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Update()
    $relzeit = $endtime - $jetztzeit
    _SetData($Label_3, StringFormat("%02u", $relminutes))
    _SetData($Label_5, StringFormat("%02u", $relseconds))
    $jetztzeit = (@HOUR * 3600) + (@Min * 60) + @Sec
    $relhours = Floor(($endtime - $jetztzeit) / 3600)
    $relminutes = Floor((($endtime - $jetztzeit) - ($relhours * 3600)) /60)
    $relseconds = Floor(($endtime - $jetztzeit) - ($relhours * 3600) - ($relminutes * 60))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SetData($cControl, $sData)
    If GUICtrlRead($cControl) <> $sData Then GUICtrlSetData($cControl, $sData)
    EndFunc

    [/autoit]


    Das lässt sich zwar immer noch verbessern, aber so flackert es nicht mehr und läuft zuverlässiger. Du solltest es generell vermeiden irgendwelche zusätzlichen Abfragen und Funktionen in die Hauptschleife zu schreiben (neben der GUIMsg Abfrage). Ich hab jetzt den Teil der für das updaten der Controls zuständig ist in eine Funktion gepackt und mit AdlibRegister mit einem 100ms Intervall registriert, dadurch wird die Funktion alle 100 Millisekunden aufgerufen (der normale Scriptverlauf wird für die Dauer der Funktion unterbrochen).
    Dann habe ich alle unnötigen Funktionen aus der Funktion genommen. Es reicht wenn du einmal die GUI mit GUISetState sichtbar machst, die versteckt sich nicht automatisch wieder :P. Das Gleiche gilt für GUICtrlSetFont und GUICtrlSetColor. Das muss alles nur ein einziges mal ausgeführt werden wenn du die entsprechenden Eigenschaften ändern willst. Dieser überflüssige Code war der Hauptgrund für das Flackern.
    Als letztes habe ich eine weitere Funktion geschrieben um den Text der Controls zu ändern, die ändert ihn aber nur wenn er sich vom momentanen Inhalt des Controls unterscheidet, so wird unnötiges aktualisieren vermeidet.

    Das solltest du dir vielleicht noch mal genauer anschauen, eventuell hilft dir dabei ein Tutorial oder die umfassende AutoIt Hilfedatei. ;)

  • Hier noch eine Version:

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    _GDIPlus_Startup()
    $hGUI = GUICreate("Test", 300, 150)
    $iLabel = GUICtrlCreateLabel("Standard Control: 0000000000", 10, 10, 290, 50)
    GUICtrlSetFont(-1, 11, 400, 0, "Arial")
    $iPic = GUICtrlCreatePic("", 10, 80, 250, 50)
    GUISetState()
    _GDIPlus_DrwTxt2Ctrl($hGUI, $iPic, "Graphic Control: 0000000000")

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    GUIDelete()
    _GDIPlus_Shutdown()
    Exit
    EndSwitch
    GUICtrlSetData($iLabel, "Standard Control: " & Random(1111111111, 99999999999, 1))
    _GDIPlus_DrwTxt2Ctrl($hGUI, $iPic, "Graphic Control: " & Random(1111111111, 99999999999, 1))
    Until False

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_DrwTxt2Ctrl($hWnd, $iCtrl, $sText, $iFontSize = 11, $sFont = "Arial", $iFontColor = 0xFF000000, $iBgColor = 0xFFF0F0F0, $bAntiAlias = False) ;coded by UEZ build 2013-01-17
    Local $hCtrl = GUICtrlGetHandle($iCtrl)
    Local $aSize = ControlGetPos($hWnd, "", $iCtrl)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $aSize[2], "int", $aSize[3], "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local $hBitmap = $aResult[6]
    Local $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsClear($hCtxt, $iBgColor)
    If $bAntiAlias Then
    _GDIPlus_GraphicsSetSmoothingMode($hCtxt, 2)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hCtxt, "int", 4)
    EndIf
    Local $hBrush = _GDIPlus_BrushCreateSolid($iFontColor)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize)
    Local $tLayout = _GDIPlus_RectFCreate(0, 0, $aSize[2], $aSize[3])
    _GDIPlus_GraphicsDrawStringEx($hCtxt, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hCtxt)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    Local $hB = GUICtrlSendMsg($iCtrl, 0x0172, 0, $hHBitmap)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBitmap)
    Return 1
    EndFunc

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • name22:
    Super. Besten Dank. Du hast Dir - und dafür ein fettes Merci - meinen Beispiel-Code vorgenommen und ihn profund verbessert. Das ist spitze. Ich schlage Dich für den Helferhelfer-Orden am Bande vor. Das hat mir sogar geholfen, meinen eigenen Code, den ich im Beispiel-Code drin hatte weiter aufzuräumen, indem ich einen Farbwechsel nur noch einmal zu einer Zeit x vornehme (und zwar alle Labels hintereinander weg). Deine Erklärungen waren dazu sehr gut. AdLibRegister bzw... Unregister kannte ich bis dato nicht, hab also wieder etwas gelernt, das ich mir gerne auch noch vertieft zu Gemüte führe.

    Greenhorn... das funktioniert bei mir leider nicht (hatte ich vor meinem Post ins Forum schon probiert). Dann hört zwar das Flackern auf, aber alle Label bis auf eines verschwinden. Ich vermute, dass das "verkehrt" herum berechnen via $WS_EX_COMPOSITED hierzu führt, aber mir ist unklar, wie ich dann alle Labels wieder sichtbar bekomme.

    UEZ: Interessanter Ansatz. Besten Dank dafür. Der Code ist momentan noch zu weit von meinem Original-Anwendungszweck entfernt (und scheint mir auch leicht zu flackern, was aber auch an der schnellen Abfolge der Änderungen bei den Zahlen liegen kann). Das schaue ich mir mal in Ruhe an, aber "name22" hat mich bereits soweit befriedigt, dass ich momentan (mangels Wissen) nicht wüsste, warum ich Deinen Ansatz weiterverfolgen sollte. Hat dieser Vorteile, gegenüber der Schiene rossini/name22 (z.B. Speicherbelegung, Geschwindigkeit, o.a.)?

    Vielen Dank für Eure Lösungsansätze. Ich sehe: ich bin von wohlmeinenden Experten umgeben und kann Euch nur loben. Ich komme sicherlich auf Euren Support zurück :)

    Ciao,
    Oliver

    EDIT sagt: Wie markiere ich denn diesen Thread als "gelöst"?

    Einmal editiert, zuletzt von rossini (18. Januar 2013 um 10:52)

  • Standard Control sollte flackern und Graphic Control nicht!

    Der Rest ist Geschmacksache!

    Greenhorn: leider hilft $WS_EX_COMPOSITED nicht...

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • @rossini Wenn du deinen ersten Beitrag bearbeitest kannst du oben das Präfix auf "[gelöst]" setzen. ;)
    Ich würde es eigentlich wie UEZ auch eher mit GDI bzw. GDIPlus umsetzen, aber für dich wird das wahrscheinlich mit den Standardcontrols einfacher sein. Außerdem scheint der GDI+ Ansatz für transparente Fenster den ich im Sinn habe sowieso nicht unter Windows XP zu funktionieren (vermutlich weil XP noch nicht mit Alpha Blending bei Fenstern zurechtkommt. Vollständige/Keine Transparenz pro Pixel funktioniert aber, wie man es an deinem Beispiel sieht) ^^.

  • UEZ,
    ist es auch möglich den Hintergrund transparent zu gestalten?
    Außerdem wäre die Ausrichtung (linksbündig, ...) der Schrift nicht schlecht ;)

    • Offizieller Beitrag

    Die Methode ("BitOR($WS_EX_COMPOSITED, $WS_EX_TOPMOST, $WS_EX_LAYERED)" als ExStyle), die Greenhorn vorgeschlagen hat, funktioniert bei mir mit Windows 7 (64 Bit) ohne flackern.
    Könnt ihr das Script hier mal testen:

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    Opt('GuiOnEventMode', 1)
    Global $iCount = 0
    $hGui = GUICreate('Test', 400, 200, -1, -1, Default, BitOR($WS_EX_COMPOSITED, $WS_EX_TOPMOST, $WS_EX_LAYERED))
    GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
    $ID_Label = GUICtrlCreateLabel('0', 50, 30, 200, 60)
    GUICtrlSetFont(-1, 24, 400)
    GUISetState()
    While True
    $iCount += 1
    GUICtrlSetData($ID_Label, _TicksToTimeFormat($iCount, '%hh:%mm:%ss %ms'))
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    Exit
    EndFunc ;==>_End

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    ; Description:: Diese Funktion wandelt Millisekunden in ein anzugebenes Zeitformat um
    ; Parameter(s): $iTicks = Zeit in Millisekunden
    ; $sFormat:
    ; %ww für Wochen
    ; %dd für Tage
    ; %hh für Stunden
    ; %mm für Minuten
    ; %ss für Sekunden
    ; %ms für Millisekunden
    ; sonstige Zeichen, die dazwischen stehen, werden übernommen
    ; Requirement(s): -
    ; Return Value(s): Zeit im ausgewählten Format (String)
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    Local $aTime[6], $sOut, $aTimeFormat[6] = ['ww', 'dd', 'hh', 'mm', 'ss', 'ms'], $aFormat
    $aTime[4] = Int($iTicks / 1000)
    $aTime[5] = $iTicks - $aTime[4] * 1000
    $aTime[0] = Int($aTime[4] / 604800)
    $aTime[4] = Mod($aTime[4], 604800)
    $aTime[1] = Int($aTime[4] / 86400)
    $aTime[4] = Mod($aTime[4], 86400)
    $aTime[2] = Int($aTime[4] / 3600)
    $aTime[4] = Mod($aTime[4], 3600)
    $aTime[3] = Int($aTime[4] / 60)
    $aTime[4] = Mod($aTime[4], 60)
    $aFormat = StringRegExp($sFormat, '%([^%]+)', 3)
    If Not IsArray($aFormat) Then Return SetError(1, 0, $iTicks)
    For $i = 0 To UBound($aFormat) - 1
    For $j = 0 To UBound($aTimeFormat) - 1
    If StringLeft($aFormat[$i], 2) = $aTimeFormat[$j] Then $sOut &= StringFormat('%0' & 2 + ($j = 5) & 'i', $aTime[$j]) & StringMid($aFormat[$i], 3)
    Next
    Next
    Return $sOut
    EndFunc ;==>_TicksToTimeFormat

    [/autoit]
  • Sieht so aus, dass die Lösung funktioniert, aber das Flackern fängt wieder an, sobald man ein Pic Control, z.B. als Hintergrung Bild, erstellt.

    Hier ein Workaround, um ein Transparenz Effekt zu bekommen:

    Spoiler anzeigen
    [autoit]


    #include <ScreenCapture.au3>
    #include <WindowsConstants.au3>
    #include <StaticConstants.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    Global $iCtrlX = 10, $iCtrlY = 70, $iCtrlW = 250, $iCtrlH = 20
    $hGUI = GUICreate("Test", 450, 100);, -1, -1, Default, BitOR($WS_EX_COMPOSITED, $WS_EX_TOPMOST, $WS_EX_LAYERED))
    $iPic_bg = GUICtrlCreatePic("", 0, 0, 450, 100)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $iLabel = GUICtrlCreateLabel("Standard Control: 0000000000", 10, 10, $iCtrlW, $iCtrlH)
    GUICtrlSetFont(-1, 11, 400, 0, "Arial")
    $iPic = GUICtrlCreatePic("", $iCtrlX, $iCtrlY, $iCtrlW, $iCtrlH)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $hBG_Image = _ScreenCapture_Capture("", 0, @DesktopHeight - 100, 450, @DesktopHeight)
    $hB = GUICtrlSendMsg($iPic_bg, 0x0172, 0, $hBG_Image)
    If $hB Then _WinAPI_DeleteObject($hB)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $hImage = _GDIPlus_BitmapCreateFromHBITMAP ($hBG_Image)
    _WinAPI_DeleteObject($hBG_Image)
    $hImgBg_Rect = _GDIPlus_CropImage($hImage, $iCtrlX, $iCtrlY, $iCtrlW, $iCtrlH)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    GUIDelete()
    _GDIPlus_BitmapDispose($hImgBg_Rect)
    _GDIPlus_Shutdown()
    Exit
    EndSwitch
    GUICtrlSetData($iLabel, "Standard Control: " & Random(1111111111, 99999999999, 1)) ;standard control is flickering
    _GDIPlus_DrwTxt2Ctrl($hGUI, $iPic, "Graphic Control: " & Random(1111111111, 99999999999, 1), $hImgBg_Rect, 11, "Arial", 0xFFF0F080, 0xFFF0F0F0, 1) ;workaround using GDI+
    Until False

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_DrwTxt2Ctrl($hWnd, $iCtrl, $sText, $hBgImage = 0, $iFontSize = 11, $sFont = "Arial", $iFontColor = 0xFF000000, $iBgColor = 0xFFF0F0F0, $iAlign = 0, $bAntiAlias = False) ;coded by UEZ build 2013-01-17
    Local $hCtrl = GUICtrlGetHandle($iCtrl)
    Local $aSize = ControlGetPos($hWnd, "", $iCtrl)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $aSize[2], "int", $aSize[3], "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local $hBitmap = $aResult[6]
    Local $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    If $hBgImage Then
    _GDIPlus_GraphicsDrawImage($hCtxt, $hBgImage, 0, 0)
    Else
    _GDIPlus_GraphicsClear($hCtxt, $iBgColor)
    EndIf
    If $bAntiAlias Then
    _GDIPlus_GraphicsSetSmoothingMode($hCtxt, 2)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hCtxt, "int", 4)
    EndIf
    Local $hBrush = _GDIPlus_BrushCreateSolid($iFontColor)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, $iAlign)
    Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize)
    Local $tLayout = _GDIPlus_RectFCreate(0, 0, $aSize[2], $aSize[3])
    _GDIPlus_GraphicsDrawStringEx($hCtxt, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hCtxt)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    Local $hB = GUICtrlSendMsg($iCtrl, 0x0172, 0, $hHBitmap)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBitmap)
    Return 1
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_CropImage($hImage, $iX, $iY, $iW, $iH, $bHBitmap = False)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local $hCtxt = _GDIPlus_ImageGetGraphicsContext($aResult[6])
    _GDIPlus_GraphicsDrawImageRectRect($hCtxt, $hImage, $iX, $iY, $iW, $iH, 0, 0, $iW, $iH)
    _GDIPlus_GraphicsDispose($hCtxt)
    If $bHBitmap Then
    Local $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($aResult[6])
    _GDIPlus_BitmapDispose($aResult[6])
    Return $hHBmp
    EndIf
    Return $aResult[6]
    EndFunc

    [/autoit]

    Wenn kein Bild als Hintergrund gewählt ist, dann einfach in Zeile 33 $hImgBg_Rect durch 0 ersetzen und den Parameter für $iBgColor entsprechend wählen.

    Was besseres ist mir im Moment nicht eingefallen.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Uhrzeit mit Sekunden (1Sek. = 1000 ms) anzeigen. So reicht es aus, die Anzeige alle 1000 ms neu zu zeichnen. ;)

    [autoit]


    GUICreate("Uhr", 160, 50)
    Global $Label = GUICtrlCreateLabel("", 10, 10, 140, 30)
    GUICtrlSetFont(-1, 20, 800, 0, "Arial")

    [/autoit][autoit][/autoit][autoit]

    GUISetState()

    [/autoit][autoit][/autoit][autoit]

    AdlibRegister("_timeSet", 1000)

    [/autoit][autoit][/autoit][autoit]

    While True
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    ExitLoop
    EndSwitch
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func _timeSet()
    GUICtrlSetData($Label, @HOUR & " : " & @MIN & " : " & @SEC)
    EndFunc ;==>_timeSet
    ; Ende

    [/autoit]