Sterikics

FIFO style read only edit box

4 posts in this topic

I am trying to make a control where in I can output a log of what my script is doing. I am using a edit control with read-only style set. I limited the gui ctrl text to only 1000 char to quickly bring the limit for testing purposes. When the limit is reached, it stops appending new data. I would like to instead have the first line deleted to limit the data. The ulimate use of my script will have 100's of thousands of lines with strings hundreds of lines long being generated, so I would like to limit what is in the control to save memory.

I suppose I could use an array to keep a FIFO log and just update the control with that, but it seems pretty intensive especially if I want a long log to scroll thru.

;Modified from AutoIt built-in examples.
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
   GUICreate("My GUI edit")

   Local $idMyedit = GUICtrlCreateEdit("Line 1" & @CRLF, 176, 32, 121, 97, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_READONLY)
   GUICtrlSetLimit($idMyedit, 1000)
   GUISetState(@SW_SHOW)

   Send("{END}")

   GUICtrlSetData($idMyedit, "Line 2", 1)
   Local $count = 2
   While 1
      $count += 1
      GUICtrlSetData($idMyedit, "Line " & $count, 1)
      Sleep(10)
      Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
            ExitLoop
      EndSwitch
   WEnd
   GUIDelete()
EndFunc

 

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Sterikics,

I would do something like this:

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

Example()

Func Example()

    Local $iMaxSize = 500

    GUICreate("My GUI edit", 500, 500)

    Local $idMyedit = GUICtrlCreateEdit("Line count 1" & @CRLF, 10, 10, 300, 300, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL, $ES_READONLY)) ; Note correct way to combine styles
    GUICtrlSetLimit($idMyedit, $iMaxSize)
    GUISetState(@SW_SHOW)

    GUICtrlSetState($idMyedit, $GUI_FOCUS) ; Better than sending "{END}"

    $iCount = 1
    $nBegin = TimerInit() ; Set timestamp

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

        EndSwitch



        ; When delay elapsed
        If TimerDiff($nBegin) > 500 Then
            $iCount += 1
            ; Get size fo current content and new data
            $sData = "Line count " & $iCount & @CRLF
            $sContent = GUICtrlRead($idMyedit)
            ; If sum too large for edit
            If StringLen($sContent) + StringLen($sData) > $iMaxSize Then
                ; Trim the start of the content and reinsert
                $sContent = StringTrimLeft($sContent, StringLen($sData))
                GUICtrlSetData($idMyedit, $sContent)
            EndIf

            ; Add new data
            GUICtrlSetData($idMyedit, "Line count " & $iCount & @CRLF, 1)
            ; Reset timestamp
            $nBegin = TimerInit()
        EndIf



    WEnd



    GUIDelete()

EndFunc   ;==>Example

I made a few other changes as well - please ask if you have any questions as to why or what I did.

M23

P.S. Welcome to the AutoIt forums.

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Melba23

     Thank you for the welcoming. I appreciate the edits, especially the BitOR function to combined styles. That makes better sense mathematically to me. I like this idea and will run with it. 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Sterikics,

Another take on your task.  This one is line, not character, oriented.  All writing to the control is done through a function.  Regex does the heavy lifting.  I tested this buffering 1000 lines and writing 10 lines/sec to the edit control.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiEdit.au3>
#include <array.au3>
#include <ScrollBarsConstants.au3>

Local $iLinesToBuffer = 1000
Local $iLineCount

Local $sBuffer

local $ret

GUICreate("My GUI edit", 500, 500)

Local $idMyedit = GUICtrlCreateEdit('', 10, 10, 480, 300, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_READONLY))
$ret = GUICtrlSetLimit(-1, 999999999)
ConsoleWrite($ret & @CRLF)
Local $btn0010 = GUICtrlCreateButton('Start Populating Edit Control', 10, 400, 480, 20)
Local $InsButton = GUICtrlCreateButton('Insert Test Text', 10, 430, 480, 20)

GUISetState(@SW_SHOW)

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $btn0010
            If StringLeft(GUICtrlRead($btn0010), 5) = 'Start' Then
                GUICtrlSetData($btn0010, 'Stop Populating Edit Control')
                AdlibRegister('_populate_edit_control', 100)
            Else
                GUICtrlSetData($btn0010, 'Start Populating Edit Control')
                AdlibUnRegister('_populate_edit_control')
            EndIf

        Case $InsButton

            _Log('Have a nice Day!')
    EndSwitch



WEnd



Func _Log($str)

    $iLineCount = _GUICtrlEdit_GetLineCount($idMyedit)
    $sBuffer = ''
    If $iLineCount + 1 > $iLinesToBuffer Then
        $sBuffer = stringregexpreplace(guictrlread($idMyedit), '(*ANYCRLF)^(.*\R){' & $iLineCount - $iLinesToBuffer & '}', '')
        GUICtrlSetData($idMyedit, $sBuffer & $str & @CRLF) ;    rewrite the edit control
        _GUICtrlEdit_Scroll($idMyedit, $SB_SCROLLCARET)
    Else
        GUICtrlSetData($idMyedit, $str & @CRLF, 1) ;    append text at insertion point
    EndIf



EndFunc   ;==>_Log

Func _populate_edit_control()

    Local $sTmp

    Local Static $iLine = 1
    For $i = 1 To Random(10, 100, 1)
        $sTmp &= Chr(Random(65, 90, 1))
    Next
    _Log('Line ' & $iLine & ' - ' & $sTmp)
    $iLine += 1

EndFunc   ;==>_populate_edit_control

kylomas

Edited by kylomas
add auto scroll to bottom

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
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