Page 1 of 1

Moving/Sliding/Scrolling Text in GUI

Posted: 16 Jan 2018, 12:23
by DigiDon
Image

Hi everyone,

Not sure of the proper English phrase for this : Moving/Sliding/Scrolling Text
I didn't see a complete existing topic on that so here is what I came up with.

I did 4 versions: 2 types (text and statusbar) with 2 variations : Left to Right or Right to Left
Feel free to adjust for more variations (pause at some point, change in the text, whatsoever). The script is quite malleable ;)

Basically it works like this (sorry I did not put comment):
Text control
It moves the text control until it has disappeared and start over
StatusBar
More complicated: it expands or reduces the size allocated to the status bar part and at the end or at the beginning (depending on right or left) it substracts or adds characters to the string until we have it empty or full. Then it starts over.

I am using some functions from jballi's [Library] Fnt v3.0 - Do Stuff With Fonts to get the width of the text
https://autohotkey.com/boards/viewtopic.php?f=6&t=4379

Code: Select all

;------------------------------
;
; Function: Fnt_GetStringSize
;
; Description:
;
;   Calculates the width and height (in pixels) of a string of text.
;
; Parameters:
;
;   hFont - Handle to a logical font.  Set to 0 to use the default GUI font.
;
;   p_String - The string to be measured.
;
;   r_Width, r_Height - Output variables. [Optional] These variables are loaded
;       with the width and height of the string.
;
; Returns:
;
;   Address to a SIZE structure if successful, otherwise FALSE.
;
; Remarks:
;
;   LF (Line Feed) and/or CR+LF (Carriage Return and Line Feed) characters are
;   not considered when calculating the height of the string.
;
; Observations:
;
;   The width of the tab character is usually determined by the control, not by
;   the font, so including tab characters in the string may not produce the
;   desired results.
;
;-------------------------------------------------------------------------------
Fnt_GetStringSize(hFont,p_String,ByRef r_Width="",ByRef r_Height="")
{
    Static Dummy6596
          ,DEFAULT_GUI_FONT:=17
          ,HWND_DESKTOP    :=0
          ,SIZE

    ;-- Workaround for AutoHotkey Basic
    PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"

    ;-- If needed, get the handle to the default GUI font
    if not hFont
        hFont:=DllCall("GetStockObject","Int",DEFAULT_GUI_FONT)

    ;-- Select the font into the device context for the desktop
    hDC      :=DllCall("GetDC",PtrType,HWND_DESKTOP)
    hFont_Old:=DllCall("SelectObject",PtrType,hDC,PtrType,hFont)

    ;-- Get string size
    VarSetCapacity(SIZE,8,0)
    RC:=DllCall("GetTextExtentPoint32"
        ,PtrType,hDC                                    ;-- hDC
        ,"Str",p_String                                 ;-- lpString
        ,"Int",StrLen(p_String)                         ;-- c (string length)
        ,PtrType,&SIZE)                                 ;-- lpSize

    ;-- Housekeeping
    DllCall("SelectObject",PtrType,hDC,PtrType,hFont_Old)
        ;-- Necessary to avoid memory leak

    DllCall("ReleaseDC",PtrType,HWND_DESKTOP,PtrType,hDC)

    ;-- Return to sender
    if RC
        {
        r_Width :=NumGet(SIZE,0,"Int")
        r_Height:=NumGet(SIZE,4,"Int")
        Return &SIZE
        }
     else
        Return False
}


;------------------------------
;
; Function: Fnt_GetStringWidth
;
; Description:
;
;   Calculates the width of a string of text.
;
; Returns:
;
;   The width of the string of text if successful, otherwise -1.
;
; Calls To Other Functions:
;
; * <Fnt_GetStringSize>
;
; Remarks:
;
;   This function is just a call to <Fnt_GetStringSize> to get the width of a
;   string.  Note that there is no associated "GetStringHeight"  function
;   because the height of a string is the same as the font height.  In addition
;   to <Fnt_GetStringSize>, the height can collected from <Fnt_GetFontHeight>.
;
;-------------------------------------------------------------------------------
Fnt_GetStringWidth(hFont,p_String)
{
    Return (pSIZE:=Fnt_GetStringSize(hFont,p_String)) ? NumGet(pSIZE+0,0,"Int"):-1
}
Scrolling Text
Left to Right

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, force

	Gui +hwndGUIHWND
	MovingText:= "This is a test"
	MovingText_Width:=Fnt_GetStringWidth(0,MovingText)
	MovingText_X1:=-MovingText_Width
	MovingText_X2:=""
	Gui, Add, Text, y50 vMovingText_V, % MovingText
	Gui, Show, Center w300
	GuiControl, Move, MovingText_V, % "x" MovingText_X1
	SetTimer, StartMoving, 10
