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.

Accordingly, RichEdit 8 was enhanced to be able to access the Windows 8 spell-checking and autocorrection components directly. The traditional Windows client using msftedit.dll on Windows 8 enables this functionality by sending an EM_SETLANGOPTIONS message with one or more of the options IMF_SPELLCHECKING, IMF_TKBAUTOCORRECTION, and IMF_TKBPREDICTION. The client also needs to enable the Text Foundation Services by sending an EM_SETEDITSTYLE message with the flags SES_USECTF, SES_CTFALLOWEMBED, SES_CTFALLOWSMARTTAG, and SES_CTFALLOWPROOFING.

In the Windows RT RichEditBox, which uses a rich-text RichEdit control, spell checking is enabled by default. The Windows RT TextBox, which uses a plain-text RichEdit control, also can have spell checking, but spell checking is disabled by default. You can change the setting using the Properties pane. Bogdan Radakovic, a developer in Windows 8, integrated the proofing features into RichEdit 8.

To try the proofing features out, I fired up Visual Studio 12 and created a new C++ project for the “Windows Store” using the “Blank App (XAML)” template. I dragged a RichEditBox from the Toolbox into the design view for the MainPage.xaml file. The RichEditBox starts out really small, so I expanded it to a reasonable size for typing text and built and ran the project. To my delight, my typing was proofed and autocorrected very nicely! The keyboard language is used to select the current proofing tools. So I switched to a German keyboard and typed in some text. Sure enough, the German proofing tools are used, which is very cool (I included the German proofing tools in my US Windows 8 installation). But if I type German using an English keyboard, I see lots of words with red-squiggle underlines. The proofing tools do not attempt to guess the language on the fly. For most people, this is a reasonable approach, especially since language detection isn’t infallible. Possibly in the next version, language detection will be offered as an option.


