Hi!
I needed a simple marquee for a project. There are very good Marquee UDFs here on the forum that rely on a IEFrame on your GUI, but I had some systems restrictions that lead me to make this quick and dirty only.
I might revisit this UDF in the future but so far it works for my needs as is. It doesn't work by scrolling the text as a real marquee should do, but by cutting letters of the string.
The usage is very simple:
Start by creating a standard label:
GUICtrlCreateLabel("Lorem ipsum dolor sit amet consectetur adipiscing elit...", 3, 3, 200, 16)
Now use the _GUICtrlStaticMarquee_Create function instead:
_GUICtrlStaticMarquee_Create("Lorem ipsum dolor sit amet consectetur adipiscing elit...", 3, 3, 200, 16)
As you can see, the functions accepts the same arguments. This also means that the two GUICtrlCreateLabel optional arguments (style and exStyle) also function. Yet, both functions will return you a handle to the label, so you can use it to change colors, fonts etc, just like with a standard label.
But two additional parameters are accepted:
$iScrollDelay: how many ms between one update and another (default: 300)
$iScrollAmount: how many characters to scroll per update (default: 1)
For specifying these parameters, remember to include GUICtrlCreateLabel's style and exStyle (you can pass the keyword Default).
_GUICtrlStaticMarquee_Create("Lorem ipsum dolor sit amet consectetur adipiscing elit...", 3, 3, 200, 16, Default, Default, 500, 2)
You can also change the marquee text (don't do it with GUICtrlSetData) and the above two parameters using the function below. Remember you can always use the Default keyword for keeping one parameter untouched.
_GUICtrlStaticMarquee_SetData($hWnd, $sText, $iScrollDelay, $iScrollAmount)
Here's the UDF:
#include-once
Global $__GUICtrlStaticMarquee_Controls = [0]
Global $__GUICtrlStaticMarquee_IsAdlibEnabled = False
#cs
$__GUICtrlStaticMarquee_Controls will contain all created static marquees.
Each one will be an array with the following items:
[
$hWnd
$iLastUpdateTimestampMs
$iScrollDelay
$iScrollAmount
$sText
$iStep
]
#ce
Func _GUICtrlStaticMarquee_Create($sText, $iLeft, $iTop, $iWidth = Default, $iHeight = Default, $iStyle = Default, $iExStyle = Default, $iScrollDelay = 300, $iScrollAmount = 1)
Local $hWnd = GUICtrlCreateLabel($sText, $iLeft, $iTop, $iWidth, $iHeight, $iStyle, $iExStyle)
; add new item to controls array
Local $aItem[] = [ _
$hWnd, _
TimerInit(), _
$iScrollDelay, _
$iScrollAmount, _
$sText, _
0 _
]
Local $iOldLength = $__GUICtrlStaticMarquee_Controls[0]
ReDim $__GUICtrlStaticMarquee_Controls[$iOldLength + 2]
$__GUICtrlStaticMarquee_Controls[0] = $iOldLength + 1
$__GUICtrlStaticMarquee_Controls[$iOldLength + 1] = $aItem
If Not $__GUICtrlStaticMarquee_IsAdlibEnabled Then
__GUICtrlStaticMarquee_StartInterval()
EndIf
Return $hWnd
EndFunc
Func _GUICtrlStaticMarquee_SetData($hWnd, $sText = Default, $iScrollDelay = Default, $iScrollAmount = Default)
For $iControl = 1 To $__GUICtrlStaticMarquee_Controls[0]
Local $aControl = $__GUICtrlStaticMarquee_Controls[$iControl]
If $aControl[0] = $hWnd Then
$aControl[1] = TimerInit()
If $sText <> Default Then $aControl[4] = $sText
If $iScrollDelay <> Default Then $aControl[2] = $iScrollDelay
If $iScrollAmount <> Default Then $aControl[3] = $iScrollAmount
If $sText <> Default Then
$aControl[4] = $sText
GUICtrlSetData($hWnd, $sText)
EndIf
$aControl[5] = 0
$__GUICtrlStaticMarquee_Controls[$iControl] = $aControl
Return True
EndIf
Next
Return False
EndFunc
Func __GUICtrlStaticMarquee_StartInterval($iDelay = 100)
$__GUICtrlStaticMarquee_IsAdlibEnabled = True
AdlibRegister("__GUICtrlStaticMarquee_Loop", $iDelay)
EndFunc
Func __GUICtrlStaticMarquee_Loop()
If UBound($__GUICtrlStaticMarquee_Controls) = 1 Then
Return
EndIf
For $iControl = 1 To $__GUICtrlStaticMarquee_Controls[0]
Local $aControl = $__GUICtrlStaticMarquee_Controls[$iControl]
If Not GUICtrlGetHandle($aControl[0]) Then
; item was removed
ContinueLoop
EndIf
If TimerDiff($aControl[1]) > $aControl[2] Then
Local $sCurrentText = GUICtrlRead($aControl[0])
; update text
Local $iTotalSteps = Floor(StringLen($aControl[4]) / $aControl[3])
Local $iNextStep = $aControl[5] + 1
; reached end of string, reset to position 0
If ($iNextStep > $iTotalSteps) Then
$iNextStep = 0
EndIf
$sNewText = __GUICtrlStaticMarquee_CalcText($aControl[4], $iNextStep, $aControl[3])
Local $aItem = $__GUICtrlStaticMarquee_Controls[$iControl]
; save current step
$aItem[5] = $iNextStep
; set text to input
GUICtrlSetData($aControl[0], $sNewText)
$__GUICtrlStaticMarquee_Controls[$iControl] = $aItem
EndIf
Next
EndFunc
Func __GUICtrlStaticMarquee_CalcText($sText, $iStep, $iScrollAmount)
Return StringTrimLeft($sText, $iStep * $iScrollAmount) & ' ' & StringLeft($sText, $iStep * $iScrollAmount)
EndFunc
Example:
#include <GUIConstantsEx.au3>
#include "GUICtrlStaticMarquee.au3"
$Form1 = GUICreate("Example", 300, 200, 300, 200)
$Label1 = _GUICtrlStaticMarquee_Create("Hello world", 3, 3, 200, 16)
GUISetState(@SW_SHOW)
; changing text:
Sleep(5500)
_GUICtrlStaticMarquee_SetData($Label1, "Ola mundo!")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd