Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - screenshot.png

Introduction

Hello again. This time I wanted to bring you something that was really challenging for me to build. I must have tried at least four totally different solutions to this problem consuming literally days of my time until I reached the best one. At the request of our beloved staff, I will attempt to explain :-)

This class is an extension of a wrapper to the RichEdit control that ships with .NET. How it achieves its speed and also its slickness is by directly modifying the RTF document behind the scenes.

Please note

I am aware that the regex matching can produce unwanted results. 99 out of 100 times, it's the regex pattern you are using. Example: the pattern "<IMG.*>" is wrong. It will only match the FIRST image tag in the document, the proper format is "<IMG.*?>". You need to test your regex's out before you put them in the code otherwise you may get unwanted results.

You can use the RegEx tool Expresso, get it here. My thanks go out to Jim Hollenhorst for making such a great tool. Without Expresso, this project would not be as far along as it is.

The UI code:

First, I will tell you how to use this class in your program. Then I will outline how the class actually gets the job done. To initialize the wrapper is really quite simple. All that is to be done is call New on the class, specifying that you want its events as well. You can accomplish this like so:

Private WithEvents RTBWrapper As New cRTBWrapper

This creates a new instance of the class. However, there is one more important thing you need to do. You need to bind the control to the rich textbox. This can be done in the onLoad Sub or wherever you like.

RTBWrapper.bind(RTB)

Next, you can fill it with whatever you want, syntax from an XML document containing keywords for your programming language, whatever. For this example, I will give it just a few words to "look" for. You could make an initialization Sub to load all this or you could put it in onLoad as well, like so:

    .rtfSyntax.add("<span.*?>", True, True, Color.Red.ToArgb)
    .rtfSyntax.add("<p.*>", True, True, Color.DarkCyan.ToArgb)
    .rtfSyntax.add("<a.*?>", True, True, Color.Blue.ToArgb)
    .rtfSyntax.add("<table.*?>", True, True, Color.Tan.ToArgb)
    .rtfSyntax.add("<tr.*?>", True, True, Color.Brown.ToArgb)
    .rtfSyntax.add("<td.*?>", True, True, Color.Brown.ToArgb)
    .rtfSyntax.add("<img.*?>", True, True, Color.Red.ToArgb)
    .rtfSyntax.add("codeproject", False, True, Color.Red.ToArgb)
    .rtfSyntax.add("not regex and case sensitive", _
                         false, False, Color.Red.ToArgb)

You can also toggle the debug view, I like doing this in a menu and use the code.

sender.checked = RTBWrapper.toggleDebug()

There is also an event that you can hook into, that will report the current positions of the caret within the window.

Private Sub RTBWrapper_position(ByVal PositionInfo _
                As cRTBWrapper.cPosition) Handles RTBWrapper.position
    StatusBar1.Text = "Cursor: " & PositionInfo.Cursor & _
                      ",  Line: " & PositionInfo.CurrentLine & _
                      ", Position: " & PositionInfo.LinePosition
End Sub

You also need to add the method colorDocument to the document load function.

Private Sub mnuOpen_Click(ByVal sender As System.Object,_
               ByVal e As System.EventArgs) Handles mnuOpen.Click
    If OpenDialog.ShowDialog Then
        RTB.LoadFile(OpenDialog.FileName, RichTextBoxStreamType.PlainText)
        RTBWrapper.colorDocument()
    End If
End Sub

You can also hook in to the syntax editor. (The syntax editor is just a quick hack. After all, this is just a demo project.)

    Private Sub MenuItem4_Click(ByVal sender As System.Object, _
              ByVal e As System.EventArgs) Handles MenuItem4.Click
        Dim syntaxView As New cRTFSyntax
        syntaxView.colSyntax = RTBWrapper.rtfSyntax

        If syntaxView.ShowDialog = DialogResult.OK Then
            RTBWrapper.rtfSyntax = syntaxView.colSyntax
        End If

        RTBWrapper.colorDocument()
    End Sub

Completed UI code:

    Private WithEvents RTBWrapper As New cRTBWrapper

    Private Sub Form1_Load(ByVal sender As System.Object, _
               ByVal e As System.EventArgs) Handles MyBase.Load
        With RTBWrapper
            .bind(RTB)
            .rtfSyntax.add("<span.*?>", True, True, Color.Red.ToArgb)
            .rtfSyntax.add("<p.*>", True, True, Color.DarkCyan.ToArgb)
            .rtfSyntax.add("<a.*?>", True, True, Color.Blue.ToArgb)
            .rtfSyntax.add("<table.*?>", True, True, Color.Tan.ToArgb)
            .rtfSyntax.add("<tr.*?>", True, True, Color.Brown.ToArgb)
            .rtfSyntax.add("<td.*?>", True, True, Color.Brown.ToArgb)
            .rtfSyntax.add("<img.*?>", True, True, Color.Red.ToArgb)
        End With
    End Sub

    Private Sub RTBWrapper_position(ByVal PositionInfo As _
              cRTBWrapper.cPosition) Handles RTBWrapper.position
        StatusBar1.Text = "Cursor: " & PositionInfo.Cursor & _
           ",  Line: " & PositionInfo.CurrentLine & _
           ", Position: " & PositionInfo.LinePosition
    End Sub

    Private Sub mnuOpen_Click(ByVal sender As System.Object,_
             ByVal e As System.EventArgs) Handles mnuOpen.Click
        If OpenDialog.ShowDialog Then
            RTB.LoadFile(OpenDialog.FileName, RichTextBoxStreamType.PlainText)
            RTBWrapper.colorDocument()
        End If
    End Sub

    Private Sub MenuItem3_Click(ByVal sender As System.Object, _
              ByVal e As System.EventArgs) Handles MenuItem3.Click
        sender.checked = RTBWrapper.toggleDebug()
    End Sub

    Private Sub mnuSave_Click(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles mnuSave.Click
        If SaveDialog.ShowDialog Then
            RTB.SaveFile(SaveDialog.FileName, RichTextBoxStreamType.PlainText)
        End If
    End Sub

    Private Sub mnuExit_Click(ByVal sender As System.Object, _
                   ByVal e As System.EventArgs) Handles mnuExit.Click
        Me.Close()
    End Sub

    Private Sub mnuNew_Click(ByVal sender As System.Object,_
              ByVal e As System.EventArgs) Handles mnuNew.Click
        RTB.Text = ""
        RTB.Rtf = ""
    End Sub

    Private Sub mnuWordWrap_Click(ByVal sender As System.Object,_
                 ByVal e As System.EventArgs) Handles mnuWordWrap.Click
        RTB.WordWrap = Not RTB.WordWrap
        sender.checked = RTB.WordWrap
    End Sub

    Private Sub MenuItem4_Click(ByVal sender As System.Object,_
               ByVal e As System.EventArgs) Handles MenuItem4.Click
        Dim syntaxView As New cRTFSyntax
        syntaxView.colSyntax = RTBWrapper.rtfSyntax

        If syntaxView.ShowDialog = DialogResult.OK Then
            RTBWrapper.rtfSyntax = syntaxView.colSyntax
        End If

        RTBWrapper.colorDocument()
    End Sub

    Private Sub mnuColor_Click(ByVal sender As System.Object,_
              ByVal e As System.EventArgs) Handles mnuColor.Click
        RTBWrapper.colorDocument()
    End Sub
View Sample Screen Shot

There have been several updates to the class, I will post them when everything's finalized.

Very high-level diagram of the way the code works.

The class code:

First and probably most important are the Import directives. The RegularExpression direction is obvious because we are going to be using regular expressions in this class. The second directive of InteropServices.Marshal are so we can hook into the GetLastWin32Error method for the API functions. If you would like to read more about what we are using the API for, please see the Scrolling with API article.

Imports System.Text.RegularExpressions
Imports System.Runtime.InteropServices.Marshal

The class begins by creating three other classes for storage, these are called cList, cDictionary and cPosition. The first two classes (cList and cDictionary) are just standard run of the mill everyday collection classes for storing color information. The third class cPosition stores the cursors position information.

    Public Class cPosition
        Public Cursor As Integer
        Public CurrentLine As Integer
        Public LinePosition As Integer
        Public xScroll As Integer
        Public yScroll As Integer
    End Class

Let's start with where it all begins, with the update on the cursor position. We have declared the variable _bind. _bind is a reference to the RTB control. _bind was imported with events as such. We can hook in to those events using AddHandler.

        AddHandler _bind.KeyUp, AddressOf update
        AddHandler _bind.MouseUp, AddressOf update
        AddHandler _bind.TextChanged, AddressOf update

We have hooked into the KeyUp, MouseUp and TextChanged events of the control. These events, when they occur, call the overloaded update procedure. Why overloaded? Well, when these events call that Sub, they each call it with different parameters. Example:

    Private Overloads Sub update()
        CursorPosition = getCurrentPosition()
        RaiseEvent position(CursorPosition)
        debugprint(_bind.Rtf, False)
    End Sub
    
    Private Overloads Sub update(ByVal sender As Object, ByVal e _
                         As System.Windows.Forms.KeyEventArgs)  'KeyUp

        update()
    End Sub
    
    Private Overloads Sub update(ByVal sender As Object, ByVal e _
                         As System.Windows.Forms.MouseEventArgs)  'MouseUp

        update()
    End Sub
    
    Private Overloads Sub update(ByVal sender As Object, ByVal e _
                                     As System.EventArgs)  ' TextChanged

        rtfColors.Clear() ' Clear the colors

        readRTFColor()    ' Read and parse the colors in the current document

        readRTFBody()     ' Read and split the RTF into lines

        readTXTBody()     ' Read and split the text into lines

    End Sub

So by overloading the Subs, we can have different events calling the same function. You may notice that the TextChanged event is slightly different from the others. This loads the RTF document into the arrays of the class to prepare for parsing.

We also need to hook into the API for some non-standard functions such as GetScrollPos, SetScrollPos, PostMessageA and LockWindowUpdate. You can read about GetScrollPos, SetScrollPos and PostMessageA in the Scrolling with API article. For now, let's look at the definitions of these functions.

    Private Declare Function GetScrollPos Lib "user32.dll" ( _
        ByVal hWnd As IntPtr, _
        ByVal nBar As Integer) As Integer

    Private Declare Function SetScrollPos Lib "user32.dll" ( _
        ByVal hWnd As IntPtr, ByVal nBar As Integer, _
        ByVal nPos As Integer, ByVal bRedraw As Boolean) As Integer

    Private Declare Function PostMessageA Lib "user32.dll" ( _
        ByVal hwnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As Integer) As Boolean

    Private Declare Function LockWindowUpdate Lib _
             "user32.dll" (ByVal hwnd As Long) As Long

Basically, what these are going to get you is the ability to lock and reset your window's scroll. We use these functions like so:

    Private Sub saveScroll(ByVal hWnd As IntPtr)
        LockWindowUpdate(hWnd.ToInt32)

        CursorPosition.xScroll = GetScrollPos(_bind.Handle, SBS_HORZ)
        CursorPosition.yScroll = GetScrollPos(_bind.Handle, SBS_VERT)
    End Sub


    Private Sub restoreScroll(ByVal hWnd As IntPtr)
        SetScrollPos(_bind.Handle, SBS_HORZ, CursorPosition.xScroll, True)
        PostMessageA(_bind.Handle, WM_HSCROLL, _
          SB_THUMBPOSITION + &H10000 * CursorPosition.xScroll, Nothing)
        SetScrollPos(_bind.Handle, SBS_VERT, CursorPosition.yScroll, True)
        PostMessageA(_bind.Handle, WM_VSCROLL, _
          SB_THUMBPOSITION + &H10000 * CursorPosition.yScroll, Nothing)

        LockWindowUpdate(0&)
    End Sub

saveScroll gets the current scroll locations of your window and locks it. restoreScroll resets the scroll information on your window and unlocks it.

Now the heart of the program, the (other) keyUp event. This is where we tell the program to start looking for words to colorize. This has changed from previous versions where it used to be in a TextChanged event.

    Private Sub _bind_KeyUp(ByVal sender As Object, ByVal e _
             As System.Windows.Forms.KeyEventArgs) Handles _bind.KeyUp
        If e.KeyData = Keys.Space Then
            ' Update the cursor position

            update()
            ' Freeze the windows and get the scroll nfo

            saveScroll(_bind.Handle)

            ' Do any coloring

            applyColor(CursorPosition.CurrentLine)
            ' Update the RTF

            _bind.Rtf = Render()
            ' Reset the cursor

            _bind.SelectionStart = CursorPosition.Cursor
            ' Update the debug window

            debugprint(_bind.Rtf, False)

            ' Unfreeze the windows and Restore the scroll

            restoreScroll(_bind.Handle)
        End If
    End Sub

As you can see, there is not much to this event. What it says is if the last key was a space then get the cursor position, lock the windows, colorize the line and unlock the windows.

Building the data:

Parsing the color information in the header of the document is the job of readRTFColor. readRTFColor parses each color in the header and adds it to the collection of colors so it can be rebuilt later.

    '----------------------------------------------------------------------

    '     Sub: readRTFColor()

    ' Purpose: parse the color information in the header of the document

    '

    Private Function readRTFColor() As Boolean
        Dim strHeader As String = ""

        ' Get Header string

        ' I hate RegEx :-)

        '

        Dim colHeader As MatchCollection = _
          Regex.Matches(_bind.Rtf, "{\\colortbl\s?;(.*);}")

        If RTFDebug Then 
          Console.WriteLine("Colors found: " & colHeader.Count)

        If colHeader.Count = 1 Then
            strHeader = colHeader.Item(0).Groups(1).Value
            If RTFDebug Then 
              Console.WriteLine(colHeader.Item(0).Groups(1).Value)
        Else
            If RTFDebug Then Console.WriteLine("No color info in header")
            Return False
        End If

        ' Translate the string to ARGB color values

        ' I hate RegEx :-)

        '

        Dim colColors As MatchCollection = Regex.Matches(strHeader, "(\d+)")

        If Not colColors Is Nothing Then
            Dim colorCounter As Integer

            For colorCounter = 0 To colColors.Count - 1 Step 3
                Dim newColor As Color = Color.FromArgb(0, _
                                colColors.Item(colorCounter).Value, _
                                colColors.Item(colorCounter + 1).Value, _
                                colColors.Item(colorCounter + 2).Value)

                rtfColors.add(newColor.ToArgb)
            Next
        End If
    End Function

readRTFBody and readTXTBody use standard string functions to extract there information but they do one other important thing. They split the information up into lines (using the split function).

    '----------------------------------------------------------------------

    '     Sub: readRTFBody()

    ' Purpose: Read the RTF and strip off the header info, 

    '          and split it into limes.

    '          RegEx avoided here !

    '

    Private Function readRTFBody() As String
        Dim tmp As String = _bind.Rtf
        Dim bodyStart As Integer

        Dim position As Integer = InStr(tmp, "\viewkind4")
        If InStr(position, tmp, " ") < 0 Then
            bodyStart = InStr(position, tmp, "\par")
        Else
            bodyStart = InStr(position, tmp, " ")
        End If

        Dim tmpRtfBody As String = tmp.Substring(bodyStart)
        rtfBody = Split(tmpRtfBody, "\par")
    End Function

    '----------------------------------------------------------------------

    '     Sub: readTXTBody()

    ' Purpose: Split the text portion into lines

    '          RegEx avoided here !

    '

    Private Function readTXTBody() As String
        Dim tmpText As String
        Dim counter As Integer

        tmpText = _bind.Text
        txtBody = Split(tmpText, Chr(10))

        For counter = 0 To UBound(txtBody)
            If txtBody(counter) Is Nothing Then
                txtBody(counter) = ""
            End If
        Next

        If RTFDebug Then Console.WriteLine("")
        If RTFDebug Then 
          Console.WriteLine("Text lines read: " & UBound(txtBody))
    End Function

Changing the data:

Once we have the data parsed and in arrays according to its line, it's really easy to change. Basically, we just loop through the current TEXT VERSION of the line and insert the colors that we gathered from cDict.

    '----------------------------------------------------------------------

    '     Sub: applyColor

    ' Purpose: Apply a new color format to a line

    '

    Private Function applyColor(ByVal line As Integer)
        Dim colWords As MatchCollection = Regex.Matches(txtBody(line), "\w+")
        Dim Word As Match
        Dim pattern As DictionaryEntry

        rtfBody(line) = txtBody(line)

        For Each Word In colWords

            If rtfSyntax.exists(Word.Value) Then
                Dim inDict = rtfSyntax.exists(Word.Value)
                Dim colorindex As Integer

                If inDict <> -1 Then
                    rtfColors.add(inDict)
                    colorindex = rtfColors.exists(inDict)

                    rtfBody(line) = _
                       Regex.Replace(rtfBody(line), _
                       "\b" & Word.Value & "\b", _
                       "\cf" & colorindex + 1 & Word.Value & "\cf0 ")
                    If RTFDebug Then 
                       Console.WriteLine("Applying color to: " & line)
                End If
            End If
        Next

Constructing the data:

Now, all the changes to the individual lines of the files are done to the arrays then reassembled later in the render procedures. What the render procedures does is take the collected information and merge the lines back together. Like this:

    '----------------------------------------------------------------------

    '     Sub: Render()

    ' Purpose: Put the moded RTF back together

    '

    Private Function Render() As String
        Return reBuildHeader() & "\viewkind4 " & reBuildBody()
    End Function

    '----------------------------------------------------------------------

    '     Sub: reBuildHeader()

    ' Purpose: Using the colortable supplied by readRTFColor() rebuilds the 

    '          headers after all you might have added a color!

    '

    Private Function reBuildHeader() As String
        Dim thisColor As Integer
        Dim DocHead As String

        DocHead = "{\rtf1\ansi\ansicpg1252\deff0\deflang1033"
        DocHead &= "{\colortbl ;"

        For Each thisColor In rtfColors
            Dim setColor As Color = Color.FromArgb(thisColor)
            DocHead &= "\red" & setColor.R
            DocHead &= "\green" & setColor.G
            DocHead &= "\blue" & setColor.B & ";"
            If RTFDebug Then Console.WriteLine("Adding Header Color")
        Next

        DocHead &= "}"
        Return DocHead
    End Function

    '----------------------------------------------------------------------

    '     Sub: reBuildBody()

    ' Purpose: Build the moded RTF Body

    '

    Private Function reBuildBody() As String
        Dim DocBody As String = ""
        Dim rtfLine As String = ""
        Dim counter As Integer

        For counter = 0 To UBound(rtfBody)
            Dim tmp As String = rtfBody(counter)
            If tmp = "" Then tmp = " "
            DocBody &= tmp & "\par" & vbCrLf
        Next

        If RTFDebug Then 
            Console.WriteLine("RTF body lines rendered: " & UBound(rtfBody))
        Return DocBody
    End Function

So now, when the user looks at his RTF, it is in fact your RTF that was built from scratch each time.

Extra goodies:

There are two Subs that you can use to wow people. They are called changeColor. What these Subs do is modify the color information that gets rendered to the document so you can change all the blues to reds or all the greens to purple or whatever you want. And it will be instantaneous.

    '

    '     Sub: ChangeColor

    ' Purpose: Change the color of an element document wide. 

    '          Basicly this changes

    '          the info in the color table used to build the headers.  

    '    Note: This changes a color to a color

    '

    Public Sub ChangeColor(ByVal srcColor As Color, ByVal toColor As Color)
        Dim index = rtfColors.exists(srcColor.ToArgb)

        If index <> -1 Then
            rtfColors.item(index) = toColor.ToArgb
        End If
    End Sub

    '

    '     Sub: ChangeColor

    ' Purpose: Change the color of an element document wide. 

    '          Basicly this changes

    '          the info in the color table used to build the headers.  

    '    Note: This changes a index value of a color to a color

    '

    Public Function ChangeColor(ByVal index As Integer, ByVal toColor As Color)
        rtfColors.item(index) = toColor.ToArgb

        reBuildHeader()
    End Function

Well, that's about it. I'm sure I will be adding more to this as time goes on but for now enjoy.

Disclaimer

This code is free for personal use. However, if you are going to use it for commercial purposes, you need to purchase a license.

Updates

I found a few issues with the wrapper class:

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralPossible suggestion
EricTTCDAS
3:32 15 Jul '08  
The keyword coloring remains the same. That is, a keyword is detected, the color changes but then the color remains the same on subsequent words (or tokens).
Is this intentional? I guess i'm looking to clone the VB IDE where keywords are detected on keydown and colored as so and white space resets the color to the default (black, in most cases).
GeneralProblem with pattern matching numbers... and a few adjustments....
TheCompWiz
6:01 19 Apr '07  
You have a mistake in the "applyColor" function...

Dim newString = "\cf" & colorindex + 1 & oldWord & "\cf0 "
should be:

Dim newString = "\cf" & colorindex + 1 & " " & oldWord & "\cf0 "
in both cases (isRegex or not). The reason for the additional space ... is that when pattern matching numbers, or something starting with a digit. In example... when pattern matching hex values... like 0xFF for instance.. using the pattern "0x[A-F0-9]+" ... you end up with the newstring value of "\cf10xFF\c0" which is interpreted as "color 10" not "color 1" and the end resulting displayed text is missing it's preceeding 0. "xFF"

In addition... to save a few cycles on the processor... and to skip a few unnecessary variables calls & such... try using a for loop... and decrement instead of incrementing.

Dim i As Integer For i = matches.Count - 1 To 0 Step -1
thisMatch = matches.Item(i)
Dim oldWord = rtfBody(line).Substring(thisMatch.Index, thisMatch.Length)
Dim newString = "\cf" & colorindex + 1 & " " & oldWord & "\cf0 " rtfBody(line) = rtfBody(line).Remove(thisMatch.Index, thisMatch.Length)
rtfBody(line) = rtfBody(line).Insert(thisMatch.Index, newString)
If RTFDebug Then Console.WriteLine("Regex pattern match: " & Style.pattern)
Next

this saves having to use the "offsetter" "count" as the text is added to the end... and initial index values remain the same... as well as the fact that "for" loops eat less CPU than "for each"

It was a really nice idea tho... exactly what I was looking for.
Generala faster getCurrentPosition
dmageiras
9:44 12 Feb '07  
Function getCurrentPosition is somewhat slow. I rewrote it and now it is really fast:

Private Function getCurrentPosition() As cPosition
Dim retval As New cPosition
Dim counter As Integer
retval.Cursor = _bind.SelectionStart

If _bind.Text <> "" Then Dim mcounter As Integer = 0 Dim s As Char = Chr(10)
Dim ss As String() = _bind.Text.Split(s)
For i As Integer = 0 To ss.Length - 1 If (mcounter <= retval.Cursor) Then mcounter += ss(i).Length + 1 Else mcounter -= ss(i - 1).Length + 1 retval.CurrentLine = i - 1 retval.LinePosition = retval.Cursor - mcounter
Exit For End If Next
End If
Return retval
End Function


D. Mageiras
QuestionUse for Free Application?
conorod
5:52 2 Dec '06  
I am making a HTML editor, but it is a free application, not a commercial one. Can I use this class in that app?
AnswerRe: Use for Free Application?
wallpaper311
6:16 29 Dec '08  
I was wondering the same thing.
GeneralRe: Use for Free Application?
Matthew Hazlett
16:24 29 Dec '08  
I wrote this a long time ago, wow a real long time ago Smile

I'm sure there is better syntax logic but feel free to use my code in your free app, all I ask is you give me a shout out in your readme or documentation (And where possible share what you create).

Good luck with your application.

Matthew Hazlett
Fighting the good fight for web usability.

QuestionPurchase a Lisence
KarlG
8:03 10 Aug '06  
You mentioned in your disclaimer that if one would like to use this ocde in a commercial project one would have to purchase a Lisence.

What would be the lisence cost and what are the terms?
JokeGood, but...
ChewsHumans
23:28 19 Apr '06  
Firstly, thank you for writing this article and the code behind it. It helped me immensely. Admittedly the article doesn't describe *how* the code works, but it shows how to use the code, and that was good enough for me.

However, I must point out that your code contains a number of glaring mistakes. For example, your API declarations use longwords, which is wrong and can cause a crash. Use Int32 or IntPtr instead. The size of a Long changed to 64 bits with the advent of .NET, so all API declarations ported from VB6 have to be altered.

Secondly, you only update the colours for a line when a space is detected. You really have to do it on any character key - backspace and delete, and return, for examples. And just any other key, really, except cursors and such.

There are also problems when deleting the first line of the code - it deletes the second line instead, for some reason. Although I seem to have fixed that somehow. Also, you need to clear the selection colour when the cursor is placed at the start of a line, otherwise the "normal" colour isn't black anymore.

Blank lines tend to sprout a phantom space character, which I narrowed down to a seemingly pointless line of code. I removed it, and this solved the problem.

You also have a lot of passive properties, which are completely unnecessary. If a property does nothing more than set a variable, just make the variable public and reduce the amount of extraneous code.

- Infinity.
GeneralRe: Good, but...
ChewsHumans
23:30 19 Apr '06  
Also you couldn't type backslashes or braces in the code, as someone else seems to have noticed. I fixed that too.
GeneralRe: Good, but...
halvar66
3:44 24 Jan '10  
You wrote Blank lines tend to sprout a phantom space character, which I narrowed down to a seemingly pointless line of code. I removed it, and this solved the problem.
My question is, how did you solved the problem? Would you give me your solution please?
Question"{"
Gi0Gi0
0:40 10 Feb '06  
Hi, I love your Wrapper class, thanks a lot..


but my problem is: your wrapper clears all "{" and "}" in the text..

if I type: "function(){ " then function becomes green (b'cause I added this to syntax...) so far so good. But the "{" just disappears...

Have you an idea how to fix that?

Thx a lot

regards

GioGio
AnswerRe: "{"
Gi0Gi0
12:51 11 Feb '06  
I worked it out:

I changed:
txtBody = Split(tmpText, Chr(10))
to
txtBody = Split(tmpText.Replace("{", "\{").Replace("}", "\}"), Chr(10))

in the Private Function readTXTBody() As String

Big Grin
Generalso bad code&#65281;&#65281;
neoyuuuu
17:18 9 Jun '04  
why?

Confused
GeneralNo very "Real-Time"
shekky
12:00 27 May '04  
Just try pasting the html source of this page into the textbox. You should probably consider moving the hilighting code to a different thread.
GeneralRe: No very "Real-Time"
Dranore
2:24 4 Jun '04  
Yeah. I have to agree. I'm fairly new to VB and I wanted to write a little programming language editor. I find that whenever I have large ammounts of highlighted matterial, the program locks up consistently with no means of recovery and that's only using your code by itself. :\ I really like it otherwise though.
GeneralRe: No very &quot;Real-Time&quot;
CuSr0r--
11:10 23 Dec '05  
the problem is in function getCurrentPosition()...
ok lets see some profiler data...

this function was called 99 times with 37..% of the total time...
this function called: get_Text() 88944 time with 36..% of total time and 98% of the parent time (37..%) hummmm (this is not good Unsure )

So this is not good as you can see! Smile

getCurrentPosition must be rethinked...

(vb sucks)

GeneralRTF Lines
AaronMasta
11:51 18 Mar '04  
Hi,

Is there any way to set the lines of the RTF?

For example, in a RichTextbox, I can say

dim someText as string = RichTextbox1.Lines(15)
RichTextbox1.Lines(16) = someText

So, would there be a way to impliment

dim rtfText as string = RichTextbox1.RtbLines(2)
RichTextbox1.RtbLines(5) = rtfText

Aaron Eldreth
TheCollective4.com
GeneralRe: RTF Lines
Matthew Hazlett
14:03 18 Mar '04  

Not that easily, just off the top of my head the best you can probably do is this:

dim lines() as string
lines = rtb.text.split(vbcrlf);
lines(5) = "Be cool if RTB supported this feature"

Then to put them together:

rtb.text = ""
for counter = 0 to ubound(lines)
rtb.text &= lines(counter) & vbcrlf
next



Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
GeneralRe: RTF Lines
Matthew Hazlett
19:33 21 Mar '04  
er, I ment rtb.rtf not rtb.text... I should read what I type Smile


Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
GeneralRe: RTF Lines
AaronMasta
10:54 23 Mar '04  
Ok, thanks. I'll see if I can impliment the RtfLines Property.

You mentioned in your article that this code needes a license for commercial use. How much $$$ would that cost?

Aaron Eldreth
TheCollective4.com
GeneralTextEditor od SharpDevelop
Frank3000
3:28 6 Feb '04  
Hi,
if you came up with this a week before maybe I didn't had to go into the hassle to use the TextEditor of the SharpDevelop IDE (took three days, source is of course available). What's still missing in the RTB is drag and drop to move text around with the mouse, nobody made it public yet (or managed it)

Frank
GeneralRe: TextEditor od SharpDevelop
Mohohlo
2:23 14 Feb '04  
Frank,

would you mind sharing how you got the sharpdevelop editor to work in your project ?

Mo
GeneralRe: TextEditor od SharpDevelop
Frank3000
5:19 14 Feb '04  
Hi,
you can make a anonymous CVS checkout (download the source code)

http://sourceforge.net/cvs/?group_id=57023

the module is called AVSEdit, it is a full featured script editor for the AviSynth scripting language with lots of features including syntax highlighting and IntelliSense!

after the next release there will be also a zip file

I'm not a CVS expert so I can't help you how to do it

hope this helps
Frank
GeneralRe: TextEditor od SharpDevelop
hazlema
5:22 14 Feb '04  
The text editor in sharpdevelop isnt very functional. I was trtying it out and typed in a tag and ended up on a completly diffrent line I started from with about 3 spaces breaking up the tag I typed...

It seems the sharpest thing in sharpdevelop is the interface. My vote is still and always has been UltraEdit. (If you need somthing other then the VS.NET IDE, by far the best) But my new IntelliEdit (when its done) will be a good choice as well Smile

Auto case fixing, intelisence and intigrated help are a few of the new things it will have. A slick docking style/tabbed interface as well...

Some of the stuff I write that I posted up will be in it like the toolbar thing I just posted yesterday.

http://www.codeproject.com/useritems/ToolBarControl.asp[^]
GeneralDemo project not working (Missing DLL)
chris.illgen
1:48 6 Feb '04  
Hi,

Demo project does not work : Windows requests a DLL : mscoree.dll
Any solution ?

Christophe


Last Updated 2 Feb 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010