Sign in to follow this  
Followers 0
ds34

_GUICtrlRichEdit_SetSel problem

19 posts in this topic

#1 ·  Posted (edited)

I work on a tool that shall provide a coloured log, so I want to append to a RichEdit a multiline string with a dedicated color. Already existing text in the log shall remain unchanged.

To do this I use a wrapper for _GUICtrlRichEdit_AppendText which remebers textlenght before appending the new log portion, adds the new string, selects from the old position till the end of the richedit and then coloures the selection.

Here a small dummy

#include <GuiRichEdit_org.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Global $tAppendTimer=TimerInit()
Main()


Func Main()
    Local $hGui, $hRichEdit, $iMsg
    $hGui = GUICreate("Rich Edit Example", 500, 550, -1, -1,$WS_SIZEBOX )
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "This is a test", 10, 10, 480, 420, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    GUISetState()
    _GUICtrlRichEdit_SetText($hRichEdit,"DANIEL"&@CRLF)

    While True
        $iMsg = GUIGetMsg()
        Select
            Case $iMsg = $GUI_EVENT_CLOSE
                Exit
            Case $iMsg= $GUI_EVENT_RESIZED

    EndSelect
    If TimerDiff($tAppendTimer)>2500 Then
        $tAppendTimer=TimerInit()
        _AddColouredText($hRichEdit,@MON&":"&@MDAY&@CRLF&@TAB&"_"&@HOUR&@MIN&":"&@SEC&@CRLF,Random(0,2,1))
    EndIf
WEnd
EndFunc   ;==>Main

Func _AddColouredText(ByRef $hWnd, $sText="",$iColorNumber = 0)
    $iLength = _GUICtrlRichEdit_GetTextLength($hWnd)
    _GUICtrlRichEdit_AppendText($hWnd,$sText)
    $iLength1 = _GUICtrlRichEdit_GetTextLength($hWnd)
    $bSetSelSuccess=_GUICtrlRichEdit_SetSel($hWnd, $iLength,$iLength1)
    Local $aPos  = _GuiCtrlRichEdit_GetSel($hWnd)
    ConsoleWrite("$SetSelSuccess="&$bSetSelSuccess&" From:"&$iLength&" to:"&$iLength1&"_GetSel:"& $aPos[0] & ","  & $aPos[1]&" @error:"&@error&@CRLF)

    Switch $iColorNumber
        Case -1
            _GUICtrlRichEdit_SetCharColor ($hWnd,'0')
        Case 0
            _GUICtrlRichEdit_SetCharColor ($hWnd,'65280')
        case 1
            _GUICtrlRichEdit_SetCharColor ($hWnd,'16711680')
        case 2
            _GUICtrlRichEdit_SetCharColor ($hWnd,'255')
        case Else
            _GUICtrlRichEdit_SetCharColor ($hWnd,'9500')
    EndSwitch
    Return True

EndFunc   ;==>

However, still the whole output is changing colours. To me it appears that the _GUICtrlRichEdit_SetSel($hWnd, $iLength,$iLength1) is not performing correctly. This seems backed up by the console output:

$SetSelSuccess=True From:16 to:58_GetSel:16,27 @error:0
$SetSelSuccess=True From:58 to:100_GetSel:45,45 @error:0
$SetSelSuccess=True From:100 to:142_GetSel:64,64 @error:0
$SetSelSuccess=True From:142 to:184_GetSel:83,83 @error:0
$SetSelSuccess=True From:184 to:226_GetSel:102,102 @error:0
$SetSelSuccess=True From:226 to:268_GetSel:121,121 @error:0
$SetSelSuccess=True From:268 to:310_GetSel:140,140 @error:0
$SetSelSuccess=True From:310 to:352_GetSel:159,159 @error:0
$SetSelSuccess=True From:352 to:394_GetSel:178,178 @error:0

GetSel shows different Selection than the SetSel was asked to perform.

Any idea what I am doing wrong?

Edited by ds34

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

ds34,

That was a fun debugging session - I know a lot more about RichEdit now, so thanks for the question! :D

You need to use _GUICtrlRichEdit_GetTextLength($hRichEdit, True, True) to get the length of the content in characters. You were getting the length in bytes - i.e 2 x chars - which was messing up your selection counter. It also appears that you need to adjust the total length of the text according to the number of lines - I imagine this is because of the requirement to discount the @CRLF at the end of each line.

Anyway after a great deal of faffing around I found that this code will write coloured lines as I believe you want:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiRichEdit.au3>

Main()

Func Main()
    Local $hGui, $hRichEdit, $iMsg
    $hGui = GUICreate("Rich Edit Example", 500, 550)
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "Test", 10, 10, 480, 420, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    GUISetState()
    _GUICtrlRichEdit_SetText($hRichEdit, "This is some test text" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, 0, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0xFF0000)

    $iEndPoint = _GUICtrlRichEdit_GetTextLength($hRichEdit, True, True) - _GUICtrlRichEdit_GetLineCount($hRichEdit)
    _GUICtrlRichEdit_AppendText($hRichEdit, "And here is a second line" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, $iEndPoint, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0x0000FF)

    $iEndPoint = _GUICtrlRichEdit_GetTextLength($hRichEdit, True, True) - _GUICtrlRichEdit_GetLineCount($hRichEdit)
    _GUICtrlRichEdit_AppendText($hRichEdit, "And now a third" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, $iEndPoint, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0x00FF00)

    _GUICtrlRichEdit_Deselect($hRichEdit)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($hRichEdit)
                Exit
        EndSwitch
    WEnd
    
EndFunc   ;==>Main

Rather more complicated than I thought it would be - (or think it should be - RichEdit is NOT likely to become one of my everyday coding companions! :huggles: ).

I hope this lets you progress in your project.

M23

Edit: Also a pity that, unlike the rest of AutoIt, we have to use BGR and not RGB colours.

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

$iEndPoint = _GUICtrlRichEdit_GetTextLength($hRichEdit, True, True) - _GUICtrlRichEdit_GetLineCount($hRichEdit)
    _GUICtrlRichEdit_AppendText($hRichEdit, "And here is a second line" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, $iEndPoint, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0x0000FF)

Thanks a lot! For my new projects I will use this. Maybe it would be worth to extend the UDF with a wrapper

_GUICtrlRichEdit_AppendText($hWnd,$sText,$sColor) and to update the documentation with the information you discovered!

Share this post


Link to post
Share on other sites

ds34,

I looked into RichEdit a bit more yesterday and the GBR colour requireemnt is because of the internal calls made by the UDF which require a 0x00GGBBRR format.

I do not think you would get much sympathy asking for a new wrapper function - but that does not mean you cannot write one yourself like this: :mellow:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiRichEdit.au3>

Main()

Func Main()
    Local $hGui, $hRichEdit, $iMsg
    $hGui = GUICreate("Rich Edit Example", 500, 550)
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "Test", 10, 10, 480, 420, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    GUISetState()
    _GUICtrlRichEdit_SetText($hRichEdit, "This is some test text" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, 0, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0xFF0000)
    _GUICtrlRichEdit_Deselect($hRichEdit)

    Sleep(2000)

    _GUICtrlRichEdit_WriteLine($hRichEdit, "And here is a second line", 0xFF0000) ; No need to add @CRLF and you can use RGB colours!

    Sleep(2000)

    _GUICtrlRichEdit_WriteLine($hRichEdit, "And now a third", 0x00FF00)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($hRichEdit)
                Exit
        EndSwitch
    WEnd

EndFunc   ;==>Main

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)

    Local $iEndPoint = _GUICtrlRichEdit_GetTextLength($hWnd, True, True) - _GUICtrlRichEdit_GetLineCount($hWnd)
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
     _GUICtrlRichEdit_Deselect($hWnd)

EndFunc

M23


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

@Melba,

I really like the idea of this wrapper and it works great provided the RichEdit control doesn't have any word-wrapped text in it. I've been fighting for a while trying to tweak it to work but for some reason RichEdit goes all skrewy whenever you have word-wrapped text. It totally throws the counts off for _GUICtrlRichEdit_GetTextLength and/or _GUICtrlRichEdit_GetLineCount.

Has anyone else had any luck with colorizing text in a RichEdit control with word-wrapped text in it? In my tests, even text on a new line will be out of phase if it follows any text which has been word-wrapped prior.


