Sign in to follow this  
Followers 0
therks

Flickering controls

6 posts in this topic

So I've got this screen saver I wrote up, but the numbers flicker a lot while they're floating around. Is there any fix for this (without a complete overhaul) or am I pretty much SOL?

#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Math.au3>

Global $aOffsets[6], $iLastActive, $sColon, $iMaxRand = 10, $hGUI, $alb_Time[5], $iMaxWidth, $iMaxHeight, $aTimePieces[5][2]
Global $aFollow[3][2] = [ _
        [ Random(-$iMaxRand, $iMaxRand, 1), Random(-$iMaxRand, $iMaxRand, 1) ], _
        [ Random(1, $iMaxWidth, 1), Random(1, $iMaxHeight, 1) ], _
        [ Random(1, $iMaxWidth, 1), Random(1, $iMaxHeight, 1) ] _
    ]
Global Enum $F_RANDMOVE, $F_RAND, $F_FINAL

If @Compiled Then
    If $CmdLine[0] Then
        Switch StringLeft($CmdLine[1], 2)
            Case '/s'
                _Screensaver()
            Case '/p'
                ; Preview
            Case '/c'
                _Config()
        EndSwitch
    Else
        _Config()
    EndIf
Else
    Sleep(1000)
    _Screensaver()
EndIf

Func _Config()
    MsgBox(0x40, 'Clock', 'Sorry, no settings.') ; Font and colour choice options go here
EndFunc

Func _Screensaver()
    Local $iLabelStyle = BitOR($SS_CENTER, $SS_CENTERIMAGE)

    $hGUI = GUICreate('', 1, 1, Default, Default, BitOR($WS_POPUP, $WS_MAXIMIZE), $WS_EX_TOPMOST)
        GUISetBkColor(0)
        GUISetFont(90, 0, 0, 'Lucida Console')
        GUICtrlSetDefColor(0xff00)
        GUICtrlSetDefBkColor($GUI_BKCOLOR_TRANSPARENT)

    $alb_Time[0] = GUICtrlCreateLabel('88', 0, 0, Default, Default, $iLabelStyle)
    $alb_Time[1] = GUICtrlCreateLabel(':', 0, 0, Default, Default, $iLabelStyle)
    $alb_Time[2] = GUICtrlCreateLabel('88', 0, 0, Default, Default, $iLabelStyle)
    $alb_Time[3] = GUICtrlCreateLabel(':', 0, 0, Default, Default, $iLabelStyle)
    $alb_Time[4] = GUICtrlCreateLabel('88', 0, 0, Default, Default, $iLabelStyle)
    For $i = 0 To 4
        $aOffsets[$i+1] = $aOffsets[$i] + _GetPos($alb_Time[$i])
    Next
    $iMaxWidth = @DesktopWidth - $aOffsets[5]
    $iMaxHeight = @DesktopHeight - _GetPos($alb_Time[0], 3)
    For $i = 0 To 4
        $aTimePieces[$i][0] = Random(1, $iMaxWidth, 1)
        $aTimePieces[$i][1] = Random(1, $iMaxHeight, 1)
    Next

    OnAutoItExitRegister('_OnExit')
    DllCall('user32.dll', 'int', 'ShowCursor', 'int', 0)
    _TimeUpdate()

    AdlibRegister('_TimeUpdate', 500)
    AdlibRegister('_Follow', 10)
    AdlibRegister('_FollowRandom', 3000)

    GUISetState()

    $iLastActive = _LastActive()
    While 1
        If $iLastActive <> _LastActive() Then ExitLoop
        Sleep(10)
    WEnd
EndFunc

Func _FollowRandom()
    $aFollow[$F_RANDMOVE][0] = Random(-$iMaxRand, $iMaxRand)
    $aFollow[$F_RANDMOVE][1] = Random(-$iMaxRand, $iMaxRand)
EndFunc

