garbb Posted January 22, 2014 Share Posted January 22, 2014 I want to have a scrolling log that my script will periodically append lines to. I have done this with a GUI with an edit control but the problem is that an edit control has a limited amount of text that it can hold so I want to keep removing the oldest lines from the edit control when that limit is reached before I add a new line. I have gotten this to work except that it flickers pretty badly and is also slow. Here is my code: expandcollapse popup#include <GuiEdit.au3> #include <WindowsConstants.au3> #include <date.au3> #include <array.au3> #include <GuiListBox.au3> Opt("GUIOnEventMode", 1) Opt("GUIResizeMode", $GUI_DOCKAUTO) $gui_width=1085 $gui_height=483 $Form1 = GUICreate("TEST", $gui_width, $gui_height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP)) $aiwe = GUICtrlCreateEdit("", 0, 0, $gui_width, $gui_height, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY)) _GUICtrlEdit_SetLimitText($aiwe,15000) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM) GUISetState(@SW_SHOW) GUISetOnEvent($GUI_EVENT_CLOSE, "closebuttonfunc") func closebuttonfunc() Exit EndFunc While 1 sleep(100) logout('TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE ') WEnd func logout($msg) $systime=_Date_Time_GetSystemTime() $systime=_Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($systime)) $darray=_Date_Time_SystemTimeToArray($systime) $datetime=StringFormat("%04d/%02d/%02d %02d:%02d:%02d.%03d", $darray[2], $darray[0], $darray[1], $darray[3], $darray[4], $darray[5], $darray[6]) ;below is for limiting the output lines local $logcharlimit=_GUICtrlEdit_GetLimitText($aiwe) local $lines=StringSplit(_GUICtrlEdit_GetText($aiwe),@CRLF,3) local $msgtoadd=$datetime&' '&$msg&@CRLF While StringLen(_ArrayToString($lines,@CRLF)&$msgtoadd)>=$logcharlimit ;if adding the new $msg would put us over the char limit then delete the oldest (top) line _ArrayDelete($lines,0) WEnd _GUICtrlEdit_BeginUpdate($aiwe) _GUICtrlEdit_SetText($aiwe,_ArrayToString($lines,@CRLF)) _GUICtrlEdit_AppendText($aiwe, $msgtoadd) _GUICtrlEdit_EndUpdate($aiwe) _GUICtrlEdit_Scroll($aiwe, 4) EndFunc I understand that the reason for the slowness and flickering is that I am rewriting all the lines into the edit box every time but I couldn't figure out a better way to delete only the top line. Is there a better way? I have tried using a list box control and just removing the top line when the limit of items is reached but that also flickers pretty badly... I was curious of what other apps that have a scrolling log/buffer are using in their GUI's. I used the autoit window info tool on mIRC to see what it was using because it displays text really fast without any flickering and it says it is a class: "static". Not sure what that means... Link to comment Share on other sites More sharing options...
Moderators Solution Melba23 Posted January 22, 2014 Moderators Solution Share Posted January 22, 2014 garbb,This code still flickers a bit, but a lot less than your original on my machine. I have also changed the code to limit the text rewriting as much as possible: expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiEdit.au3> #include <WindowsConstants.au3> #include <date.au3> #include <array.au3> #include <GuiListBox.au3> #include <ScrollBarsConstants.au3> Opt("GUIOnEventMode", 1) Opt("GUIResizeMode", $GUI_DOCKAUTO) $gui_width = 1085 $gui_height = 483 $logcharlimit = 15000 ; Max size of edit $logcharbuffer = 500 ; Buffer to hold 2 x longest expected line $Form1 = GUICreate("TEST", $gui_width, $gui_height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP)) $aiwe = GUICtrlCreateEdit("", 0, 0, $gui_width, $gui_height, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY)) _GUICtrlEdit_SetLimitText($aiwe, $logcharlimit) GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) GUISetState(@SW_SHOW) GUISetOnEvent($GUI_EVENT_CLOSE, "closebuttonfunc") Func closebuttonfunc() Exit EndFunc ;==>closebuttonfunc While 1 Sleep(100) logout('TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE TEST OF A LONG LINE ') WEnd Func logout($msg) $systime = _Date_Time_GetSystemTime() $systime = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($systime)) $darray = _Date_Time_SystemTimeToArray($systime) $datetime = StringFormat("%04d/%02d/%02d %02d:%02d:%02d.%03d", $darray[2], $darray[0], $darray[1], $darray[3], $darray[4], $darray[5], $darray[6]) _GUICtrlEdit_BeginUpdate($aiwe) ; Get line count $iLines_Count = _GUICtrlEdit_GetLineCount($aiwe) ; Check position of first char of last line is not inside buffer If _GUICtrlEdit_LineIndex($aiwe, $iLines_Count - 1) > $logcharlimit - $logcharbuffer Then ; Move down lines until we get to a value greater then the buffer For $i = 1 To $iLines_Count - 1 $iCurrLine_Index = _GUICtrlEdit_LineIndex($aiwe, $i) If $iCurrLine_Index > $logcharbuffer Then ; Select and delete lines to that point _GUICtrlEdit_SetSel($aiwe, 0, $iCurrLine_Index - 1) _GUICtrlEdit_ReplaceSel($aiwe, "", False) ; No point in looking further ExitLoop EndIf Next EndIf ; Text is now smaller by at least twice the buffer size so add new text _GUICtrlEdit_AppendText($aiwe, $datetime & " " & $msg & @CRLF) _GUICtrlEdit_EndUpdate($aiwe) ; Select the last character and scroll it into view _GUICtrlEdit_SetSel($aiwe, -1, -1) _GUICtrlEdit_Scroll($aiwe, $SB_SCROLLCARET) EndFunc ;==>logoutAs all code instructions need to be interpreted, updating every 100 ms without any flickering is asking a lot of any AutoIt GUI - especially when the majority of the GUI is text that needs to be redrawn! M23 garbb 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
garbb Posted January 22, 2014 Author Share Posted January 22, 2014 Wow. Yeah there still is some flickering but your code is significantly better and faster. I guess its because of only deleting the top of the log and good usage of beginupdate and endupdate? Thanks! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 22, 2014 Moderators Share Posted January 22, 2014 garbb,Glad I could help. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted January 22, 2014 Share Posted January 22, 2014 If I add extended style $WS_EX_COMPOSITED to gui (double buffering?) then all flicker is gone for me. $Form1 = GUICreate("TEST", $gui_width, $gui_height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP), $WS_EX_COMPOSITED) Well that is if the mouse cursor is hovering on it, and I've no Idea why that would occur, seems quite odd. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now