2010-01-28 6 views
1

J'ai trouvé quelques articles sur l'interaction avec le vérificateur d'orthographe MS-Word de C# et la gestion de C++ avec .NET. (Pour les personnes intéressées: this et this)Accès au vérificateur d'orthographe MS-Word à partir de (non géré) C++

Mais je ne pouvais pas trouver quelque chose de comparable à le faire grâce à C++ non géré la norme dans une application MFC, COM à l'aide. Je suppose que les exemples .NET utilisent réellement COM, c'est possible, mais est-ce que ça risque d'être horrible et moche à faire?

Répondre

4

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(); 
    } 
} 
+0

Si vous en avez, je suis sûr que cela profiterait aux autres aussi bien qu'à moi. –

Questions connexes