Func _Follow()
    $aFollow[$F_RAND][0] += $aFollow[$F_RANDMOVE][0]
    $aFollow[$F_RAND][1] += $aFollow[$F_RANDMOVE][1]
    If $aFollow[$F_RAND][0] < 0 Then $aFollow[$F_RANDMOVE][0] = Random(5, $iMaxRand)
    If $aFollow[$F_RAND][0] > $iMaxWidth Then $aFollow[$F_RANDMOVE][0] = Random(-$iMaxRand, -5)
    If $aFollow[$F_RAND][1] < 0 Then $aFollow[$F_RANDMOVE][1] = Random(5, $iMaxRand)
    If $aFollow[$F_RAND][1] > $iMaxHeight Then $aFollow[$F_RANDMOVE][1] = Random(-$iMaxRand, -5)

    _FollowCalc($aFollow[$F_FINAL][0], $aFollow[$F_RAND][0])
    _FollowCalc($aFollow[$F_FINAL][1], $aFollow[$F_RAND][1])

    _FollowCalc($aTimePieces[0][0], $aFollow[$F_FINAL][0], 50)
    _FollowCalc($aTimePieces[0][1], $aFollow[$F_FINAL][1], 50)

    For $i = 1 To 4
        _FollowCalc($aTimePieces[$i][0], $aTimePieces[$i-1][0])
        _FollowCalc($aTimePieces[$i][1], $aTimePieces[$i-1][1])
    Next

    For $i = 0 To 4
        GUICtrlSetPos($alb_Time[$i], _Max(0, $aTimePieces[$i][0] + $aOffsets[$i]), _Max(0, $aTimePieces[$i][1]))
    Next
EndFunc

Func _FollowCalc(ByRef $iPos, $iGoTo, $iDiv = 10)
    Local $iDiff = $iGoTo - $iPos
    $iPos += Round($iDiff / $iDiv, 2)
EndFunc

Func _TimeUpdate()
    If $sColon = ':' Then
        $sColon = ''
    Else
        $sColon = ':'
    EndIf

    GUICtrlSetData($alb_Time[0], @HOUR)
    GUICtrlSetData($alb_Time[1], $sColon)
    GUICtrlSetData($alb_Time[2], @MIN)
    GUICtrlSetData($alb_Time[3], $sColon)
    GUICtrlSetData($alb_Time[4], @SEC)
EndFunc

Func _LastActive($vUser32Dll = 'user32.dll')
    Local $sLastInput = DllStructCreate('uint;dword')
    DllStructSetData($sLastInput, 1, DllStructGetSize($sLastInput))
    DllCall($vUser32Dll, 'int', 'GetLastInputInfo', 'ptr', DllStructGetPtr($sLastInput))

    Return DllStructGetData($sLastInput, 2)
EndFunc

Func _GetPos($iCtrl, $iIndex = 2)
    Local $t = ControlGetPos($hGUI, '', $iCtrl)
    Return $t[$iIndex]
EndFunc

Func _OnExit()
    DllCall('user32.dll', 'int', 'ShowCursor', 'int', 1)
EndFunc

Share this post


Link to post
Share on other sites



therks,

The trick to prevent flicker is to update the labels only when they need it. ;)

Try adding a check along these lines for each label:

If GUICtrlRead($alb_Time[0]) <> @HOUR Then
    GUICtrlSetData($alb_Time[0], @HOUR)
EndIf

Any better? :huh2:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Under normal circumstances that would work, but it's not (just) the control updates that are causing flicker, I think it's the positioning.

In fact You can comment out the whole block of GUICtrlSetData()'s at line 119 and it still flickers.

Share this post


Link to post
Share on other sites

therks,

When I run the script with the "flicker-resistant" update code, it looks as if the remaining flicker occurs when you overlap the labels as they move around. This is likely to be due to AutoIt's interpreted nature - it takes (in computer terms) quite a time to move each control. You could try adjusting the movement logic to prevent as much as possible of this overlap. :huh2:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Try GDI+.

Here a fast hack which has enough room for improvement especially for the digits movement.

;fast hack by UEZ 2011
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)

_GDIPlus_Startup()
Global Const $hWin = WinGetHandle("Program Manager")
Global Const $aWin = WinGetPos($hWin)

Global Const $iW = @DesktopWidth
Global Const $iH = @DesktopHeight
Global Const $hgui = GUICreate("GDI+ Test by UEZ", $aWin[2], $aWin[3], $aWin[0], $aWin[1], $WS_POPUP)
GUISetBkColor(0x000000, $hgui)
GUISetState()

Global Const $hDC = _WinAPI_GetWindowDC($hGUI)
Global Const  $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
Global Const  $hBitmap_backbuffer = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hBitmap_backbuffer)
Global Const $hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hBackbuffer, "int", 4)

