Help Your Application Users Become Great Spellers

Virtually all interactive applications nowadays involve the input of human-readable text. From accounting to instant messaging, we all want to look professional and use communication that speaks to our point and not to our ham-fisted typos. Sure, you can always use a dictionary attack on human-readable strings, but to really help the user you should offer the familiar "suggestions" interactions provided by your typical office word processor.

Fortunately, a variety of spell checking products are available for the Visual C++ and Visual Basic developer. This article looks at SpellChecker, an easy-to-use shareware DLL add-on by GPP Software.

A Speller Without a Lot of Baggage

SpellChecker is a self-contained Windows Dynamic Link Library (DLL) that has all of its functionality in SPLCHK32.DLL. The included setup script installs it in your System32 directory. By using the provided import library or Win32 LoadLibrary() calls, you can obtain a spell checking functionality that normally requires the use of DDE/OLE communications with products such as Microsoft Word. Thus, it should be simple to integrate it into any development environment that can call DLL functions.

SpellChecker dictionaries can reside in flat files, Microsoft Access, or Microsoft SQL Server databases to enable sharing across a network. SpellChecker comes with a standard UK English dictionary of 113,000 words, but you easily can build up your own dictionaries—even for different languages. (Free dictionaries for other languages can be obtained around the Internet or from GNU Aspell project, for example.) You need only pass SpellChecker edit fields or files containing many words.

SpellChecker provides essential API calls to spell check the following:

  • Windows Edit fields
  • String buffers
  • ASCII files
  • Individual words

SpellChecker is available in a 30-day evaluation version. During the evaluation period, a dialog periodically pops up reminding you to register. At the end of the evaluation period, you can pay the $99 registration fee.

"Hello SpellChecker"

Without further ado, take a look at how quickly you can perform the simplest of spelling functions: checking and correcting an arbitrary buffer. Using the supplied "demo" project, I compiled the basic MFC app shown in Figure 1 with Visual Studio.

Figure 1: Spell Check an Arbitrary Buffer

The upper-left window is an ordinary MFC dialog created in the sample app. The lower-right dialog was invoked by SpellChecker as a result of the API calls. The buttons work in the expected ways:

  • Ignore: Ignores current word
  • Ignore All: Ignores current and all future occurrences in this session
  • Replace: Replaces current word with "Change To" selection (does not affect dictionaries)
  • Suggest: Updates suggestions based on current value of "Change To" (user typed over, presumably)
  • Add: Adds the word to the dictionary (The dictionary is not case-sensitive, but it will remember the case entered by the user next time.)
  • Add+Replace: Does an Add followed by Replace in one step
  • Undo Add: Undoes the last Add from this session (cannot affect prior sessions)

Now, take a look at the code used to build this particular demo, starting from the MFC "OK" button handler:

#include "splchk1.h"    // SpellChecker API
#include "sizes.h"      // SpellChecker Size Defs