[size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]

Share this post


Link to post
Share on other sites

Fr0zT,

Try replacing the _GUICtrlRichEdit_WriteLine function with the version in this script which should account for wordwrapped lines - it does in my tests: :blink:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiRichEdit.au3>

Main()

Func Main()
    Local $hGui, $hRichEdit, $iMsg
    $hGui = GUICreate("Rich Edit Example", 500, 550)
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "Test", 10, 10, 480, 420, _
            BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    GUISetState()
    _GUICtrlRichEdit_SetText($hRichEdit, "This is some very long long long long long long long long long long long long long long long long long test text" & @CRLF)

    _GuiCtrlRichEdit_SetSel($hRichEdit, 0, -1)
    _GuiCtrlRichEdit_SetCharColor($hRichEdit, 0xFF0000)
    _GUICtrlRichEdit_Deselect($hRichEdit)

    Sleep(2000)

    _GUICtrlRichEdit_WriteLine($hRichEdit, "And here is a second line", 0xFF0000) ; No need to add @CRLF and you can use RGB colours!

    Sleep(2000)

    _GUICtrlRichEdit_WriteLine($hRichEdit, "And now a very long long long long long long long long long long long long long long long long long long third", 0x00FF00)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($hRichEdit)
                Exit
        EndSwitch
    WEnd

EndFunc   ;==>Main

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)

    ; Get the UDF line count
    Local $iUDFLines = _GUICtrlRichEdit_GetLineCount($hWnd)
    ; Count the @CRLF
    Local $iDump = StringReplace(_GUICtrlRichEdit_GetText($hWnd, True), @CRLF, "")
    ; Determine the correct adjustment
    Local $iAdjust = $iUDFLines - @extended

    Local $iEndPoint = _GUICtrlRichEdit_GetTextLength($hWnd, True, True) - $iAdjust
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
     _GUICtrlRichEdit_Deselect($hWnd)

EndFunc

I like RichEdits less each time I play with them! ;)

M23


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

Hmmm.... Still doesn't work for me. What's interesting is how the offset seems to be incremented every time there is a word wrap...

#include <GuiRichEdit.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Color.au3>

Opt('MustDeclareVars', 1)

Global $lblMsg, $hRichEdit

Main()

Func Main()
    Local $hGui, $iMsg, $btnNext, $iStep = 0, $lastendpoint, $iEndPoint
    $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName,4) & ")", 320, 350, -1, -1)
    $hRichEdit = _GUICtrlRichEdit_Create($hGui, "", 10, 10, 300, 220, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    GUISetState()

    _GUICtrlRichEdit_WriteLine($hRichEdit,"ASDF  fj aslfj skldjf lkdsjf jaskdjf lsjdfldsjflasldsjf llskjlg fsdfsdffdsdsfghjf lskjdf lskdjf lskdjflkjlg ashd")
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ABC",0x00FF00)
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ASDF  fj aslfj skldjf lkdsjf jaskdjf lsjdfldsjflasldsjf llskjlg fsdfsdffdsdsfghjf lskjdf lskdjf lskdjflkjlg ashd")
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ABC",0xFF0000)
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ASDF  fj aslfj skldjf lkdsjf jaskdjf lsjdfldsjflasfj asldj fdsjf ldsjffdsdsfghjf lskjdf lskdjf lskdjflkjlg ashd")
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ABC",0xFFFF00)
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ASDF  fj aslfj skldjf lkdsjf jaskdjf lsjdfldsjflasfj asldj fdsjf ldsjffdsdsfghjf lskjdf lskdjf lskdjflkjlg ashd")
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ABC",0x00FF00)
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ASDF  fj aslfj skldjf lkdsjf jaskdjf lsjdfldsjflasfj asldj fdsjf ldsjffdsdsfghjf lskjdf lskdjf lskdjflkjlg ashd")
    _GUICtrlRichEdit_WriteLine($hRichEdit,"ABC" ,0x00FF00)

    While True
        $iMsg = GUIGetMsg()
        Select
            Case $iMsg = $GUI_EVENT_CLOSE
                GUIDelete()
                Exit
        EndSelect
    WEnd
EndFunc

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)
    ; Get the UDF line count
    Local $iUDFLines = _GUICtrlRichEdit_GetLineCount($hWnd)
    ; Count the @CRLF
    Local $iDump = StringReplace(_GUICtrlRichEdit_GetText($hWnd, True), @CRLF, "")
    ; Determine the correct adjustment
    Local $iAdjust = $iUDFLines - @extended

    Local $iEndPoint = _GUICtrlRichEdit_GetTextLength($hWnd, True, True) - $iAdjust
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
     _GUICtrlRichEdit_Deselect($hWnd)
