Я сделал это. Это не , что сложно. Я упаковал все это в DLL и сделал диалог предложений сам.
По сути, это просто открытие слова и запрос его проверки орфографии для конкретного слова. Если проверка не удалась, вы запрашиваете предложения.
Есть только две точки, где вы можете потерпеть неудачу:
1. документ должен быть открытым, то есть вы всегда должны создавать его в коде
2. для разных версий слов словарь иногда сохраняется как юникод, а иногда (более старые версии) нет. Конечно, это важно, только если вы хотите сохранить новые слова в пользовательском словаре.
Хорошо, вот код:
заголовочный файл:
#pragma once
#include "msword.h"
class CWord
{
public:
CWord();
bool Initialize();
void Terminate();
bool CheckSpelling(CString text);
bool CorrectSpelling(CString text,CString& corrected,CWnd* pParent,CPoint point);
private:
_Application m_word;
COleVariant m_vTrue;
COleVariant m_vFalse;
COleVariant m_vOpt;
bool m_bInit;
void AddToDictionary(CString text);
CString OleErrorMsg(COleDispatchException* e);
};
И реализация (только самые важные части, извините за немецкие комментарии -> Я переведу их при необходимости)
CWord::CWord()
{
// häufig gebrauchte Variants
m_vFalse = COleVariant((short) FALSE);
m_vTrue = COleVariant((short) TRUE);
m_vOpt = COleVariant((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
m_bInit = false;
}
// sinnvolle Fehlermeldung erstellen
CString CWord::OleErrorMsg(COleDispatchException* e)
{
CString msg;
if(!e->m_strSource.IsEmpty())
msg = e->m_strSource + " - ";
if(!e->m_strDescription.IsEmpty())
msg += e->m_strDescription;
else
msg += "Unbekannter Fehler.";
return msg;
}
// Word starten
bool CWord::Initialize()
{
try
{
if(!m_bInit)
{
m_word.CreateDispatch("Word.Application");
m_bInit = true;
}
}
catch(COleDispatchException* e)
{
AfxMessageBox(OleErrorMsg(e),MB_ICONEXCLAMATION);
e->Delete();
return false;
}
return true;
}
// Aufräumen
void CWord::Terminate()
{
try
{
if(m_word != NULL)
{
m_word.Quit(m_vFalse,m_vOpt,m_vOpt);
m_word.DetachDispatch();
m_word = NULL;
m_bInit = false;
}
}
catch(COleDispatchException* e)
{
AfxMessageBox(OleErrorMsg(e),MB_ICONEXCLAMATION);
e->Delete();
}
}
// ein Wort auf Rechtschreibung überprüfen
bool CWord::CheckSpelling(CString text)
{
try
{
if(m_word == NULL)
{
AfxMessageBox("Word nicht initialisiert!",MB_ICONINFORMATION);
return false;
}
int res = m_word.CheckSpelling((LPCTSTR) text,m_vOpt,m_vFalse,m_vOpt,
m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt);
return res != 0;
}
catch(COleDispatchException* e)
{
AfxMessageBox(OleErrorMsg(e),MB_ICONEXCLAMATION);
e->Delete();
}
return false;
}
// Dialog mit Möglichkeiten anzeigen und Auswahl zurückgeben
bool CWord::CorrectSpelling(CString text,CString& corrected,CWnd* pParent,CPoint /*point*/)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(pParent != NULL);
bool ret = false;
CVorschlagDlg dlg(pParent);
dlg.m_strWort = text;
try
{
// ein Dokument muss geöffnet sein, sonst verweigert GetSpellingSuggestions!
Documents docs = m_word.GetDocuments();
_Document doc = docs.Add(m_vOpt,m_vOpt,m_vOpt,m_vTrue);
// jetzt die Vorschläge holen
SpellingSuggestions spells = m_word.GetSpellingSuggestions((LPCTSTR) text,m_vOpt,m_vOpt,m_vOpt,
m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt,m_vOpt);
// in die Stringlist des Dialogs einfüllen
for(int i = 1;i <= spells.GetCount();i++)
{
SpellingSuggestion ss = spells.Item(i);
dlg.m_slVorschlaege.AddTail((LPCTSTR) ss.GetName());
}
// das Dokument wieder schliessen
doc.SetSaved(TRUE);
doc.Close(m_vFalse,m_vOpt,m_vOpt);
}
catch(COleDispatchException* e)
{
AfxMessageBox(OleErrorMsg(e),MB_ICONEXCLAMATION);
e->Delete();
return false;
}
// Dialog öffnen und Ergebnis auswerten
// ACHTUNG: im Switch fällt das Ergebnis durch bis zu 3 Cases durch!
switch(dlg.DoModal())
{
case IDOK:
// noch zum Word-Wörterbuch hinzufügen
AddToDictionary(dlg.m_strWort);
case IDYES:
case IDIGNORE:
corrected = dlg.m_strWort;
ret = true;
break;
default:
break;
} // switch
return ret;
}
void CWord::AddToDictionary(CString text)
{
CString strFilename;
CStdioFile datei;
try
{
// den Dateinamen herausfinden
Dictionaries dics = m_word.GetCustomDictionaries();
Dictionary dic = dics.GetActiveCustomDictionary();
strFilename = dic.GetPath() + "\\" + dic.GetName();
}
catch(COleDispatchException* e)
{
AfxMessageBox(OleErrorMsg(e),MB_ICONEXCLAMATION);
e->Delete();
return;
}
try
{
if(!datei.Open(strFilename, CFile::modeReadWrite))
{
AfxMessageBox("Fehler beim Öffnen des Wörterbuches!",MB_ICONEXCLAMATION);
return;
}
// herausfinden ob Datei UNICODE - kodiert - für Office 2007
bool bUnicode = false;
unsigned char cBOM[2];
const unsigned char UNICODE_BOM[2] = {unsigned char(0xFF),unsigned char(0xFE)};
if(datei.GetLength() > 2)
{
datei.Read((LPVOID) cBOM,2);
bUnicode = cBOM[0] == UNICODE_BOM[0] && cBOM[1] == UNICODE_BOM[1];
}
datei.SeekToEnd();
if(bUnicode)
{
USES_CONVERSION;
LPCWSTR lpsz = T2W(text);
datei.Write(lpsz,wcslen(lpsz) * sizeof(WCHAR));
}
else
{
datei.WriteString(text + "\n");
}
datei.Close();
// jetzt noch das CRLF im Unicode nachschreiben
if(bUnicode)
{
using namespace std;
char crlf[4] = {13,0,10,0};
//ofstream of(strFilename,ios_base::binary | ios_base::_Openmode::app);
ofstream of(strFilename,ios_base::binary | ios_base::app);
of.write(crlf,4);
of.close();
}
}
catch(CException* e)
{
e->ReportError();
e->Delete();
}
}