Leaderboard
Popular Content
Showing content with the highest reputation on 03/12/2025 in all areas
-
Smooth and infinite marquee style scroll of a long string in a short control
pixelsearch and 3 others reacted to Gianni for a topic
If you want the text scrolling to continue even when you drag the GUI or even when an MsgBox() is in action, you can use _WinAPI_SetTimer instead of AdlibRegister, as in this slightly modified version of your script. ... But if you don't care, then forget it ... #include <GUIConstants.au3> #include <WinAPISysWin.au3> $guiWidth = 300 $hGUI = GUICreate("Main GUI", $guiWidth, 70) $sString = "This is a long string that scrolls smoothly and infinitely in a short label control." ; Create a child GUI for scrolling label $iMargin = 10 $sGap = " " $iLabelWidth = $guiWidth - $iMargin * 2 $hChildGUI = GUICreate("", $iLabelWidth, 20, 10, 10, $WS_CHILD, -1, $hGUI) GUISetFont(12, 400, 0, "Arial") ; Create a label wide enough to hold a long string without truncation $idLabel = GUICtrlCreateLabel($sString, 0, 0, 2000, 20, BitOR($SS_NOPREFIX, $SS_LEFTNOWORDWRAP)) ; Get the string width $tmpLabel = GUICtrlCreateLabel($sString, 0, 0, -1, 20, BitOR($SS_NOPREFIX, $SS_LEFTNOWORDWRAP)) $iStringWidth = ControlGetPos($hChildGUI, "", $tmpLabel)[2] - 9 ; Label is wider than the string width by 9 pixels GUICtrlDelete($tmpLabel) GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_SHOW, $hChildGUI) ; Update the label data if the string width is larger than the label width If $iStringWidth > $iLabelWidth Then GUICtrlSetData($idLabel, $sString & $sGap & $sString) $iScrollPos = 0 $iMarquee = 0 $iScrollDelay = 40 ; AdlibRegister("_Marquee", $iScrollDelay) ; -- setup timer-- Local $hTimerProc = DllCallbackRegister('_Marquee', 'none', 'hwnd;uint;uint_ptr;dword') Local $iTimerID = _WinAPI_SetTimer(0, 0, $iScrollDelay, DllCallbackGetPtr($hTimerProc)) ; ---------------- EndIf MsgBox(64, "Info", "text scrolls") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE ; -- clean timer-- _WinAPI_KillTimer(0, $iTimerID) DllCallbackFree($hTimerProc) ; ---------------- Func _Marquee($hWnd, $iMsg, $iTimerID, $iTime) #forceref $hWnd, $iMsg, $iTimerID, $iTime $iMarquee += 1 If $iMarquee < 3000 / $iScrollDelay Then Return ; 3 seconds of halt when $sString comes to the initial position $iScrollPos -= 1 If - $iScrollPos = $iStringWidth + StringLen($sGap) * 4 Then ; Initialize the $idLabel's position $iMarquee = 0 $iScrollPos = 0 EndIf GUICtrlSetPos($idLabel, $iScrollPos, 0) EndFunc ;==>_Marquee4 points -
Smooth and infinite marquee style scroll of a long string in a short control
pixelsearch and one other reacted to CYCho for a topic
This concept was used in my zPlayer to display long file names in a short label control. #include <GUIConstants.au3> $guiWidth = 300 $hGUI = GUICreate("Main GUI", $guiWidth, 70) $sString = "This is a long string that scrolls smoothly and infinitely in a short label control." ; Create a child GUI for scrolling label $iMargin = 10 $sGap = " " $iLabelWidth = $guiWidth - $iMargin * 2 $hChildGUI = GUICreate("", $iLabelWidth, 20, 10, 10, $WS_CHILD, -1, $hGUI) GUISetFont(12, 400, 0, "Arial") ; Create a label wide enough to hold a long string without truncation $idLabel = GUICtrlCreateLabel($sString, 0, 0, 2000, 20, BitOR($SS_NOPREFIX, $SS_LEFTNOWORDWRAP)) ; Get the string width $tmpLabel = GUICtrlCreateLabel($sString, 0, 0, -1, 20, BitOR($SS_NOPREFIX, $SS_LEFTNOWORDWRAP)) $iStringWidth = ControlGetPos($hChildGUI, "", $tmpLabel)[2] - 9 ; Label is wider than the string width by 9 pixels GUICtrlDelete($tmpLabel) GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_SHOW, $hChildGUI) ; Update the label data if the string width is larger than the label width If $iStringWidth > $iLabelWidth Then GUICtrlSetData($idLabel, $sString & $sGap & $sString) $iScrollPos = 0 $iMarquee = 0 $iScrollDelay = 40 AdlibRegister("_Marquee", $iScrollDelay) EndIf Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func _Marquee() $iMarquee += 1 If $iMarquee < 3000/$iScrollDelay Then Return ; 3 seconds of halt when $sString comes to the initial position $iScrollPos -= 1 If -$iScrollPos = $iStringWidth + StringLen($sGap) * 4 Then ; Initialize the $idLabel's position $iMarquee = 0 $iScrollPos = 0 EndIf GUICtrlSetPos($idLabel, $iScrollPos, 0) EndFunc2 points -
FYI, I tested on other computers. Older computer reacts correctly as it should be expected. Faster (more recent) computer behave exactly as I am experiencing. So this is not related to my own computer. It seems to be another of those timing issues with AutoIt. Sadly not the first, not the last... For those who face the same problem as I have, here a simple solution : #include <GUIConstants.au3> #include <Constants.au3> Example() Func Example() Local $hGUI = GUICreate("Main GUI", 300, 70) GUISetState() Sleep(100) Local $hGUI2 = GUICreate("", 280, 30, 10, 10, $WS_CHILD, -1, $hGUI) GUISetFont(11) Local $idLabel = GUICtrlCreateLabel("This is a test", 0, 0, 100, 30) GUISetState() MsgBox($MB_OK, "", "Test") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;==>Example Slow down the creation of child GUI by putting a Sleep in between. It is working on all computers correctly now.1 point
-
FileExplorer Treeview and Listview (TreeListExplorer)
WildByDesign reacted to Kanashius for a topic
@WildByDesign Thank you very much for the praise, I am glad you like it :). And thanks for finding the bug, I fixed it. It was a missing check for $sPath="" in __TreeListExplorer__OpenPath when checking if the path is a file (and then splitting it), that did overwrite the $sSelect to empty. I also checked, if it is possible to select multiple files/folders, which is working with ListViews and not causing any problems. So I added that to the example. (It looks like it is not possible to enable multiselection for TreeViews, if I did not overlook something... Only thing I saw was enabling checkboxes).1 point -
1 point
-
FileExplorer Treeview and Listview (TreeListExplorer)
WildByDesign reacted to Kanashius for a topic
@WildByDesign I made up my mind and removed the single click expand/collapse. It is now done with a double click. This makes the managing of the selection a lot easier. It is now possible to select folders in the TreeView :). I used the change to adjust the callback parameters to include the selection and added some additional information that was missing (selected index/item handle for clicks; The current path when loading).1 point -
$WS_EX_COMPOSITED seems to help reduce flickers when the adlib time is set to 25. When the time is set to 40, it doesn't seem to help. Maybe it's due to my bad eye sights. Thanks for the hint anyway. As to the string size, creating a temporary label with width set to -1 seems to give precise width. I tried it with diferrent languages and different font weights, and so far, I am happy with the results. According to my observations, the label width is always 9 pixels longer than the actual string size.1 point
-
Understand what you mean now. Here a new version with no flickers. It uses a similar approach of yours. #include <GUIConstants.au3> Local $hGUI = GUICreate("Main GUI", 300, 70) Local $sString = "This is a long string that scrolls smoothly and infinitely without flickers..." GUISetState() Global $iLen = StringLen($sString) * 6.5 ; <<<<< adjust as needed or use M23 UDF StringSize for more precision Local $hGUI2 = GUICreate("", 280, 30, 10, 10, $WS_CHILD, $WS_EX_COMPOSITED, $hGUI) GUISetFont(11) Global $idLabel1 = GUICtrlCreateLabel($sString, 0, 0, $iLen, 30, $SS_LEFTNOWORDWRAP) Global $idLabel2 = GUICtrlCreateLabel($sString, $iLen, 0, $iLen, 30, $SS_LEFTNOWORDWRAP) GUISetState() AdlibRegister(Scroll, 25) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func Scroll() Local Static $iPos = 0 $iPos -= 1 If -$iPos >= $iLen Then $iPos = 0 GUICtrlSetPos($idLabel1, $iPos) GUICtrlSetPos($idLabel2, $iLen + $iPos) EndFunc1 point
-
Nice mate. its possible to reduce the flicker a bit by double buffering. So hope you don't mind - but here's another approach #include <GUIConstants.au3> #include <GDIPlus.au3> #include <WinAPI.au3> Global $iGUIWidth = 300 Global $hGUI = GUICreate("Main GUI", $iGUIWidth, 70) Global $sString = "This is a long string that scrolls smoothly and infinitely in a short label control." Global $iLabW = $iGUIWidth - 8, $iLabH = 30 ;The border style is here to mark the label boundry - for demo purposes! Global $hLabel = GUICtrlCreateLabel("", 4, 4, $iGUIWidth - 8, $iLabH, $WS_BORDER) GUISetState() Global $hLabGraphic, $hBuffGraphic, $hBuffBitMap Global $hBrush, $hFormat, $tLayout, $hFamily, $hFont, $iBkColour _GDIPlus_Startup() ;Graphic of the static control - its possible to draw directly to this, but we'll introduce flicker. $hLabGraphic = _GDIPlus_GraphicsCreateFromHWND(GUICtrlGetHandle($hLabel)) ;Create Buffer - Draw to this. Copy to the label once the image is complete. $hBuffBitMap = _GDIPlus_BitmapCreateFromGraphics($iLabW, $iLabH, $hLabGraphic) $hBuffGraphic = _GDIPlus_ImageGetGraphicsContext($hBuffBitMap) ;Create font etc.. $hBrush = _GDIPlus_BrushCreateSolid(0xFFAA0000) ;ARGB $hFormat = _GDIPlus_StringFormatCreate() $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 12, 3) ;Size, Italic + Bold $iBkColour = BitOR(0xFF000000, _WinAPI_GetSysColor($COLOR_3DFACE)) ;dialog background colour. ; ----- Find dims of the text. --------- Global $iMargin = 4 $tLayout = _GDIPlus_RectFCreate($iMargin, 0, 1, 1) ;Text rectangle. Margin of 4 from left Local $aStrMeasure[4] ;Expand height until we can fit 2 lines ;Sanity checks are required here! This'll break if there's < 2 printable characters in the string. Do $tLayout.Height += 1 $aStrMeasure = _GDIPlus_GraphicsMeasureString($hLabGraphic, $sString, $hFont, $tLayout, $hFormat) Until $aStrMeasure[2] = 2 $tLayout.Height -= 1 ; Gets us the max height of 1 line. ;Expand width until we can fit the entire string. Do $tLayout.Width += 1 $aStrMeasure = _GDIPlus_GraphicsMeasureString($hLabGraphic, $sString, $hFont, $tLayout, $hFormat) Until $aStrMeasure[1] = StringLen($sString) ;Center vertically in the label $tLayout.Y = Floor(($iLabH - $tLayout.Height)/2) ConsoleWrite(StringFormat("text dims: [%d, %d, %d, %d]\r\n", $tLayout.X, $tLayout.Y, $tLayout.Width, $tLayout.Height)) ;-------------------------------------- ;Initial write to label - cause I'm too lazy to fix scrolling logic! _GDIPlus_GraphicsDrawStringEx($hLabGraphic, $sString, $hFont, $tLayout, $hFormat, $hBrush) Local $hTimer = TimerInit(), $iShift = 3 ; $iShift = Pos shift on each iteration. While 1 If GUIGetMsg() = $GUI_EVENT_CLOSE Then ExitLoop ;Pause at string start. If TimerDiff($hTimer) < 2000 Then ContinueLoop ;wipe buffer _GDIPlus_GraphicsClear($hBuffGraphic, $iBkColour) ;Redraw the string at new position. $tLayout.X -= $iShift If ($tLayout.X + $tLayout.Width) < 0 Then ;If we've fallen off the label.. $tLayout.X = $iMargin ;Start at our initial position $hTimer = TimerInit() EndIf _GDIPlus_GraphicsDrawStringEx($hBuffGraphic, $sString, $hFont, $tLayout, $hFormat, $hBrush) ;Copy the buffer to the label _GDIPlus_GraphicsDrawImageRect($hLabGraphic, $hBuffBitMap, 0, 0, $iLabW, $iLabH) Sleep(40) WEnd ;Cleanup _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hBuffGraphic) _GDIPlus_ImageDispose($hBuffBitMap) _GDIPlus_GraphicsDispose($hLabGraphic) _GDIPlus_Shutdown() GUIDelete($hGUI)1 point