EndFunc

[size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

OK, I figured it out, this is actually working for me.

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)
    ; Get the UDF line count
    Local $iUDFLines = _GUICtrlRichEdit_GetLineCount($hWnd)
    ; Count the @CRLF
    Local $iDump = StringReplace(_GUICtrlRichEdit_GetText($hWnd, True), @CRLF, "")
    ; Determine the correct adjustment
    Local $iLines = @extended
    Local $iAdjust = $iUDFLines - $iLines
    Local $iEndPoint = _GUICtrlRichEdit_GetTextLength($hWnd, True, True) - $iAdjust
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint-($iLines-$iAdjust), -1)
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
     _GUICtrlRichEdit_Deselect($hWnd)
EndFunc

Melba, thanks for that last revision! I don't know why I never thought to attempt that approach but that was the key.

Edited by Fr0zT

[size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]

Share this post


Link to post
Share on other sites

Fr0zT,

Glad I could help. :blink:

M23


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

Fr0zT,

After a bit more testing I believe you can simplify the function even more: :blink:

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)

    ; Count the @CRLFs
    StringReplace(_GUICtrlRichEdit_GetText($hWnd, True), @CRLF, "")
    Local $iLines = @extended
    ; Adjust the text char count to account for the @CRLFs
    Local $iEndPoint = _GUICtrlRichEdit_GetTextLength($hWnd, True, True) - $iLines
    ; Add new text
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    ; Select text between old and new end points
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
    ; Convert colour from RGB to BGR
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    ; Set colour
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
    ; Clear selection
    _GUICtrlRichEdit_Deselect($hWnd)

EndFunc

M23


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

If you just want to colorize the newly added line you can find the start of it an even easier way (and much less calculation needed if dealing with a large amount of data since it doesn't need to get and analyze the entire rich edit's contents for every line you append).

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText, $iColor = 0)

    ; Find the end of the existing text
    Local $iEndPoint = _GUICtrlRichEdit_FindText($hWnd, @CR,False)
    ; Add new text
    _GUICtrlRichEdit_AppendText($hWnd, $sText & @CRLF)
    ; Select text between old and new end points
    _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
    ; Convert colour from RGB to BGR
    $iColor = Hex($iColor, 6)
    $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
    ; Set colour
    _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
    ; Clear selection
    _GUICtrlRichEdit_Deselect($hWnd)

EndFunc

First I tried finding @CRLF since that's what is at the end of the append text but it didn't work. Searching for @CR backwards works great though. I found this post because I'm trying to do something very similar with displaying a log in the main gui, but instead of changing the color of an entire line that's added, I want to change the color of pieces of it based on a regex (so it'll look more like syntax highlighting). It's times like these that I'd kill for a python dictionary object in autoit.

Share this post


Link to post
Share on other sites

C2i,

Excellent! :blink:

M23


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

It works as long as the @CRLF is added to the string after the string, if it's added before then the command to search for @CR would need to happen after the string is appended.

Not sure what would be the best approach to highlight certain words or elements of the string that's added. I def like the idea of making it a wrapper. Could even make your wrapper into a multi-functional one. Most efficient syntax I've come up with so far would be:

_GUICtrlRichEdit_WriteLine($hWnd, $sText, $vColor = 0)

where $vColor could be either an integer color or a 2 dimensional array that has $vColor[$i][0] as a regex search string like "(\d*)" to do all digits, or "\[(.+)\]" to do text that's between a [ and a ], or something to select a date or time, etc etc. Then $vColor[$i][1] would contain the integer color that things that match the regex would get. The order in the array would matter too in case some things match multiple regex's

So essentially it'd be a double wrapper that wraps the append text to rich edit as well as the StringRegExp function.

2 different methods to start from I can think of are:

A) append the string then go back and select the elements that match the regex's and change their colors

