Introduction
Searching around in MSDN trying to find how to use the MS Office spell checker, I found a "fantastic" OLE solution:
- Run Word
- Push the word to be checked into Word
- Get the result.
Thanks very much :(
Then I found this. Through them, I got the Microsoft Common Spell API (CSAPI).
CSAPI
To ensure I respect copyright, I cut the smallest possible example using the default dictionary only, and ignored possible error states or exceptions. You will probably need to modify it for your language and paths (I'm not reading paths from registry).
Below is some sample code that illustrates how to use the SDK.
#include "windows.h"
#include "csapi.h"
typedef WORD (*SpellInit_fn) (SPLID FAR *lpSid,
WSC FAR *lpWsc);
typedef WORD (*SpellOpenMdr_fn)(SPLID splid,
LPSPATH lpspathMain,
LPSPATH lpspathExc,
BOOL fCreateUdrExc,
BOOL fCache,
LID lidExpected,
LPMDRS lpMdrs);
typedef WORD (*SpellCheck_fn)(SPLID splid,
SCCC iScc,
LPSIB lpSib,
LPSRB lpSrb);
typedef WORD (*SpellCloseMdr_fn)(SPLID splid,
LPMDRS lpMdrs);
typedef WORD (*SpellTerminate_fn)(SPLID splid,
BOOL fForce);
void main(void)
{
int Language = 1051;
char DllName[] =
"C:\\Program Files\\Common Files\\Microsoft Shared\\Proof\\MSPSK32.DLL";
char MdrName[] =
"C:\\Program Files\\Common Files\\Microsoft Shared\\Proof\\MSSP_SK.LEX";
HMODULE SpellInstance = LoadLibrary(DllName);
SpellInit_fn SpellInit =
(SpellInit_fn)GetProcAddress(SpellInstance,
"SpellInit");
SpellOpenMdr_fn SpellOpenMdr =
(SpellOpenMdr_fn)GetProcAddress(SpellInstance,
"SpellOpenMdr");
SpellCheck_fn SpellCheck =
(SpellCheck_fn)GetProcAddress(SpellInstance,
"SpellCheck");
SpellCloseMdr_fn SpellCloseMdr =
(SpellCloseMdr_fn)GetProcAddress(SpellInstance,
"SpellCloseMdr");
SpellTerminate_fn SpellTerminate =
(SpellTerminate_fn)GetProcAddress(SpellInstance,
"SpellTerminate");
SPLID Handle;
WSC SpecChars;
SpecChars.bIgnore = 0;
SpecChars.bHyphenHard = 45;
SpecChars.bHyphenSoft = 31;
SpecChars.bHyphenNonBreaking = 30;
SpecChars.bEmDash = 151;
SpecChars.bEnDash = 150;
SpecChars.bEllipsis = 133;
SpecChars.rgLineBreak[0] = 11;
SpecChars.rgLineBreak[1] = 10;
SpecChars.rgParaBreak[0] = 13;
SpecChars.rgParaBreak[1] = 10;
SpellInit(&Handle, &SpecChars);
MDRS Mdrs;
SpellOpenMdr(Handle, MdrName, NULL, FALSE, TRUE, Language, &Mdrs);
SIB InputBuffer;
InputBuffer.cMdr = 1;
InputBuffer.lrgMdr = &Mdrs.mdr;
InputBuffer.cUdr = 0;
InputBuffer.lrgUdr = NULL;
SRB ResultBuffer;
ResultBuffer.cch = 1024;
ResultBuffer.lrgsz = (char*)malloc(ResultBuffer.cch);
ResultBuffer.cbRate = 255;
ResultBuffer.lrgbRating = (unsigned char*)malloc(ResultBuffer.cbRate);
InputBuffer.lrgch = "slovo";
InputBuffer.cch = strlen(InputBuffer.lrgch);
InputBuffer.wSpellState = fssStartsSentence;
SpellCheck(Handle, sccVerifyWord, &InputBuffer, &ResultBuffer);
int Result = ResultBuffer.scrs;
free(ResultBuffer.lrgsz);
free(ResultBuffer.lrgbRating);
SpellCloseMdr(Handle, &Mdrs);
SpellTerminate(Handle, TRUE);
FreeLibrary(SpellInstance);
}
I have tried the above code with Office 95 and Office 97. Installing Office 2000 with English, Slovak and German languages creates a registry Spelling\1051 (slovak) and Grammar\1031 (german) entries.
BTW: My search for a similar WIN API for string comparison failed. It seems Windows knows how to use the actual language only (resp. see .NET Framework Reference, String.Compare Method (String, String, Boolean, CultureInfo)
), and there is no way to hook between your application and the system to correct the MS bugs for "small markets" like my country (where exceptional vocabulary or similar solution are necessary for proper string evaluation). If you know more about this, do not hesitate to publish it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.