Jump to content

Anti Flicker this please!!


Recommended Posts

This works fine it just has a flicker. Is there a better way?

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <Date.au3>
$GUi = GUICreate("Time Clock", 464, 388, 362, 81)
$Time = GUICtrlCreateLabel("", 72, 40, 350, 81)
GUICtrlSetFont(-1, 50)
$Name = GUICtrlCreateCombo("Combo1", 56, 152, 137, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SIMPLE))
$Clock = GUICtrlCreateButton("Button1", 256, 150, 139, 25)
GUISetState(@SW_SHOW)
$sec = @SEC

While 1
    If @SEC <> $sec Then
        GUICtrlSetData($Time, _NowTime())
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Link to comment
Share on other sites

To reduce CPU consumption you have to insert a Sleep statement. You should wait for less than a second because processing the While loop takes a few cycles.

You have to set $sec so the comparison doesn't always trigger GUICtrlSetData.

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <Date.au3>
$GUi = GUICreate("Time Clock", 464, 388, 362, 81)
$Time = GUICtrlCreateLabel("", 72, 40, 350, 81)
GUICtrlSetFont(-1, 50)
$Name = GUICtrlCreateCombo("Combo1", 56, 152, 137, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SIMPLE))
$Clock = GUICtrlCreateButton("Button1", 256, 150, 139, 25)
GUISetState(@SW_SHOW)
$sec = @SEC

While 1
    If @SEC <> $sec Then
        GUICtrlSetData($Time, _NowTime())
        $sec = @SEC   ; <== inserted 
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    Sleep(800)  ; <== inserted
WEnd
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Try this:

;coded by UEZ 2011
#include <ComboConstants.au3>
#include <Date.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>

Global Const $iW = 350
Global Const $iH = 81
Global Const $gW = 464
Global Const $gH = 288
Global Const $hGUI = GUICreate("Time Clock by UEZ 2011", $gW, $gH)
Global Const $bgc = "F0F0F0"
GUISetBkColor("0x" & $bgc, $hGUI)
Global Const $idPic = GUICtrlCreatePic("", 72, 40, $iW, $iH)
Global Const $cCombo = GUICtrlCreateCombo("Test Combo", 56, 152, 137, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SIMPLE))
Global Const $bExit= GUICtrlCreateButton("Exit", 256, 150, 139, 25)
GUISetState(@SW_SHOW)

Global $nMsg

_GDIPlus_Startup()
Global $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int",  0x0026200A, "ptr", 0, "int*", 0)
$hBitmap = $hBitmap[6]
Global Const $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hContext, 2)
DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hContext, "int", 4)
_GDIPlus_GraphicsClear($hContext, "0xFF" & $bgc)

Timer()

AdlibRegister("Timer", 1000)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE, $bExit
            AdlibUnRegister("Timer")
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_GraphicsDispose($hContext)
            _GDIPlus_Shutdown()
            GUIDelete($hGUI)
            Exit
    EndSwitch
WEnd

Func Timer()
    _GDIPlus_GraphicsDrawString($hContext, _NowTime(), 0, 0, "Arial", 50)
    Local $hHBITAMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, 0x0172, 0, $hHBITAMP))
    _WinAPI_DeleteObject($hHBITAMP)
    _GDIPlus_GraphicsClear($hContext, "0xFF" & $bgc)
EndFunc

Tested on Win7 x64 with Aero.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

To reduce CPU consumption you have to insert a Sleep statement. You should wait for less than a second because processing the While loop takes a few cycles.

You have to set $sec so the comparison doesn't always trigger GUICtrlSetData.

If you have got GUIGetMsg() in your loop then you don't need Sleep() because it internally do this for you.

In fact such Sleep() in main loop of GUI scripts is bad because it increase reaction time of GUI controls to user action.

Link to comment
Share on other sites

I learn something new every day :huh2:

But now it's time for bed ;)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Thanks guys,

And to UEZ - Way to make a simple NowTime display complicated! Works but doesn't all that slow down the main script with all those functions every second?

added, $sec = @SEC within the If...Then statement was all it took...

Also agree with adding Sleep in with GUIGetMsg, really slows down response time!!!

Link to comment
Share on other sites

I like the GDI+ Example UEZ :huh2: That goes straight into my Function folder.

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Try this bad boy on for size:

#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1)
Opt("GUICloseOnEsc", 1)

Global Const $GUI = GUICreate("Time Clock", 464, 388, 362, 81)
GUISetOnEvent($GUI_EVENT_CLOSE, "_exit", $GUI)

Global Const $Time = GUICtrlCreateLabel('', 40, 40, 450, 81)
GUICtrlSetFont($Time, 50)

Global Const $Name = GUICtrlCreateCombo("Combo1", 56, 152, 137, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SIMPLE))

Global Const $Clock = GUICtrlCreateButton("Button1", 256, 150, 139, 25)

time_of_the_now()

GUISetState(@SW_SHOWNORMAL)

AdlibRegister("time_of_the_now", 1000)

While True
    Sleep(100)
WEnd

Func _exit()
    Exit
EndFunc   ;==>_exit