:blink: chop up the string before it's appended according to the regex's and then append it piece by piece changing the color of each piece as it goes.

:idea:Ideas, thoughts, suggestions?

Share this post


Link to post
Share on other sites

C2i,

Feel free to modify that wrapper function as much as you want - everything I post here is available for all to plunder as they wish. ;)

I would definitely go for the second of your 2 options - from my limited experience of RichEdit controls, the less you have to mess around with the content the better! So sorting out the different sections of the line before adding them gets my vote. :blink:

Quite frankly, I dislike RichEdit controls more each time I try to help someone with the dratted things. Just like SREs! :

Give your idea a go - despite my comments above I am happy to help if you run into problems, not that I expect you will. :P

M23


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

Do you know if there's a way to preformat text that's being applied to a richedit? I know you can copy rtf with formating and paste it and it'll maintain formatting (like color). _GUICtrlRichEdit_StreamToFile() has an option that :

$fIncludeCOM [optional] True (default): If writing to a .rtf file, includes any COM objects (space consuming). If writing to any other file, writes a text represntation of COM object.

No matter what I do I can't seem to get it to write anything to a .txt file that has any more data then the text itself. If we knew what the text representation of COM objects for color looked like, do you know if it's possible to include that in a string that is appended and it'll convert it to COM data? Or another approach would be to use the copy/paste method and paste text into the richedit instead of appending it. But I have no idea how to apply the desired formatting to a string prior to sending it to the clipboard.

Also do you know of an easy way to get the value for a color? Think I'd like to include a 'library' of common colors and their values so that if the value in the color variable is text instead of numbers it looks up the specified color.

Share this post


Link to post
Share on other sites

C2i,

I have no idea about RichEdits other than the few basic cripts I have written to help others. Perhaps if you started a new thread you might attract the attention of the authors who will be more able to help you. ;)

As for you r other question, search Google for "colour values" and you will find many libraries. :blink:

M23


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

#17 ·  Posted (edited)

Got it :blink:

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText,$vColor = 0)
    Local $iColor
    _GUICtrlRichEdit_AppendText($hWnd,@CRLF & $sText)
    Local $iEndPoint = _GUICtrlRichEdit_FindText($hWnd, @CR,False)
    If $vColor <> 0 Then
        If IsArray($vColor) Then ;regex mode
            _GuiCtrlRichEdit_SetSel($hWnd,$iEndPoint,-1)
            _GuiCtrlRichEdit_SetCharColor($hWnd, 0)
            For $i = 0 To UBound($vColor)-1
                Local $iStart = $iEndPoint ;reset begining
                $iColor = Hex($vColor[$i][1], 6) ; Convert colour from RGB to BGR
                $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
                $aRegFound = StringRegExp($sText,$vColor[$i][0],3)
                If Not @error Then
                    For $j = 0 To UBound($aRegFound)-1
                        Local $aLoc = _GUICtrlRichEdit_FindTextInRange($hWnd,$aRegFound[$j],$iStart,-1,True,True)
                        _GuiCtrlRichEdit_SetSel($hWnd,$aLoc[0],$aLoc[1])
                        _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
                        _GUICtrlRichEdit_Deselect($hWnd)
                        $iStart = $aLoc[1]
                    Next
                EndIf
            Next
        Else ;paint the whole line;
            $iColor = Hex($vColor, 6); Convert colour from RGB to BGR
            $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
            _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
            _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor); Set colour
            _GUICtrlRichEdit_Deselect($hWnd); Clear selection
        EndIf
    EndIf
EndFunc

Array can be something like:

$vColor[5][2] = [["(?:\h|\(|,)(\d+(?:\x2e\d+)?)(?:\)|\s|\r|,|\x2e)?",0xFF0000], _
                            ["\[(.*?)(?:\(\d+\))?\]",0x0000FF], _
                            ["\]\s(.+)\s>",0x808040], _
                            ["SYSTEM",0x8000FF], _
                            ["((?:\d{1,2}:\d{1,2}:\d{1,2}\h?(?:AM|PM)?)(?: \d{1,2}/\d{1,2}/\d{1,4})?)",0x008080]]

