Question how do I get all selected rich text (including any hidden) text from RichTextBox?

Joined
Sep 16, 2023
Messages
20
Programming Experience
10+
WHAT I HAVE:
Visual Basic 2019, WinForms, RichTextBox, .NET Framework 4.6+

MY ISSUE:
When compliing a WinForms app using a RichTextBox for .NET Framework 4.6.x or lower, the properties Text, SelText, SelectionLength, and SelRtf all properly account for any hidden (invisible) text when being read. This is not so when compiling for .NET Framework 4.7+!!! While I can create workarounds for the first 3 properties by relying on the non-public properties WindowText, curSelStart, and curSelEnd, this technique will not work for SelRtf--since WindowText only returns the full plain text (including hidden text), and the Substring method wouldn't work properly with curSelStart and curSelEnd when dealing with a rich text string anyway.

Generally, SelRtf (when working with .NET Framework 4.7+) only reliably returns hidden rich text when it's surrounded within the selection by visible text. If one has

RichTextBox1.Rtf = {rtf1 {vText1 \v iText1 \v0 vText2 \v iText2\v0}}"

then whether one gets all hidden text of a selection depends on the values set for RichTextBox1.SelectionStart and RichTextBox1.SelectionLength. (BTW, RichTextBox1.Rtf will reliably get all hidden text for the full document, regardless of the platform version.)

Is there a way (i.e., using Win32 or some other) to get the full rich text of a selected region--including any hidden text--when using .NET Framework 4.7+?