void CBufferDlg::OnOK() {

   int ilRc;
   char szlString[1025];

   UpdateData(TRUE);
   lstrcpy((LPSTR)szlString, (LPCSTR)tmBuffer);
   ilRc = SpellLoadDictionary();
   if(!ilRc) ilRc = SpellCheckBuffer(this->GetSafeHwnd(),
                                     (LPSTR)szlString, 1024);
   lstrcpy((LPSTR)tmBuffer,(LPSTR)szlString);
   UpdateData(FALSE);
   SpellCheckError(this->GetSafeHwnd(), ilRc);
   SpellUnloadDictionary();

The code is about as simple as anyone could ask for! It has tmBuffer linked to the contents of the edit buffer and copied in by the UpdateData(TRUE). Then, it calls SpellLoadDictionary(), which is an all-in-one initialization function. Coincidentally, if the product is unregistered, this is when the registration reminder pops up. Then, it's basically a matter of kicking off the spell check routine by calling SpellCheckBuffer() with the current hWnd, a copy of your buffer, and maximum length. Remember, a spelling correction session can arbitrarily change the length of the string needed.

After the user has completed the interactive session, the code returns back from SpellCheckBuffer(), copies the new string for storage, and displays any error conditions that might have resulted from the session. The most likely error would be a missing dictionary or similar problem, I suppose.

Because the example was designed to be completely self-contained, the code frees all the resources at the end with a call to SpellUnloadDictionary().

Spell Checking a Live Edit Field

One of the coolest SpellChecker features is the ability to spell check a live edit field in place. The following is an example of the code for that:

void CMainFrame::OnToolsSpellEdit() {

   int ilRc;
   ilRc = SpellLoadDictionary();
   if(!ilRc) ilRc = SpellCheckEdit(this->GetSafeHwnd(),
                                   tmEdit.m_hWnd);
   SpellCheckError(this->GetSafeHwnd(), ilRc);
   SpellUnloadDictionary();

This time, the code calls SpellCheckEdit() instead of SpellCheckBuffer and passes in both the parent hWnd and the edit control's hWnd, which should be enough to get the job done. No need to repeat the screen dump for this one.

Expand Your Vocabulary

Importing words is as easy as pie with SpellChecker. Basically, you do the usual setup and then call SpellImportWords() with the name of an ASCII file containing the new words to add:

void CMainFrame::OnToolsSpellImport() {

   int ilRc;
   char szlTFileName[MAXFILENAMELEN + 1],
        szlTQualName[MAXFILENAMELEN + 1];

   if(FileDlg(this, FD_OPEN, "Import",
              "Text Files (*.TXT)|*.TXT|All Files (*.*)|*.*||",
              "TXT", OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
              szlTFileName, szlTQualName, 0)) {
      // User has selected a text file to be imported
      ilRc = SpellLoadDictionary();
      if(!ilRc) ilRc = SpellImportWords(szlTQualName);

      if(!ilRc) {
         AfxMessageBox("Import completed successfully");
      } else {
         SpellCheckError(this->GetSafeHwnd(), ilRc);
      }

      SpellUnloadDictionary();
   }
}

I was impressed to find that it actually updated the permanent dictionary file ("UK.DIC") after this API call rather than writing a temporary file. Upon inspection, the dictionary had grown an appropriate amount and its datestamp had changed, of course. As you can see in Figure 2, the word "Codeguru" was added to the dictionary. So, it appears as a possible suggestion.

Figure 2: SpellChecker Recognizes Codeguru as a Valid Word

As far as I can tell, suggestions are always listed alphabetically, not probabilistically. So, even if a word is off by only one letter, the user might need to scroll. Maybe SpellChecker can offer that as an option in a future release.

Other Spell Checker DLLs

Of course, different developers have different requirement levels for their spell check needs. I encourage you to check out several APIs before committing yourself to any. Here are a couple of others to browse:

  • Wintertree Software's Sentry Spelling Checker Engine works with RichEdit type controls and offers an "as you type" mode as well. Other products include Java and HTML spell checkers.
  • Polar SpellChecker Component offers autocorrection and "as you type" mode, and it comes with full source code and dictionaries for 14 languages.

Help Users Help Themselves

Spell checkers are plentiful and easy to integrate, so why not enable your interactive application to help users look a little smarter (or less clumsy, if you prefer) through a helpful dialog or two. Give GPP Spellchecker a try for your basic spelling needs.

About the Author

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for Washtenaw Community College CIS department. Volkman is the editor of numerous books, including C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries, just drop an e-mail to sysop@HAL9K.com.



About the Author

Victor Volkman

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for Washtenaw Community College CIS department. Volkman is the editor of numerous books, including C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries, just drop an e-mail to sysop@HAL9K.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • It's not unusual for a company to use a variety of formal and informal file-sharing methods. Many methods are fraught with significant operational, financial, and legal risks in addition to other potentially negative business consequences. Strategic managed file transfer (MFT) software and services help connect the business "dots" between the various ad hoc and more systematic ways that files are moved. Read this white paper to learn how the right MFT solution, can bring order, structure, and, importantly, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds