Jump to content

Label Blinking with Pic for Background


 Share

Go to solution Solved by UEZ,

Recommended Posts

I have a program that has a large label acting as a count down timer.
I have set the background color of the label to $GUI_BKCOLOR_TRANSPARENT.
 
This program has a picture for a background.
In the below example the gui's background color is set to yellow.
 
Occasionally when the timer updates you can see the yellow background color in the shape of the label.
 
i have looked at many posts about blinking labels, but the all appear to find a way around the blinking problem instead of fixing it and none of them use a background picture.
 
Does anyone know how this problem can be fixed?
Or perhaps just a work around for my situation?

As you can see by my commented out code, I have tried ControlSetText and GUISetState LOCK/UNLOCK.

ControlSetText results in each new number being written over whatever was in the label instead of replacing it

GUISetState LOCK/UNLOCK cause the issue to happen to the whole gui instead of just the label.
 
 I have attached the background I was using.

Thanks in advance.

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

Const $BKGND_FILE = "C:\Users\sjraisbe\Pictures\poker bkgd.jpg"

Global $seconds = 60

$hMain = GUICreate("Timer", 800, 600, -1, -1, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUP,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_BORDER,$WS_CLIPSIBLINGS))
   GUISetBkColor(0xFFFF00, $hMain)
   GUICtrlSetDefBkColor($GUI_BKCOLOR_TRANSPARENT, $hMain)

$pic = GUICtrlCreatePic($BKGND_FILE, 0, 0, 1920, 1080)
   GUICtrlSetState(-1,$GUI_DISABLE)

$lblTime = GUICtrlCreateLabel("01:00", 192, 222, 424, 156, $SS_CENTER)
   GUICtrlSetFont($lblTime, 100, 400, 0, "Arial")
   GUICtrlSetColor($lblTime, 0xFFFFFF)

AdlibRegister("UpdateTime", 1000)

GUISetState(@SW_SHOW, $hMain)

While 1
   $msg = GUIGetMsg()
   If $msg = $GUI_EVENT_CLOSE Then
      ExitLoop
   EndIf

WEnd


Func UpdateTime()
   ;GUISetState(@SW_LOCK)
   Local $sec, $min, $hr
   $sec = Mod($seconds, 60)
   $min = Mod($seconds / 60, 60)
   GUICtrlSetData($lblTime, StringFormat("%02i:%02i", $min, $sec))
   ;ControlSetText($hMain, "", $lblTime, StringFormat("%02i:%02i", $min, $sec))
    

   $seconds -= 1
   ;GUISetState(@SW_UNLOCK)
EndFunc

post-24647-0-19432700-1393965568_thumb.j

Link to comment
Share on other sites

Have a look here for a start: 

There should a lot of code snippets flying around how to update a control without flickering using GDI+.

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

UEZ,

I looked at the GDI script in your linked post and played with it a bit.

When I add a background to the gui, the time label/graphic is not transparent so it ends up having a grey rectangle around the time.

I was unable to figure out if it's possible to make the background transparent.

I believe I ran across this before, GDI looked like a good solution until I realized that none of the example scripts use a background and transparency.

Can GDI be used to create a label with a transparent background?

Thanks,

momar33

Link to comment
Share on other sites

Try this:
 

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>
_GDIPlus_Startup()

Const $BKGND_FILE = @ScriptDir & "\poker bkgd.jpg"
Local $hImage_Bg = _GDIPlus_ImageLoadFromFile($BKGND_FILE)
Local $hTexture = _GDIPlus_TextureCreate($hImage_Bg)
Global $seconds = 60
Global Const $iW = 800, $iH = 600
$hMain = GUICreate("Timer", $iW, $iH)
GUISetBkColor(0x2C6135)
$lblTime = GUICtrlCreatePic("", 0, 0, $iW, $iH)
GUICtrlSetState(-1, $GUI_DISABLE)
UpdateTime()
GUISetState(@SW_SHOW, $hMain)

AdlibRegister("UpdateTime", 1000)


While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then
        _GDIPlus_BrushDispose($hTexture)
        _GDIPlus_ImageDispose($hImage_Bg)
        _GDIPlus_Shutdown()
        GUIDelete()
        Exit
    EndIf
WEnd


