home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource1
/
program8
/
spell.cp$
/
spell.cpp
Wrap
C/C++ Source or Header
|
1993-07-13
|
11KB
|
305 lines
// spell.cpp
// A few functions to demonstrate how to integrate the SPELMATE DLL with ObjectWindows.
// (c) 1993, Stewart McSporran for Aciran Software Systems
// NB: The tab size for this file is 2
#include <windows.h>
#include <string.h>
#include "spelmate.h"
#include "spell.h"
// spelmate.dll instance
HINSTANCE hSpellLibrary;
// function prototypes
BOOL GetWord(PTEdit pEdit, LPSTR lpWord, WORD &Start, WORD &Finish);
BOOL GetWord(LPSTR lpStr, LPSTR lpWord, WORD &Start, WORD &Finish);
BOOL ValidChar(char C);
BOOL LoadSpelmateDLL();
void UnloadSpelmateDLL();
void HourGlass(BOOL iOn);
//****************** TEdit functions ********************************************
/*
Spell : Spell checks the supplied edit control. This version of the
function always checks the entire text.
*/
void Spell(PTEdit pEdit)
{
BOOL Abort = FALSE;
int OriginX, OriginY; // location of cursor when spellchecking starts
char TempWord[MaxWordLen+1]; // holds each word as it is retrieved from the string
char NewWord[MaxWordLen+1]; // any replacements selected by user
WORD StartChar = 0; // First char in current word
WORD FinishChar = 0; // last char of current word
// load spelmate dll
if (LoadSpelmateDLL())
{
// set cursor to busy
HourGlass(TRUE);
// get cursor location
pEdit->GetSelection(OriginX,OriginY);
// Extract and check each word
while (GetWord(pEdit,TempWord,StartChar,FinishChar) && !Abort) // for every word in lpString
{
if (!SpellCheck(TempWord)) // word not in any dictionary
{
// highlight word
pEdit->SetSelection(StartChar,FinishChar);
// Find if text in upper half of screen (NOT trivial!)
int FirstLine = (int)SendMessage(pEdit->HWindow,EM_GETFIRSTVISIBLELINE,0,0);
int CurrentLine = pEdit->GetLineFromPos(-1); // -1 gets line selected text is on
int NoLinesVisible = CurrentLine - FirstLine + 1;
// get the height of each line
TEXTMETRIC Tm;
HDC EditDC = GetDC(pEdit->HWindow);
GetTextMetrics(EditDC,&Tm);
ReleaseDC(pEdit->HWindow,EditDC);
// Now get the distance from the text to the top of the client area
// The following is not 100% accurate but is good enough for our purposes
int DistFromMenuBar = Tm.tmHeight * NoLinesVisible;
// get height of menu bar + title + frame (SM_CYCAPTION does title & frame)
int NCAHeight = GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYCAPTION);
// get y co-ord of top of window pEdit belongs to
int WinY = ((PTWindow)(pEdit->Parent))->Attr.Y;
// calculate absolute Y location of text
int TextY = WinY + NCAHeight + DistFromMenuBar;
// get height of screen
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
// FINALLY! if text in lower half of screen put suggest word dialog at top
if (TextY > (ScreenHeight /2))
DisplayAtTop();
// activate cursor
HourGlass(FALSE);
// provide user with list of suggestions
strcpy(NewWord,SuggestWord(TempWord));
if (NewWord[0] != 0) // not canceled
{
if (lstrcmp(NewWord,TempWord) != 0) // if different word
{
// replace TempWord with NewWord.
// delete old word
pEdit->DeleteSelection();
// insert new word
pEdit->Insert(NewWord);
// amend FinishChar to point to end of new word
FinishChar += strlen(NewWord) - strlen(TempWord);
}
}
else
{
Abort = TRUE; // finish spell checking (user pressed cancel)
}
}// if
StartChar = ++FinishChar; // point to start on (possibly) next word
HourGlass(TRUE);
}// while
// restore cursor to original place (might not be exact if words have been changed)
// Uses OriginX twice so that no text is actually selected, just places the cursor
pEdit->SetSelection(OriginX,OriginX);
}
HourGlass(FALSE);
UnloadSpelmateDLL();
MessageBox(GetFocus(),"Spell check complete.","Spelling",MB_OK);
}
// Parse words from an edit control, return true if word found.
// pEdit : control to be parsed
// lpWord : on exit contains next word, MUST be of size MaxWordLen.
// Start : index position in lpStr of first char of lpWord
// Finish : index position in lpStr of last char of lpWord
BOOL GetWord(PTEdit pEdit, LPSTR lpWord, WORD &Start, WORD &Finish)
{
// Clear contents of lpWord
_fmemset(lpWord,'\0',MaxWordLen);
// check for empty lpString
WORD len = pEdit->GetTextLen();
if (len == 0) return FALSE;
// find first character in word, DON'T use ValidChar, want to ignore "'" as first char
LPSTR Char = new char[2];
do{
pEdit->GetSubText(Char,Start,Start + 1);
Start++;
}while ((!IsCharAlpha(Char[0])) && (Start < len));
// if Char[0] = '\0' then string contains no valid words so return FALSE
if ((Char[0] == '\0') || (Start == len))
return FALSE;
else
Start--; // Position Start to first character. (because of Start++ above)
// set finish to first character before continuing search
Finish = Start;
// Now find last valid char in word
do{
pEdit->GetSubText(Char,Finish,Finish + 1);
Finish++;
}while (ValidChar(Char[0]) && ((Finish - Start) < MaxWordLen));
Finish--; // don't want Finish to point to space after the word
// now extract complete word from edit control into lpWord
pEdit->GetSubText(lpWord,Start,Finish);
// if last character in word is "'" remove it
if (lpWord[lstrlen(lpWord)-1] == '\'')
{
lpWord[lstrlen(lpWord)-1] = '\0';
Finish--;
}
// we've got this for so we must have a valid word
return TRUE;
}
//****************** String functions ********************************
void Spell(LPSTR lpString)
{
char TempWord[MaxWordLen]; // holds each word as it is retrieved from the string
char NewWord[MaxWordLen]; // any replacements selected by user
WORD StartChar = 0; // begining of the string (start of current word)
WORD FinishChar = 0; // end of current word
// load spelmate dll
if (LoadSpelmateDLL())
{
// spell check string
// set cursor to busy
HourGlass(TRUE);
while (GetWord(lpString,TempWord,StartChar,FinishChar)) // for every word in lpString
{
if (!SpellCheck(TempWord)) // word not in any dictionary
{
HourGlass(FALSE); // enable cursor again
// provide user with list of suggestions
strcpy(NewWord,SuggestWord(TempWord));
HourGlass(TRUE);
if (strlen(NewWord) != 0)
{
// replace TempWord with NewWord
LPSTR lpEnd; // temporary string to hold section of lpString after old word
lpEnd = new char[lstrlen(lpString)];
// copy all text after the old word into lpEnd
_fstrcpy(lpEnd,(LPSTR)(lpString + FinishChar+1)); //,lstrlen(lpString)-(FinishChar+1));
lpString[StartChar] = '\0'; // terminate at start of old word
// add new word to end of lpString
_fstrcat(lpString,NewWord);
// append remainder of lpString to end of new word
_fstrcat(lpString,lpEnd);
// amend FinishChar to point to end of new word
FinishChar += strlen(NewWord) - strlen(TempWord);
delete lpEnd;
}
}// if
StartChar = ++FinishChar; // point to start on (possibly) next word
}// while
HourGlass(FALSE);
}
// unload dll (if loaded)
UnloadSpelmateDLL();
}
// Parse words from string, return true if word found.
// lpStr : string to be parsed
// lpWord : on exit contains next word, MUST be of size MaxWordLen.
// Start : index position in lpStr of first char of lpWord
// Finish : index position in lpStr of last char of lpWord
BOOL GetWord(LPSTR lpStr, LPSTR lpWord, WORD &Start, WORD &Finish)
{
int TempIndex = 0;
// Clear contents of lpWord
_fmemset(lpWord,'\0',MaxWordLen);
// check for empty lpString
WORD len = lstrlen(lpStr);
if (len == 0) return FALSE;
// find first character in word, DON'T use ValidChar, want to ignore "'" as first char
for (char Char = lpStr[Start];(!IsCharAlpha(Char))&&(Start < len);Char = lpStr[++Start]);
// if Char = '\0' then string contains no vali