Global Const $hBrush_Clear = _GDIPlus_BrushCreateSolid(0xFF000000)
Global Const $hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
Global Const $hFormat = _GDIPlus_StringFormatCreate ()
Global Const $hFamily = _GDIPlus_FontFamilyCreate ("Lucida Console")
Global Const $fSize = $iH / 10
Global Const $hFont = _GDIPlus_FontCreate ($hFamily, $fSize, 0)
Global Const $tLayout = _GDIPlus_RectFCreate (0, 0, 0, 0)

Global $aTxt[5] = [@HOUR, ":", @MIN, ":", @SEC]
Global $aPos[5][2]
Global Const $d = $fSize * 1.1
Global Const $dx = $fSize * 2.5
Global Const $dy = $fSize * 1.5
Global Const $fS2 = $fSize / 4

$aPos[0][0] = Random($iW / 4, $iW / 3, 1)
$aPos[0][1] = Random($iH / 3, $iH / 2, 1)
$aPos[1][0] = $aPos[0][0] + $d * 1.35
$aPos[1][1] = $aPos[0][1]
$aPos[2][0] = $aPos[0][0] + $d * 2
$aPos[2][1] = $aPos[0][1]
$aPos[3][0] = $aPos[0][0] + $d * 3.35
$aPos[3][1] = $aPos[0][1]
$aPos[4][0] = $aPos[0][0] + $d * 4
$aPos[4][1] = $aPos[0][1]
GUISetOnEvent($GUI_EVENT_CLOSE , "_Exit")

Global $timer = TimerInit(), $zz, $s = 1
Global $timer_blink = TimerInit()
Global Const $om = MouseGetCursor()
AdlibRegister("Draw", 30)
AdlibRegister("Update_Time", 100)

OnAutoItExitRegister("_Exit")

While Sleep(1000000000)
WEnd

Func Draw()
    GUISetCursor(16, 1, $hGUI)
    Local Static $i
    Local $j, $z = 0.75 + $zz
    For $j = 0 To 4
        _GDIPlus_GraphicsFillRect($hBackbuffer, $aPos[$j][0] - $fS2, $aPos[$j][1] - $fS2, $dx, $dy, $hBrush_Clear)
    Next
;~  _GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $iW, $iH, $hBrush_Clear)
    For $j = 4 To 0 Step - 1
        DllStructSetData($tLayout, "x", $aPos[$j][0])
        DllStructSetData($tLayout, "y", $aPos[$j][1])
        _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $aTxt[$j], $hFont, $tLayout, $hFormat, $hBrush)
        $aPos[$j][0] -= Cos(($i - $z) / 10) * 12
        $aPos[$j][1] -= Sin(($i + $z) / 8) * 8
        $z *= 1.75
    Next
    $i += 0.75
    _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY)
EndFunc

Func Update_Time()
    $aTxt[0] = @HOUR
    $aTxt[2] = @MIN
    $aTxt[4] = @SEC
    If $s = 1 Then
        $aTxt[1] = ""
        $aTxt[3] = ""
    Else
        $aTxt[1] = ":"
        $aTxt[3] = ":"
    EndIf
    If TimerDiff($timer) > 10000 Then
        $zz += Random(-0.5, 0.5)
        $timer = TimerInit()
    EndIf
    If TimerDiff($timer_blink) > 500 Then
        $s *= -1
        $timer_blink = TimerInit()
    EndIf
EndFunc

Func _Exit()
    GUISetCursor($om, 1, $hGUI)
    AdlibUnRegister("Update_Time")
    AdlibUnRegister("Draw")
    _GDIPlus_BrushDispose($hBrush_Clear)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _WinAPI_SelectObject($hDC, $DC_obj)
    _WinAPI_DeleteDC($hDC_backbuffer)
    _WinAPI_DeleteObject($hBitmap_backbuffer)
    _WinAPI_ReleaseDC($hGUI, $hDC)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
    Exit
EndFunc

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Thanks UEZ, that looks really good. Something seems odd about it, but I can't put my finger on it.. it might just be the way it's floating. Either way, it's definitely not flickering anymore, so this gives me something to pick apart and figure out. Thanks again!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0