Please provide answers ASAP, in VB.NET, and as simply as possible. (BTW, ideally, I shouldn't have to derive another type control from RichTextBox.)
 
Solution
I somehow misread that, the SelectedRtf property does include hidden text when I test it with .Net Framework 4.8.

To get (selected) RTF with native code one can send the EM_STREAMOUT message (Richedit.h) - Win32 apps
I converted some code from .Net source (not .Net Framework source) starting from SelectedRtf property here. Added a public GetRtf(rt, selection) method for this and updated attachment in post 4. The backing code is a lot more complicated, but it seems to work for me and returns the same as SelectedRtf property. You can test it with your versions and experiment texts.

I tried the new GetRtf "native method", and it, regardless of the .NET platform (and therefore the underlying "richedxx"...
Attaching the module I used to test the EM_GETTEXTEX message. Just add to project and call the public GetText(rt, selection) method to get text or selected text including hidden.

Edit: included EM_STREAMOUT message for RTF and a public GetRtf(rt, selection) method
 

Attachments

  • NativeMethods.zip
    2.2 KB · Views: 3
Last edited:
Create a Windows Forms project targeting .Net 7.0 or .Net 8.0 (not .Net Framework). You need VS 2022 too.
The problem is due to a newer RichEdit version: RichTextBox with RichEdit 4.1 unusable when hidden text is used - Developer Community

The link above refers me to a page about the issue, which in turn has a link to a VS Dowloads page (Download Visual Studio Tools - Install Free for Windows, Mac, Linux), which seems to involve wholesale environment upgrades. Is it necessary to upgrade the entire IDE to VS 2022? I'm not ready to do that yet, since that might mean losing custom configurations (i.e., editor settings) and having familiar environment features no longer where I'm used to seeing them. (I'm not prepared to re-learn how to navigate my way around things, since VS 2019 otherwise seems adequate so far.) Does that download page feature a more limited, targeted package that simply upgrades the buggy stuff like the underlying rich edit DLL --and if so, how do I find it there? (Searchs for things like "hidden text", "rich edit", and "rich text box upgrade" have returned 0 results!) Must I upgrade everything simply to upgrade 1 problematic DLL?! Seems like overkill.

If there's somewhere else I can go to download the specific fix (or simply the latest version of the underlying rich-edit DLL), then please show me where. I'm in a rush, so I don't want to have to do a lot of web-surfing and playing around. (Besides, I'm a lone-wolf programmer with multiple projects, so I can't arrange for multiple issues to be worked out simulataneously!)

PS. Is there a workaround for projects with platforms higher than .NET Franework 4.6.x but lower than .NET 5?!
 
Last edited:
See post 3 + 4.
 
Attaching the module I used to test the EM_GETTEXTEX message. Just add to project and call the public GetText(rt, selection) method to get text or selected text including hidden.
Does this work for getting the hidden rich text of a selection (RTF codes/escapes and all for the selected text)? I already know how to get hidden plain text! Your approach must return RTF codes along with regular text, and whether or not full hidden (rich) text is returned must not matter on where within the selection text is hidden (i.e., in the interior of the selection, on an edge of it, the entire selection, etc.)--or it's of no use to me!

If you haven't already done this test first, then please do so and get back to me: A sample string with various sections of visible and invisible text in it, experimenting with various selection boundaries each time on the same text; if you have done this, then tell me so. I typically try the full gamut of possible selections, but as a frustrated in-a-rush lone-wolf programmer, I lack the patience to try this all over again without prior assurance that the "fix" actually works in .NET Framework 4.7+. Sorry for any inconvenience!

BTW, the MS documentation on rich-edit messages doesn't contain any info on whether EM_GETTEXTEX returns plain or rich text; if there are flags that determine which, it's not clear. So I have no idea who how SelectedRtf works. I know only that in .NET Framework 4.7+, it's flaky on whether hidden rich text is returned depending on where in the selection the hidden text occurs! Incidentally, I've tried an experiment where I tried to delete text around an intended selection--"cropping"--to return the remainder--and that didn't work! So I really need to know if EM_GETTEXTEX is truly a reliable alternative to SelectedRtf (as opposed to simply SelectedText, which I already have a fix for).
 
Last edited:
I somehow misread that, the SelectedRtf property does include hidden text when I test it with .Net Framework 4.8.

To get (selected) RTF with native code one can send the EM_STREAMOUT message (Richedit.h) - Win32 apps
I converted some code from .Net source (not .Net Framework source) starting from SelectedRtf property here. Added a public GetRtf(rt, selection) method for this and updated attachment in post 4. The backing code is a lot more complicated, but it seems to work for me and returns the same as SelectedRtf property. You can test it with your versions and experiment texts.
 
I somehow misread that, the SelectedRtf property does include hidden text when I test it with .Net Framework 4.8.

To get (selected) RTF with native code one can send the EM_STREAMOUT message (Richedit.h) - Win32 apps
I converted some code from .Net source (not .Net Framework source) starting from SelectedRtf property here. Added a public GetRtf(rt, selection) method for this and updated attachment in post 4. The backing code is a lot more complicated, but it seems to work for me and returns the same as SelectedRtf property. You can test it with your versions and experiment texts.

SelectedRtf will return all, some, or none of the hidden text on .NET Framework 4.7.x depending on where the hidden text is vis-a-vis the selection boundaries. Create an RTF string with multiple sections of regular and hidden text, then play with the SelectionStart and SelectionLength properties and see what SekectedRtf returns each time if you don’t believe me. Then do the same with your native-code technique and see if the results are more reliable. Then get back to me. With all the frustration I’ve had, I respectfully would like some assurances your technique does not have the same unreliable effects before downloading it. Thank you.
 
I somehow misread that, the SelectedRtf property does include hidden text when I test it with .Net Framework 4.8.

To get (selected) RTF with native code one can send the EM_STREAMOUT message (Richedit.h) - Win32 apps
I converted some code from .Net source (not .Net Framework source) starting from SelectedRtf property here. Added a public GetRtf(rt, selection) method for this and updated attachment in post 4. The backing code is a lot more complicated, but it seems to work for me and returns the same as SelectedRtf property. You can test it with your versions and experiment texts.

I tried the new GetRtf "native method", and it, regardless of the .NET platform (and therefore the underlying "richedxx" DLL), returns exactly the same value as .SelectedRtf. A few interesting discoveries, though, when playing around with selection boundaries for a document with regions of visible and invisible text:

Regardless of platform/riched version, how much of both visible and invisible regions of text are returned within a theoretical selection depends on whether a hidden-text region straddles 1 or both selection boundaries or is contained entirely within them--however, how these factors determine what visible and hidden text comes back depends on the .NET/riched version being used. One common trait always holds true: whenever a region of invisible text is wholly or partially within a theoretical selection, that hidden text is returned either in its entirety or not at all (!!), regardless of what logical boundaries are set for the selection! It's apparently not possible to return just a "fragment" of a region of hidden rich text. Wierd. (Perhaps the presence of invisible text affects how the selection boundaries can actually be set--at least physically.)

Others have posted a link to an article about the bug with a certain version of "richedxx", which itself has a link to a page for a fix; however, that ultimate page appears to suggest that the fix requires upgrading the entire IDE to a more recent VS version. I've also seen web articles suggesting a way, via DevExpress, to upgrade just the RichEdit DLL, but that now appears to be for a special WinForms control so-named, as opposed to the under-the-hood "richedxx" DLL. Is there a way to simply upgrade the (native) "richedxx" DLL--and if so, where can I download and install the more recent DLL, and how can I get VS to use it for RichTextBox (does that require creating a derived control)? (Can anything ever be simple?!)
 
Last edited:
Solution
Back
Top