Func UpdateTime()
    Local $sec, $min, $hr
    $sec = Mod($seconds, 60)
    $min = Mod($seconds / 60, 60)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4 + (@OSBuild > 5999))
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3)
    _GDIPlus_GraphicsFillRect($hGfx, 0, 0, $iW, $iH, $hTexture)
    Local Const $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    Local Const $hFormat = _GDIPlus_StringFormatCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    Local Const $hFont = _GDIPlus_FontCreate($hFamily, 100)
    Local Const $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_GraphicsDrawStringEx($hGfx, StringFormat("%02i:%02i", $min, $sec), $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGfx)
    Local Const $hBitmap_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($lblTime, 0x0172, 0x0000, $hBitmap_GDI)) ;$STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
    _WinAPI_DeleteObject($hBitmap_GDI)
    $seconds -= 1
    If $seconds < 0 Then AdlibUnRegister("UpdateTime")
EndFunc   ;==>UpdateTime

Br,

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

UEZ,

That script was very helpful.

It looks like it is still not using a transparent background though, instead just making the label and background all in the same pic.

The program I intend to use this timer in has several other labels being displayed at the same time.

Based on what I have learned from the script, and assuming there is no way to make the pic background transparent, it seems that either the GDI pic will either overwrite everything, or if i adjust the position and size, the GDI pic background will not match up with the GUI background.

It seems the only way I can proceed is to make all the information on my program using GDI.

Thanks,

momar33

Link to comment
Share on other sites

There is a way with GDI+ to exclude the areas where the controls are placed.

I will modify the example appropriately later.

Br,

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

  • Solution

Then try something like this here:

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>
_GDIPlus_Startup()

Const $BKGND_FILE = @ScriptDir & "\poker bkgd.jpg"
Global Const $hImage_Bg = _GDIPlus_ImageLoadFromFile($BKGND_FILE)
Global Const $hTexture = _GDIPlus_TextureCreate($hImage_Bg)
Global $seconds = 60
Global Const $iW = 800, $iH = 600

Global $sec, $min, $hr

$hMain = GUICreate("Timer", $iW, $iH)
GUISetBkColor(0x2C6135)

$iBtn = GUICtrlCreateButton("Hit me", 700, 500, 80, 60)
$iLbl = GUICtrlCreateLabel("This is a label", 20, 500, 250, 45)
GUICtrlSetFont(-1, 30)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUISetState(@SW_SHOW, $hMain)

Global Const $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hMain)

_GDIPlus_RegionExcludeContorls($hGraphic, $hMain)

UpdateTime()

AdlibRegister("UpdateTime", 1000)

GUIRegisterMsg($WM_PAINT, "Draw")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $iBtn
            _GDIPlus_BrushDispose($hTexture)
            _GDIPlus_ImageDispose($hImage_Bg)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
        Case $iLbl
            MsgBox(0, "Test", "Label was clicked")
        Case @SW_RESTORE
            Draw()
   EndSwitch
WEnd

Func _GDIPlus_RegionExcludeContorls($hGraphic, $hGUI)
    Local Const $aHWND_Info = WinGetClientSize($hGUI)
    Local Const $hRegion = _GDIPlus_RegionCreateFromRect(0, 0, $aHWND_Info[0], $aHWND_Info[1])
    Local $hChild = _WinAPI_GetWindow($hGUI, $GW_CHILD), $aRect
    Do
        $aRect = ControlGetPos($hChild, "", 0)
        _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3)
        $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
    Until Not $hChild
    _GDIPlus_GraphicsSetClipRegion($hGraphic, $hRegion)
    _GDIPlus_RegionDispose($hRegion)
EndFunc

Func UpdateTime()
    $sec = Mod($seconds, 60)
    $min = Mod($seconds / 60, 60)
    Draw()
    $seconds -= 1
    If $seconds < 0 Then AdlibUnRegister("UpdateTime")
EndFunc   ;==>UpdateTime

Func Draw()
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4 + (@OSBuild > 5999))
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3)
    _GDIPlus_GraphicsFillRect($hGfx, 0, 0, $iW, $iH, $hTexture)
    Local Const $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    Local Const $hFormat = _GDIPlus_StringFormatCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    Local Const $hFont = _GDIPlus_FontCreate($hFamily, 100)
    Local Const $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_GraphicsDrawStringEx($hGfx, StringFormat("%02i:%02i", $min, $sec), $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iW, $iH)
    _GDIPlus_BitmapDispose($hBitmap)
    Return "GUI_RUNDEFMSG"
EndFunc

Br,

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

×
×
  • Create New...