Ian Boyd
Ian Boyd

Reputation: 256651

How to clear "temporary" (tomApplyTmp) formatting from a RichEdit?

In the 2015 blog post RichEdit Colorsđź•—, Microsoft developer Murray Sargent noted that the RichEdit controlsupports "temporary" formatting; used by spell checkers and IME editors:

Temp formatting

IMEs and proofing tools like to use character formatting such as squiggly underlines and special colors to indicate specialized text treatment, e.g., a spelling error. To avoid changing the underlying character formatting, RichEdit provides temporary formatting of underline type and color, and foreground and background colors. When such formatting is removed, the original formatting is used again for display. Temporary formatting isn’t persisted in file formats and can’t be read out by the client, only applied.

To define temporary formatting properties, call

Then specify the temporary formatting colors by calling as desired:

Specify the temporary underline color and type by calling ITextFont::SetUnderline(value).

Specify value as value:

  • value = tomAutoColor: autocolor (default text color) is used.
  • value = (color | 0xFF000000): the temporary underline color is set to value & 0x00FFFFFF.
  • otherwise, when value is a valid underline type: the temporary underline type is set to value.

To apply the temporary formatting so defined, call ITextFont->Reset(tomApplyNow). If a temporary formatting property isn’t defined, the corresponding original property is used.

emphasis mine

How do you actually remove the "temporary" formatting?

To apply temporary formatting to a block of text:

ITextRange range = textDocument.Range(0, 5); //startIndex, endIndex
ITextFont font = range.Font();
font.Reset(tomApplyTmp);
font.Underline = tomWave;    //red wavy underline
font.Underline = 0xFF0000FF; //and make the wavy underline red
font.Reset(tomApplyNow);

In 2012 he notedđź•— that the RichEdit has supported these things - the Text Object Model - for years (i.e. it was introduced with Window XP SP1):

RichEdit Spell Checking, Autocorrection and Prediction

RichEdit has provided support for client spell checking (TOM object model and temporary character formatting—see tomApplyTmp) and autocorrect (see EM_SETAUTOCORRECTPROC) for many years. But it has been the RichEdit client’s responsibility to access the spell-checking and autocorrection components, except for the built-in math autocorrect option. For clients like OneNote and Outlook, such a responsibility is a small part of the app. But for little programs, accessing proofing components can be arduous. This would be especially true for small apps written using Windows RT.

I can figure out how to apply temporary formatting to a text block:

//Get ITextDocument interface for the RichEdit control    
IRichEditOle ole;
SendMessage(RichEdit.Handle, EM_GETOLEINTERFACE, 0, out ole);
ITextDocument doc = ole as ITextDocument;


ITextRange range = doc.Range(spellingError.StartIndex, spellingError.EndIndex);
ITextFont font = range.Font();
font.Reset(tomApplyTmp);
font.Underline = tomWave;
font.Underline = 0xFF0000FF; //and make the wavy underline red
font.Reset(tomApplyNow);

But what i can't figure out is how to clear all existing temporary formatting.

I tried to "select everything and apply nothing":

ITextRange range = doc.Range(0, TextLength); //start index, end index
ITextFont font = range.Font();
font.Reset(tomApplyTmp);
font.Underline = tomNone;
font.Reset(tomApplyNow);

But that just left existing temporary formatting as it was.

Note: In 2015 Remy Lebeauđź•— (@RemyLebeau) noted that the Text Services object model requires MsftEdit.dll (i.e. Microsoft Edit v4.1)

Bonus Chatter

The Rich Edit was introduced with Windows 95, and originally had the Windows class name:

RICHEDIT_CLASS = "RichEdit"

Over the years it was improved, but gained new class names, sitting in new dlls, to maintain backwards compatibility.

Windows XP SP1 saw the introduction of the new "Microsoft Edit" class, living in "MsftEdit.dll"

Version       Dll           Class name const  Class name string             OS
============  ============  ================  ============================  ===========
RichEdit 1.0  Riched32.dll  RICHEDIT_CLASS    "RICHEDIT"                    Windows 95
RichEdit 2.0  Riched20.dll  RICHEDIT_CLASS    "RichEdit20A", "RichEdit20W"  Windows 98
RichEdit 3.0  Riched20.dll  RICHEDIT_CLASS    "RichEdit20A", "RichEdit20W"  Windows 2000   (with RichEdit 1.0 emulator
RichEdit 4.1  Msftedit.dll  MSFTEDIT_CLASS    "RICHEDIT50W"                 Windows XP SP1 (with RichEdit 1.0 emulator)
RichEdit 7.5  MsftEdit.dll  MSFTEDIT_CLASS    "RICHEDIT50W"                 Windows 8
RichEdit 8.5  MsftEdit.dll  MSFTEDIT_CLASS    "RICHEDIT50W"                 Windows 10

And so "Microsoft Edit" is the thing you should be using (and need to be using for Text Services), and not a "Rich Edit".

The Microsoft Edit gets updated with newer versions of the OS:

Windowx XP:    File description: Rich Text Edit Control, v4.1
Windows Vista: File description: Rich Text Edit Control, v4.1
Windows 7:     File description: Rich Text Edit Control, v4.1
Windows 8:     File description: Rich Text Edit Control, v7.5
Windows 10:    File description: Rich Text Edit Control, v8.5

With Windows 8, the Microsoft Edit control gained the ability to automatically have spell-checking support (since Windows 8 added a SpellCheck API).

Upvotes: 4

Views: 305

Answers (1)

Václav Slavík
Václav Slavík

Reputation: 6650

That's strange. I'm doing something similar (thanks to your post, because coherent documentation for this is extremely hard to find) and have no problem resetting the temporary styles in the same way you write, with the only difference being that I use C++:

doc->Range(5, 15, &range);
range->GetFont(&font);
font->Reset(tomApplyTmp);
font->SetUnderline(tomNone);
font->Reset(tomApplyNow);

Upvotes: 1

Related Questions