; this code was shamelessly stolen and striped of it's identify -- all to suit my purposes
Func time_of_the_now()
    ; split the Date and Time portion
    Local Const $sDateTime = StringSplit(@YEAR & '/' & @MON & '/' & @MDAY & ' ' & @HOUR & ':' & @MIN & ':' & @SEC, " T")

    ; split the Time portion
    Local $asTimePart = StringSplit($sDateTime[2], ':')

    ; update the array to contain numbers not strings
    For $x = 1 To 3
        If StringIsInt($asTimePart[$x]) Then
            $asTimePart[$x] = Number($asTimePart[$x])
        Else
            $asTimePart[$x] = 0
        EndIf
    Next

    Local $sTempTime = "h:mm:ss tt"

    If $asTimePart[1] < 12 Then
        $sTempTime = StringReplace($sTempTime, "tt", "AM")
        If $asTimePart[1] = 0 Then $asTimePart[1] = 12
    Else
        $sTempTime = StringReplace($sTempTime, "tt", "PM")
        If $asTimePart[1] > 12 Then $asTimePart[1] = $asTimePart[1] - 12
    EndIf

    $asTimePart[1] = StringRight('0' & $asTimePart[1], 2) ; make sure the length is 2
    $asTimePart[2] = StringRight('0' & $asTimePart[2], 2) ; make sure the length is 2
    $asTimePart[3] = StringRight('0' & $asTimePart[3], 2) ; make sure the length is 2

    $sTempTime = StringReplace($sTempTime, "hh", StringFormat("%02d", $asTimePart[1]))
    $sTempTime = StringReplace($sTempTime, 'h', StringReplace(StringLeft($asTimePart[1], 1), '0', '') & StringRight($asTimePart[1], 1))
    $sTempTime = StringReplace($sTempTime, "mm", StringFormat("%02d", $asTimePart[2]))
    $sTempTime = StringReplace($sTempTime, "ss", StringFormat("%02d", $asTimePart[3]))

    GUICtrlSetData($Time, StringStripWS($sTempTime, 4))
EndFunc   ;==>time_of_the_now

It's a little bit off but what can ya do? Now it seems to be right on time.

Edit: latest revision again, even better

Edited by LaCastiglione
Link to comment
Share on other sites

I agree with Zedna you shouldn't use it inside the loop and use a seperate function in combination with AdlibRegister

The example giving by UEZ is really good..

I simply use an alternative GUICtrlSetData.. this one only updates while something is changed

Func _GUICtrlSetData($iCtrlID, $sData)
    If GUICtrlRead($iCtrlID, 1) <> $sData Then GUICtrlSetData($iCtrlID, $sData)
EndFunc   ;==>_GUICtrlSetData

Best regards,Emiel Wieldraaijer

Link to comment
Share on other sites

Thanks guys,

And to UEZ - Way to make a simple NowTime display complicated! Works but doesn't all that slow down the main script with all those functions every second?

added, $sec = @SEC within the If...Then statement was all it took...

Also agree with adding Sleep in with GUIGetMsg, really slows down response time!!!

Why complicated? You asked for an anti flicker way and I showed you a simple one! Imho, using some little GDI+ calls makes the script not more complicated!

I measured the time how long it takes to call the Timer function. I called it 1000 times and the average time was ~5 milli seconds. I don't believe that 5 milli seconds will slow down your script!

I modified my example and added font smoothing for a better look!

Well, this one works, too but sometimes it still flickers:

 

#include <ComboConstants.au3>
#include <Date.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$GUi = GUICreate("Time Clock", 464, 388, 362, 81, Default, BitOR($WS_EX_COMPOSITED, $WS_EX_LAYERED))
$Time = GUICtrlCreateLabel("", 72, 40, 350, 81)
GUICtrlSetFont(-1, 50, 400, 0, "Arial", 4)
$Name = GUICtrlCreateCombo("Combo1", 56, 152, 137, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL,$CBS_SIMPLE))
$Clock = GUICtrlCreateButton("Button1", 256, 150, 139, 25)
GUISetState(@SW_SHOW)

Timer()
AdlibRegister("Timer", 1000)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            AdlibUnRegister("Timer")
            Exit
    EndSwitch
WEnd

Func Timer()
    GUICtrlSetData($Time, _NowTime())
EndFunc

Or GDI+ version:

#include <ComboConstants.au3>
#include <Date.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>

Global Const $iW = 350
Global Const $iH = 81
Global Const $gW = 464
Global Const $gH = 288
Global Const $hGUI = GUICreate("Time Clock by UEZ 2011", $gW, $gH)
Global Const $iColor = _WinAPI_GetSysColor($COLOR_3DFACE) ;"F0F0F0"
Global Const  $bgc = Hex(BitOR(BitAND($iColor, 0x00FF00), BitShift(BitAND($iColor, 0x0000FF), -16), BitShift(BitAND($iColor, 0xFF0000), 16)), 6)
GUISetBkColor("0x" & $bgc, $hGUI)
Global Const $idPic = GUICtrlCreatePic("", 72, 40, $iW, $iH)
Global Const $cCombo = GUICtrlCreateCombo("Test Combo", 56, 152, 137, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SIMPLE))
Global Const $bExit= GUICtrlCreateButton("Exit", 256, 150, 139, 25)
GUISetState(@SW_SHOW)

Global $nMsg

_GDIPlus_Startup()
Global $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int",  0x0026200A, "ptr", 0, "int*", 0)
$hBitmap = $hBitmap[6]
Global Const $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hContext, 2)
DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hContext, "int", 4)
_GDIPlus_GraphicsClear($hContext, "0xFF" & $bgc)

Timer()

AdlibRegister("Timer", 1000)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE, $bExit
            AdlibUnRegister("Timer")
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_GraphicsDispose($hContext)
            _GDIPlus_Shutdown()
            GUIDelete($hGUI)
            Exit
    EndSwitch
WEnd

Func Timer()
    _GDIPlus_GraphicsDrawString($hContext, _NowTime(), 0, 0, "Arial", 50)
    Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, 0x0172, 0x0000, $hHBITMAP)) ;$STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
    _WinAPI_DeleteObject($hHBITMAP)
    _GDIPlus_GraphicsClear($hContext, "0xFF" & $bgc)
EndFunc

It is your example but using Adlib function which is the smartest way imho.

Br,

UEZ

Edit: code was broken in code box - fixed now.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...