Careful with the regex's, they can be feisty.

Should also note that the captures in the regex are what gets colored. Also, if 2 regex's overlap eachother then the one furthest down the array is the winner.

Edited by C2i

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

This one allows the 2d array for $vColor to have 3 columns, $aColor[#][0] = a regex, $aColor[#][1] = character color to set the matches, $aColor[#][2] = background color to set for matches.

Func _GUICtrlRichEdit_WriteLine($hWnd, $sText,ByRef Const $vColor)
    Local $iColor,$iBkColor
    _GUICtrlRichEdit_AppendText($hWnd,@CRLF & $sText)
    Local $iEndPoint = _GUICtrlRichEdit_FindText($hWnd, @CR,False)
    If $vColor <> 0 Then
        If IsArray($vColor) Then ;regex mode
            _GuiCtrlRichEdit_SetSel($hWnd,$iEndPoint,-1)
            _GuiCtrlRichEdit_SetCharColor($hWnd, 0)
            For $i = 0 To UBound($vColor)-1
                Local $iStart = $iEndPoint ;reset begining
                $iColor = Hex($vColor[$i][1], 6) ; Convert colour from RGB to BGR
                $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
                If  $vColor[$i][2] <> '' Then
                    $iBkColor = Hex($vColor[$i][2], 6)
                    $iBkColor = '0x' & StringMid($iBkColor, 5, 2) & StringMid($iBkColor, 3, 2) & StringMid($iBkColor, 1, 2)
                Else
                    $iBkColor = ''
                EndIf
                $aRegFound = StringRegExp($sText,$vColor[$i][0],3)
                If Not @error Then
                    For $j = 0 To UBound($aRegFound)-1
                        Local $aLoc = _GUICtrlRichEdit_FindTextInRange($hWnd,$aRegFound[$j],$iStart,-1,True,True)
                        _GuiCtrlRichEdit_SetSel($hWnd,$aLoc[0],$aLoc[1],True)
                        _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor)
                        If $iBkColor <> '' Then _GUICtrlRichEdit_SetCharBkColor($hWnd, $iBkColor)
                        _GUICtrlRichEdit_Deselect($hWnd)
                        $iStart = $aLoc[1]
                    Next
                EndIf
            Next
        Else ;paint the whole line;
            $iColor = Hex($vColor, 6); Convert colour from RGB to BGR
            $iColor = '0x' & StringMid($iColor, 5, 2) & StringMid($iColor, 3, 2) & StringMid($iColor, 1, 2)
            _GuiCtrlRichEdit_SetSel($hWnd, $iEndPoint, -1)
            _GuiCtrlRichEdit_SetCharColor($hWnd, $iColor); Set colour
            _GUICtrlRichEdit_Deselect($hWnd); Clear selection
        EndIf
    EndIf
EndFunc

Here's an example array i'm using:

Global Const $aColor[7][3] = [["(?:\h|\(|,)(\d+(?:\x2e\d+)?)(?:\)|\h|\r|,|\x2e)?",0x800000], _
                            ["\[(.*?)(?:\(\d+\))?\]",0x0000FF], _
                            ["\]\h(.+)\h>",0x8000FF], _
                            ["SYSTEM",0xFF0000], _
                            ["FAIL",0xFFFFFF,0xFF0000], _
                            ["SUCCESS",0,0x00FF00], _
                            ["(\d+:\d{1,2}:\d{1,2})\h?(AM|PM)?\h?(\d{1,2}/\d{1,2}/\d{1,4})?",0x008080]]

Which makes numbers dark red, elements in [ ] blue (unless that element is "SYSTEM" in which case makes that red), elements after a ] and before a > purple, the word "FAIL" to be while but the background of it red, "SUCCESS" has a green background, and dates and times are teal. :blink: Works most of the time, the first row that changes numbers to dark red can sometimes change everything previous to dark red, hence the complication in an attempt to prevent that (which still happens occasionally), but the rest works great.

Edited by C2i

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Solution posted by Fr0zT seems to be working good.

Solution posted by C2i will work unless same string is added more than once.

In both cases the font is reset to default so you will need to use

_GUICtrlRichEdit_SetFont again after adding a line.

Edited by line333

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