return

StartMoving:
WinGetPos, , , RNGui_Width, , ahk_id %GUIHWND%
	if (MovingText_X2="")
		MovingText_X2:=MovingText_X1
		
	MovingText_X2:=MovingText_X2+1
	
	if (MovingText_X2>RNGui_Width*96/A_ScreenDPI)
		MovingText_X2:=MovingText_X1
	GuiControl, Move, MovingText_V, % "x" MovingText_X2
return

GuiClose:
Exitapp
return
Right to Left

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, force

	Gui +hwndGUIHWND
	MovingText:= "This is a test"
	MovingText_Width:=Fnt_GetStringWidth(0,MovingText)
	MovingText_X2:=""
	Gui, Add, Text, x10 y50 vMovingText_V, % MovingText
	Gui, Show, Center w300
	
	WinGetPos, , , Gui_Width, , ahk_id %GUIHWND%
	MovingText_X1:=Gui_Width*96/A_ScreenDPI
	GuiControl, Move, MovingText_V, % "x" MovingText_X1
	SetTimer, StartMoving, 10
return

StartMoving:
	if (MovingText_X2="")
		MovingText_X2:=MovingText_X1
	MovingText_X2-=1
		if (MovingText_X2<-MovingText_Width)
		MovingText_X2:=MovingText_X1
	GuiControl, Move, MovingText_V, % "x" MovingText_X2
return

GuiClose:
Exitapp
return
Scrolling StatusBar
Left to Right

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, force

	Gui, +hwndGUIHWND

	Gui, Add, Statusbar, vMyStatusbar
	MovingText:="This is a test"
	MovingText_Len:=StrLen(MovingText)
	PartX1:=50
	PartX2:=PartX1
	SB_SetParts(PartX1)
	SB_SetText("Static text",1,1)
	MovingText_X1:=0
	MovingText_X2:=""
	Gui, Show, Center w300
	SetTimer, StartMoving, 50
return

StartMoving:
	if (MovingText_X2="")
		MovingText_X2:=MovingText_X1
	else
	MovingText_X2:=MovingText_X2+1
	Gui 1:Default
	
	if (MovingText_X2>MovingText_Len) {
		WinGetPos, , , Gui_Width, , ahk_id %GUIHWND%
		
		PartX2+=3
		if (PartX2>Gui_Width*96/A_ScreenDPI) {
		quotedisplayedtimes++
		PartX2:=PartX1
		MovingText_X2:=""
		
		MovingText:="This is a test"
		MovingText2:=""
		SB_SetText(MovingText2,2,1)
		}
		SB_SetParts(PartX2)
		}
	else {
	if MovingText_X2=0
		MovingText2:=""
	else
		MovingText2:=SubStr(MovingText,-MovingText_X2+1)
	SB_SetText(MovingText2,2,1)
	}
return

GuiClose:
Exitapp
return
Right to Left

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, force

	Gui, +hwndGUIHWND

	Gui, Add, Statusbar, vMyStatusbar
	MovingText:="This is a test"
	MovingText_Len:=StrLen(MovingText)
	PartX1:=50
	; PartX2:=PartX1
	MovingText_X1:=0
	MovingText_X2:=""
	Gui, Show, Center w300
	 WinGetPos, , , RNGui_Width, , ahk_id %GUIHWND%
	 PartX2:=RNGui_Width*96/A_ScreenDPI
	SB_SetParts(PartX2)
	SB_SetText("Static text",1,1)
	SB_SetText(MovingText,2,1)
	SetTimer, StartMoving, 50
return

StartMoving:
	if (MovingText_X2="") {
        MovingText_X2:=1
        SB_SetText(MovingText,2,1)
        }
    
    WinGetPos, , , RNGui_Width, , ahk_id %GUIHWND%
    
    PartX2-=3
    
    if (PartX2<PartX1 and MovingText_X2<MovingText_Len) {
        PartX2:=PartX1
        MovingText2:=SubStr(MovingText,MovingText_X2)
        MovingText_X2++
        SB_SetText(MovingText2,2,1)
        }
    else if (PartX2<PartX1 and MovingText_X2>=MovingText_Len) {
        MovingText_X2:=""
        MovingText:="This is a test"
        MovingText2:=MovingText
        PartX2:=RNGui_Width*96/A_ScreenDPI
        SB_SetParts(PartX2)
        SB_SetText(MovingText2,2,1)
        }
    else
        SB_SetParts(PartX2)
return

GuiClose:
Exitapp
return
Enjoy ! ;)

Re: Moving/Sliding/Scrolling Text in GUI

Posted: 22 Jan 2022, 17:41
by stretchymantis
Thank you for all the work you put into this! Haven't tested yet, but looks neat!