Sign in to follow this  
Followers 0
buymeapc

How to speed up a loop with a RichEdit?

11 posts in this topic

Hi all,

I'm trying to speed up a loop that goes through a rich edit control that has a couple thousand lines of text and select/hilight the lines. The current way I have it set up, it takes almost 3 seconds to go through the list of 2000 lines. If I increase the amount of lines, it could take much longer, too. How could I make this faster? Here's a quick example:

#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
Dim $aLines[2000][2]
Dim $text = "This is a line."&@CRLF
OnAutoItExitRegister("_Exit")
$Form1 =  GUICreate("Test", 700, 520)
$hEdit1 =  _GUICtrlRichEdit_Create($Form1, "", 1, 21, 698, 478, BitOR($ES_MULTILINE, $WS_VSCROLL, $WS_HSCROLL, $ES_AUTOVSCROLL, $ES_READONLY))
$Test =  GUICtrlCreateButton("Test", 0, 0, 70, 20)
$time =  GUICtrlCreateLabel("", 10, 505, 1000, 21)
_GUICtrlRichEdit_PauseRedraw($hEdit1)
For $x = 1 To 2000
_GUICtrlRichEdit_AppendText($hEdit1, $text)
$aLines[$x-1][0] = $text
$aLines[$x-1][1] = 0x00FF00; Green
Next
_GUICtrlRichEdit_ResumeRedraw($hEdit1)
_GUICtrlRichEdit_ScrollLineOrPage($hEdit1, "ld"); Added this so the page would show the text instead of blank area after redraw
GUISetState()
While 1
$msg = GUIGetMsg()
Select
  Case $msg = $GUI_EVENT_CLOSE
   ExitLoop
  Case $msg = $Test
   $sTime = TimerInit()
   _GUICtrlRichEdit_PauseRedraw($hEdit1)
   For $l = 0 To UBound($aLines)-1
    If $aLines[$l][0] <> "" Then
     $iFirst = _GUICtrlRichEdit_GetFirstCharPosOnLine($hEdit1, $aLines[$l][0])
     $iLen = _GUICtrlRichEdit_GetLineLength($hEdit1, $aLines[$l][0])
     _GUICtrlRichEdit_SetSel($hEdit1, $iFirst, $iFirst+$iLen, True)
     _GUICtrlRichEdit_SetCharBkColor($hEdit1, $aLines[$l][1])
    EndIf
   Next
   _GUICtrlRichEdit_ResumeRedraw($hEdit1)
   GUICtrlSetData($time, TimerDiff($sTime))
EndSelect
WEnd
Func _Exit()
_GUICtrlRichEdit_Destroy($hEdit1)
EndFunc

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

what is your primary goal?

1) Select all the text

2) Select specific lines

3) set the background color of the font

What do you want to archive with selecting all the text?

Edited by qsek

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

My ultimate goal is to be able to display a log of varying size in the rich edit and be able to have certain lines that contain keywords colored. Every time I poll the log, however, I have to re-color all the lines all over again and this can take a very long time depending on what's being colored. My exact code with what I want to do is in this To test it, just click the open button and point it to a large log file.

Share this post


Link to post
Share on other sites

Ok i might speculate here but i am quite certain that a RichEdit Control is not the right way of displaying and managing large Logfiles.

Especially if it is controlled by AutoIt, which is another (maybe the biggest) performance bottleneck.

I think you wont be satisfied with any possible control, if autoit have to go through 10000k loops anytime you want to update the logfile.

The best thing i know is a listview. There is a mode of dealing with them where you can put all the data in an array and pass this as whole to the listview. Then the listview internally reads from the array only those values that are currently displayed. If you want to update items, you update the array, not the listview.

Blazing fast scrolling, coloring of subitems and sorting, but not easy to understand.

Im not sure if there is an UDF. There wasn't last time i checked. I think i have a working script somewhere, or maybe another one knows more about this listviewmode. I dont even know the exact term anymore.


Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

Hmmm...I passed over listview controls for rich edit controls because I thought the displaying of the large (sometimes huge) log files was quicker that way. I've worked with listviews quite a bit recently and they can be rather cumbersome if they get too big, which is why I went the rich edit route. I would love a working example if you have one. Wait...are you thinking of _GUICtrlListView_AddArray()?

Thanks

Share this post


Link to post
Share on other sites

Nono,

They are called Virtual Listviews

I even made a topic once about that and forgot about it ;)

you can search this in the forums or LVS_OWNERDATA

Its the style you set when you want to operate the listview in this mode.


Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Forgot to add my topic:
/'?do=embed' frameborder='0' data-embedContent>>

Edit: Found another example, maybe suited better for you (lots of items)
>http://www.autoitscript.com/forum/topic/...iew-item/page__view__findpost_

I think i used this as source for my low CPU approach

Edited by qsek

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

Wow. This is great stuff! Thanks qsek! I am having some issues with trying to get certain lines that have keywords in this (virtual) listview colored - like you have in your example. Is there a way to do that outside of the WM_NOTIFY function?

Share this post


Link to post
Share on other sites

not with virtual listviews. But is is already made in the WM_NOTIFY function. Look at

Case $NM_CUSTOMDRAW

Switch $iDrawStage

Case $CDDS_ITEMPREPAINT

DllStructSetData($tCustDraw, 'clrText', 0x000000)

DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF)

Those 2 lines set the fore and backgroundcolor of the item that is being drawed.

All you have to do is add a Stringsearch that searches your arrayitem for the keyword and then set the color if matched

1 person likes this

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

Ok, I'm trying to wrap my head around this still.

In your example, I see you change the color of all the lines. I guess what I'm not understanding is how do I only change the color using DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF) of a single line that meets my criteria?

Share this post


Link to post
Share on other sites

Ok, nevermind. I finally got it....didn't have enough coffee yet. I realized that the WM_NOTIFY would follow an array of colors if I create it. So, all I did was create a second array with the same size of the array that contains the file lines and apply the colors of each line to the second array based upon the search criteria.

Bottom line: I was making it more difficult than it needed to be.

Thanks for all your help!!

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
Sign in to follow this  
Followers 0