Comments (21)

  1. NP says:

    Can I call an API and give it a piece of text to be checked for spelling errors?

  2. NP says:

    Why isn't spelling support turned on in Wordpad or Notepad then? I tried Windows 8 Preview and neither Notepad nor Wordpad support spell checking. Why? Do you happen to know?

  3. MurrayS3 says:

    I don't know of an API you can call to check text for spelling errors. RichEdit allows its client to identify spelling errors visually with squiggly underlines as described in the post, but it doesn't have APIs to return those properties. I'll add that capability to the RichEdit wish list.

    Windows 8 is a huge upgrade and much effort was spent in creating the Windows RT APIs that work across devices on the desktop, slates, phones, Xbox, TV, etc. No time was left to change the code bases of the older desktop applets such as NotePad and WordPad, although the Windows 8 WordPad is substantially better than earlier versions since it uses RichEdit 8 instead of RichEdit 4. Maybe in a future version, spell checking will be enabled in WordPad. But the spell checker is not integrated into the Win32 system edit control, which NotePad uses. So it'd take some work to enable it or NotePad would have to use RichEdit instead of the system edit control. Internally a few years ago, a Windows developer did change NotePad to use RichEdit 6.0 for a while, and NotePad had elegant mathematical typography! But that change was backed out.

  4. NP says:

    It's a shame really. I can understand why Notepad does not have spell checking but Wordpad? Since Internet Explorer was changed to include this functionality and since Wordpad is a very simple program which already will use Righ Edit 8.0, I can't understand why adding spell checking was more than a day's work.

  5. Werner Büllow-Bartenstein says:

    You mean you fired up the German language, after all the keyboard setting is, thank goodness, separate.

  6. Christian says:

    And why is it "Rich Edit 8" while the control has version 6.002 (indication it supports Rich Edit version 0.2 only as the lowword contains the richedit version times 10!!!)?

    Oh ye versioning chaos!

    Apart from that, is it possible to ADD some OWN spell checker for keywords and such even when the Windows 8 spell checker is active? Or can I temporarily add another dictionary?

  7. Christian says:

    Hi Murray,

    a) what's the value of IMF_TKBPREDICTION? It is not defined in the current include files in VS2012

    b) is SES_CTFALLOWEMBED needed?

    (if this is a double-post, it might be some misunderstanding between my browser and your page ;))

  8. Peter says:

    How do we get a list of the items listed in the Spelling Context Menu to use in our own context menus? The current implementation interferes with existing context menu implementations, so is not much use.

    Thank you.

  9. Peter says:

    Maybe we need to use the new GETCONTEXTMENUEX struct in Windows 8? Could you possibly please explain how we would go about using this struct, There 's no accompanying EM_XXX message or any other documentation for this struct.

    Thank you

  10. MurrayS3 says:

    Have to admit, I don't know all the answers to these questions. But here are a couple of answers. richedit.h contains the definition

    #define IMF_TKBPREDICTION 0x1000

    GETCONTEXTMENUEX is an extended CHARRANGE that's passed to IRichEditOleCallback::GetContextMenu(). But RichEdit doesn't make this call if the spell checker is active. You might want to implement your own context menu and add spell checking using the ISpellCheckerFactory interface, which is described in MSDN. The documentation discusses the full Spell Checking API. But it's clear that it would be nice if RichEdit would allow the client to add items to its spell-checking menu.

  11. Peter says:

    Thanks for replying. No luck with GETCONTEXTMENUEX, I presumed from what you said that this structure might be passed in via the lpchrg member of IRicheditOleCallback::GetContectMenu. But we just get access violations when casting lpchrg. The docs are very vague.

    I already went down the route of implementing my own spellchecking using the new ISpellcheckerFactory. That part was nice and easy. The issue is that it is no longer possible to show the red wavy lines in Windows 8. ITextFont.Reset tomApplyTemp appears to be broken for colouring underlines in Windows 8.(Unless you know a workaround). Is this a bug or a conscious decision?

    Thanks

    Peter

  12. Peter says:

    Spoke too soon we can now cast the lpchrg member. Since GetContextMenu is never called for spelling, what is the GCMF_SPELLING flag used for? The following comment in richedit.h header is very intriguing.

    "#define GCMF_SPELLING 0x00000002 // pSpellingSugestions is valid and points to the list of spelling suggestions"

    Thanks

  13. MurrayS3 says:

    GCMF_SPELLING is only used in Office 2013 and immersive builds of RichEdit, which are housed in riched20.dll or richedim.dll, respectively, in an Office subdirectory. Probably GCMF_SPELLING shouldn't be documented in MSDN since it's not used in msftedit.dll at least in Windows 8 and 8.1. It would be nice to expose this facility in a way that a client can incorporate spelling entries in a more extensive context menu.

  14. jo0ls says:

    If I have a RichEdit set up with some spelling mistakes, and then switch on spell checking, the current text in the edit control does not get checked until you start making changes to the document. Is there no way via TOM2 or with a SendMessage call to trigger an immediate spell check of the content?

  15. MurrayS3 says:

    At the moment, there's only a work around: cut/paste the entire text. You can do this with ITextRange::SetRange(0, tomForward); ITextRange::Cut/Paste. It's not great, but should work fine.

  16. jo0ls says:

    Thanks, cut and paste works fine, as does reading out the RTF and writing it back. It doesn't seem to check the last word in a block of text unless it ends with a full stop, or there is whitespace at the end. I guess it's really intended to be used to check as you type, rather than to spellcheck existing text, and so as an optimisation it's not checking until the word is complete.

  17. TiKu says:

    Hi Murray,

    the definition of IMF_TKBAUTOCORRECTION is missing from richedit.h (Windows 10 SDK, build 10586). What is its value?

    Thank you

  18. MurrayS3 says:

    I find the value 0x2000, but I don't know if it works.

  19. TiKu says:

    Thanks a lot. This would mean, that it has been renamed to IMF_IMEUIINTEGRATION, which has the same value.

    Anyway, I tried it out in a Windows 8.1 virtual machine, with emulated touch input device, because currently I don't have access to a touch screen or anything newer than Windows 7. I'm also not sure it is working.

    At first I thought it would be working: I started my test application (native Win32) without IMF_TKBAUTOCORRECTION (but with IMF_SPELLCHECKING) and typed "Scgiff ", using the on-screen keyboard. The word "Scgiff" got underlined as a spelling error. So no auto-correction, just as I did expect it.

    Then I changed the test application to set IMF_TKBAUTOCORRECTION (and IMF_SPELLCHECKING) and did the same test again. Now the word "Scgiff" has been auto-corrected to "Schiff", so the IMF_TKBAUTOCORRECTION flag seemed to work.

    But after some more tests, I noticed that the IMF_TKBAUTOCORRECTION flag actually does not seem to have any effect. I used the version of my test application, that does not set the IMF_TKBAUTOCORRECTION flag. On first, third, fifth, … start of my application "Scgiff" got detected as a spelling mistake. On second, fourth, sixth, … start of my application "Scgiff" got corrected to "Schiff". Sounds weird, but it is what I'm seeing.

    I'm testing on a german Windows 8.1.

    Also when calling EM_GETLANGOPTIONS, IMF_TKBAUTOCORRECTION never is set.

    If I don't set the IMF_SPELLCHECKING flag, the random behavior disappears, but then no auto-correction does ever happen – just like IMF_TKBAUTOCORRECTION not working.

    Can you shed some light on this behavior?

  20. chksr says:

    Where can the proofing tools be found for differnt languages?

  21. chksr says:

    We have the effect that spellchecking is only active if the input language (most of the times the keyboard layout) is the system's default language.

    How can we enable spellchecking of another language (for example, German in my English system)?