Geeks With Blogs
Pete's Weblog The Blog Formerly Known as Fun with WinForms

Microsoft Word and Visual Studio have one very cool feature in common -- squiggly underlining of errors. As of richedit 3.0 (distributed with Windows 2000 and higher, possibly also with ME) we can get these in the RichTextBox. Actually, we can get a lot more underline styles than that...

Underlining

Once again we are going to have to communicate with the underlying richedit control. This time we need to set the character format, so we'll need to add some extra stuff to our class:

+ Code to interface with the Win32 CHARFORMAT2 structure.

Underline Style

The underline style and colour are both set with the same message, so we must be careful to preserve the colour while changing the underline style. We'll use a property again so that we remain consistent with the original RichTextBox:

+ Code to set the underline style.

Once again, this has not been fully tested so you use it at your own risk. Let me know if there are any problems, etc. The UnderlineStyle enumeration is also fairly straightforward:

+ UnderlineStyle enumeration.

Note that some of these styles may not display correctly. This is a common problem with the richedit control, often you will apply some formatting only to find that it will not display at all. The formatting is usually stored though, so cutting and pasting into Word will show the text correctly.

Underline Colour

We can also change the underline colour. Notice how the set method of underline colour retrieves the underline style in order to maintain consistency.

+ Code to set the underline colour.

Unfortunately there are not many colours available to this property. They are defined by the UnderlineColor enumeration:

+ UnderlineColor enumeration.

If you set the underline colour to anything other than black it will not serialise correctly. I don't know if this is by design or not. Any text with a non-black underline that is cut and pasted into Word (or any other application) will lose it's underlining all together. I don't know if the underline is still stored in the actual rich text or not when this happens.

Conclusion

Well that's it for part two. In my next post in this series I will cover setting the background colour.

Posted on Wednesday, October 15, 2003 9:19 AM Windows Forms | Back to top


Comments on this post: Extending RichTextBox - Part II

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi Pete,

Pete, hi I'm Eugene Mortimore from Multimedia
Software. I wanted the THANK YOU for your extensions to the
.Net RichTextBox control. I'll have to try them out.

I'm looking for an extension where the program user can
HOVER (NOT select) his mouse over any text word and
see a ToolTip (BalloonTip) for that text word.

For example, this might be the word's definition.

Have you seen anything that will do that?

Thanks
Gene
Left by Eugene Mortimore on Oct 16, 2003 2:43 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Okay I've tried it and it can be done (sort of). The problem is that how you do it depends on exactly what you are looking to achieve.

Here's what I tried:

1) Write the OnMouseHover method:
2) Use Cursor.Position.X and .Y to get the cursor pos
3) Use PointToClient to get that pos in client coords
4) Use GetCharIndexFromPosition to get the char index
5) From that index find the word that you are hovering over
6) Set your tooltip text ("myToolTip.SetToolTip( this, text );")
7) Activate the tooltip ("myToolTip.Active = true")
8) Use ResetMouseEventArgs() to get hover to fire again without the mouse having to leave the text area

The problem with this is that if the mouse is beyond the last bit of text, GetCharIndexFromPosition will return the index to the end of the text and NOT the position at the actual cursor. I can't immediately see a way around this problem, but if you find a way please let me know.

Basically you could try and calculate the word under the cursor and get your tooltip from that. Or you could store a collection of tooltip text values (referenced by index and length) which you just check in OnMouseHover. The problem with that method is you have to update that collection when the user edits the text.

Sorry I couldn't be more help.
Left by Pete Vidler on Oct 16, 2003 5:40 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
This is really Nice!! i think you can help me too. I am using RichEdit Control of .net in windows forms with some linklabel controls inside the richedit control. These controls can be placed anywhere in the richedit control by the user using treeview dragdrop operation. I have to open a new form on click of linklabels. And after closing the new form the data on the form is to be placed in richedit control exactly at the position after the linklabel control. will you be able to help me to do this. My mailid is sameer.khanna@ihealthcareinc.co.in
Thanks in advance
Left by Sameer Khanna on Jun 17, 2004 11:03 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi,

Using this method to display wavy underlines has an undesirable effect in that it embeds that underline style in the rich text document itself. If the text is saved or copied, the document will be saved with the wavy underlines. Also, if you want a real underline, using CHARFORMAT2 will overwrite that underline. Yet another effect is that the SelectionFont.Underline will say that a word is underlined when it is not and it will mess up the undo and redo buffers.

I've been trying to build an As You Type spell checker (NetSpell) for some time. I've completed my first beta but it is suffering from a lot of flicker. I'm drawing red wavy underlines under words in the RichTextBox by
overriding WndProc and looking for the WM_PAINT message. I then raise the OnPaint Event to draw the underlines. This technique works but has a horrible flicker. I've optimized the OnPaint as much as i can by drawing to an internal bitmap, then drawing that bitmap.

I've also tried setting the style bits to use DoubleBuffer and UserPaint. This makes the drawing very smooth but the text in the control is no longer painted. Do you have any ideas as to a better way this could be done?

Thanks
Paul
Left by Paul on Jun 29, 2004 9:31 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hello, I am writing a control for syntax highlighting and had flicker problems as well. I found this code and it was a life saver. It basically Freezes all painting while the work is being done, then it releases the freeze and the control is invalidated which forces a repaint (only once when your work is done) This works for any control, you just pass it a reference to the control object.

Here is the code - watch for line wraps - see how to call it below the code. Sorry, it's in VB.NET -

**********************************
Apologies to whoever wrote this -
you deserve the credit, but I don't
know who you are!
**********************************

