October 2, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Help Your Application Users Become Great Spellers

  • June 19, 2006
  • By Victor Volkman
  • Send Email »
  • More Articles »

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), which 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, which 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 can easily 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, let's 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.



Click here for a larger image.

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.

Since 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.



Click here for a larger image.

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.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel