Je l'ai fait. Ce n'est pas que compliqué. J'ai emballé le tout dans une DLL et fait la boîte de dialogue de suggestions moi-même. Fondamentalement, il s'agit juste d'ouvrir le mot et de lui demander de faire une vérification orthographique pour un seul mot spécifique. Si la vérification a échoué, vous demandez des suggestions.
Il n'y a que deux points où vous pouvez échouer: 1. un document doit être ouvert, cela signifie que vous devez toujours créer un dans le code 2. pour les différentes versions de mots, le dictionnaire est parfois stocké sous forme unicode et parfois (versions plus anciennes) pas. Bien sûr, cela n'est important que si vous voulez stocker de nouveaux mots dans le dictionnaire utilisateur.
Ok, voici le code:
fichier d'en-tête
:
#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);
};
Et la mise en œuvre (uniquement des pièces les plus importantes, désolé pour les commentaires allemand -> je les traduirai en cas de besoin)
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();
}
}
Si vous en avez, je suis sûr que cela profiterait aux autres aussi bien qu'à moi. –