Public Property FreezePainting(ByVal vControl As Control) As Boolean
Get
If Not mPaintFrozenHT.ContainsKey(vControl.GetHashCode) Then
Return False
Else
Return (CType(mPaintFrozenHT(vControl.GetHashCode), PaintFrozenCount).Count > 0)
End If
End Get
Set(ByVal Value As Boolean)
If Not mPaintFrozenHT.ContainsKey(vControl.GetHashCode) Then
mPaintFrozenHT(vControl.GetHashCode) = New PaintFrozenCount
End If
Dim cnt As PaintFrozenCount = CType(mPaintFrozenHT(vControl.GetHashCode), PaintFrozenCount)

If Value And vControl.IsHandleCreated And vControl.Visible Then
If cnt.Count = 0 Then
SendMessageAPI(vControl.Handle.ToInt32, WM_SETREDRAW, 0, 0)
End If
cnt.Count += 1
End If
If Not Value Then
If cnt.Count = 0 Then Return
cnt.Count -= 1
If cnt.Count = 0 Then
SendMessageAPI(vControl.Handle.ToInt32, WM_SETREDRAW, 1, 0)
vControl.Invalidate(True)
mPaintFrozenHT.Remove(vControl.GetHashCode)
End If
End If
End Set
End Property

Private Class PaintFrozenCount
Public Count As Integer
End Class

********************************

How to use it....

FreezePainting(Me) = True
Try
' DO YOUR WORK HERE...
Catch Ex As Exception

Finally
FreezePainting(Me) = False
End Try

Left by Matt on Aug 04, 2004 2:19 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi,

I am trying hard - without success - to enable cleartype fonts in a RichTextBox, on systems that support cleartype (such as XP) but have the system-wide setting disabled.

I have searched newsgroups and .net websites but I can't find a solution.

Even using a LOGFONT structure and setting lfQuality=5 does not produce any result.

Any help would be greatly appreciated..
Left by magma on Nov 05, 2004 6:59 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Do you have any examples/samples which allow the user to use the <ALT> key along with the left mouse click to block copy columns across rows similar to how Microsoft Word has implemented this feature?

Left by Dave Londeck on Dec 02, 2004 4:18 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi,
Could anyone tell me what does the following mean:

private const int CFM_UNDERLINETYPE = 8388608;
private const int EM_SETCHARFORMAT = 1092;
private const int EM_GETCHARFORMAT = 1082;

Thanks
Left by Howie on Jan 08, 2005 2:40 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
How can I get multipages, split and shown page-wise (as in MS word) in richtextbox? Using vb.net. YOur above code seems very nice.I'll try it too.
Left by Meetquant on Feb 09, 2005 7:31 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi! very good your extension...what i'm trying to do myself is a "show/hide" function like in Microsoft Word.

for the space character...this is quite easy...but to show "return carriage" and tabulature...this is quite an other problem.

thanks
Vincent
Left by Vince on Mar 09, 2005 2:28 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
I too am struggling with "showing" whitespace characters; e.g. tabs. Any help, please?
Left by Matt on Apr 19, 2005 9:23 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi Every One
I do some of this code in Delphi and were reached to "re: Extending RichTextBox - Part II 10/16/2003 5:40 PM Pete Vidler
"
but there was a problem !.
in GetCharIndexFromPosition Function there are two essentiall argument. X and Y . I convert the Y value to its real value by dividing Y to Font.Height but what i can do for X .
Left by MH2538 on Jun 15, 2005 12:39 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Anyone manage to set the wavy red underline in RTF?
I am using \ulwavy\ulc1 where 1 is the color table index of Red, and the underline is always black.
I need RTF-time setting, not run-time setting due to multiple complex constraints, can you suggest something please?
Left by caractacus on Jul 19, 2005 2:17 PM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
About the tooltip: I did something very similiar. The way I detected whether it was actually on a word or not was to get the coords of the character being reported. Then if the distance is greater than 2*font.height, the mouse is too far away [dist=sqrt((y2-y1)^2 + (x2-x1)^2)] (if you compare the square of the distance to the square of the font height, that will avoid the expensive sqrt call)
Left by Charlie on May 25, 2006 5:16 PM

# Extending RichTextBox - Part II
Requesting Gravatar...

Dear all,
Can anyone tell me how do we add more
buttons on the toolbar of the extended richtextbox.
I tried, it is possible, but i am not getting the event
to raise the new added button's Event.

Thank you
Left by Chandra Bhushan on Oct 22, 2007 5:08 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Is this supposed to work? the underline color is always the same color as the text itself for me.
Left by Meidan Alon on Oct 12, 2008 8:38 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi Pete,
thanks for this great article.
Is there any way to make classic underlining and this underlining separate, just the way it is in MS Word? At the moment I cannot underline and show spelling error at the same time.

Let me know if you have any ideas, thanks in advance.
Michal.
Left by Michal on Sep 14, 2010 7:16 AM

# re: Extending RichTextBox - Part II
Requesting Gravatar...
Hi!

This code is not working on RichEdit v40 and greater...
Left by Oleg on Oct 13, 2010 11:36 PM

# How to remove?
Requesting Gravatar...
Hello,

If I set underline style like this:

txtbox.Find(word);
txtbox.SelectionUnderlineStyle = AndvancedRTB.UnderlineStyle.Wave;
txtbox.SelectionUnderlineColor = AndvancedRTB.UnderlineColor.Red;

It was set, but how I can remove it for next text what I type?
Left by VitekST on Nov 29, 2012 1:24 PM

Your comment:
 (will show your gravatar)
 


Copyright © Pete Vidler | Powered by: GeeksWithBlogs.net | Join free