从(非托管)C+;访问MS Word拼写检查器+; 我发现了一些与C语言中的MS单词拼写检查器交互的文章,并使用.NET管理C++。 (适用于有兴趣的人士:及) 但是我在MFC应用程序中使用COM,通过标准非托管C++做不到任何类似的东西。我假设.NET示例实际上使用的是COM,这意味着这是可能的,但这样做可能会很可怕和丑陋吗?

从(非托管)C+;访问MS Word拼写检查器+; 我发现了一些与C语言中的MS单词拼写检查器交互的文章,并使用.NET管理C++。 (适用于有兴趣的人士:及) 但是我在MFC应用程序中使用COM,通过标准非托管C++做不到任何类似的东西。我假设.NET示例实际上使用的是COM,这意味着这是可能的,但这样做可能会很可怕和丑陋吗?,c++,com,interop,ms-word,C++,Com,Interop,Ms Word,我这样做了。这并不复杂。我把整个东西打包在一个动态链接库中,并亲自制作了“建议”对话框 基本上,它只是打开一个单词,让它对一个特定的单词进行拼写检查。如果检查失败,您可以征求建议 只有两点可以让你失败: 1.文档必须是打开的,这意味着您必须始终在代码中创建一个文档 2.对于不同的单词版本,字典有时存储为unicode,有时(旧版本)不存储为unicode。当然,这只有在您想将新词存储到用户词典时才重要 好的,下面是代码: 头文件: #pragma once #include "msword.h"

我这样做了。这并不复杂。我把整个东西打包在一个动态链接库中,并亲自制作了“建议”对话框

基本上,它只是打开一个单词,让它对一个特定的单词进行拼写检查。如果检查失败,您可以征求建议

只有两点可以让你失败: 1.文档必须是打开的,这意味着您必须始终在代码中创建一个文档 2.对于不同的单词版本,字典有时存储为unicode,有时(旧版本)不存储为unicode。当然,这只有在您想将新词存储到用户词典时才重要

好的,下面是代码:

头文件:

#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()
{
//哈菲格·格布劳什特变种
m_vFalse=colevant((短)FALSE);
m_vTrue=colevant((短)TRUE);
m_vOpt=COleVariant((长)DISP_E_PARAMNOTFOUND,VT_ERROR);
m_bInit=假;
}
//辛诺沃勒·费勒梅尔登·埃斯泰伦
CString CWord::OleErrorMsg(COleDispatchException*e)
{
CString味精;
如果(!e->m_strSource.IsEmpty())
msg=e->m_strSource+“-”;
如果(!e->m_strDescription.IsEmpty())
msg+=e->m\u标准说明;
其他的
msg+=“unbekanner Fehler。”;
返回味精;
}
//单词starten
boolcword::Initialize()
{
尝试
{
如果(!m_bInit)
{
m_word.CreateDispatch(“word.Application”);
m_bInit=真;
}
}
捕获(COleDispatchException*e)
{   
AfxMessageBox(OleErrorMsg(e),MB_图标连接);
e->Delete();
返回false;
}
返回true;
}
//奥夫鲁门
void CWord::Terminate()
{   
尝试
{   
if(m_word!=NULL)
{
m_word.Quit(m_vFalse,m_vOpt,m_vOpt);
m_word.dispatch();
m_word=NULL;
m_bInit=假;
}
}
捕获(COleDispatchException*e)
{
AfxMessageBox(OleErrorMsg(e),MB_图标连接);
e->Delete();
}
}
//麦汁是一种很好的饮料
bool CWord::检查拼写(CString文本)
{
尝试
{
if(m_word==NULL)
{
AfxMessageBox(“Word nicht initialiseert!”,MB_图标信息);
返回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);
返回res!=0;
}
捕获(COleDispatchException*e)
{
AfxMessageBox(OleErrorMsg(e),MB_图标连接);
e->Delete();
}
返回false;
}
//对话:Möglichkeiten Anzegen和Auswahl zurückgeben
bool CWord::更正拼写(CString text、CString&corrected、CWnd*pParent、CPoint/*point*/)
{
AFX_管理_状态(AFXGetStaticModuleEstate());
断言(pParent!=NULL);
bool-ret=假;
CVorschlagDlg dlg(pParent);
dlg.m_strWort=文本;
尝试
{
//在这一天,我听到了很多建议!
Documents docs=m_word.GetDocuments();
_Document doc=docs.Add(m_vOpt,m_vOpt,m_vOpt,m_vTrue);
//福施勒格霍伦酒店
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);
//在对话列表中
对于(int i=1;i Delete();
返回false;
} 
//Dialogöffnen und Ergebnis auswerten
//ACHTUNG:我把它换成了三个案例!
开关(dlg.DoModal())
{
案例IDOK:
//noch zum Word-Wörterbuch hinzufügen
AddToDictionary(dlg.m_strWort);
案例分析:
案例IDIGNORE:
校正=dlg.m_strWort;
ret=真;
打破
违约:
打破
}//开关
返回ret;
} 
void CWord::AddToDictionary(CString文本)
{
CString strFilename;
CSTDOIFILE datei;
尝试
{
//赫拉斯芬登酒店
字典dics=m_word.GetCustomDictionaries();
Dictionary dic=dics.GetActiveCustomDictionary();
strFilename=dic.GetPath()+“\\”+dic.GetName();
}
捕获(COleDispatchException*e)
{
AfxMessageBox(OleErrorMsg(e),MB_图标连接);
e->Delete();
返回;
}
尝试
{
如果(!datei.Open(strFilename,CFile::modeReadWrite))
{
AfxMessageBox(“Fehler beimÖffnen des Wörterbuches!”,MB_图标连接);
返回;
}
//herausfinden ob Datei UNICODE-kodiert-für Office 2007
bool-bUnicode=false;
无符号字符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)
{
使用_转换;
LPCWSTR lpsz=T2W(文本);
数据写入(lpsz,wcslen(lpsz)*sizeof(WCHAR));
}
其他的
{
datei.WriteString(text+“\n”);
}
datei.Close();
//这是一个统一码的密码
if(bUnicode)
{
使用名称空间std;
char-crlf[4]={13,0,10,0};
//流(strFilename,ios_base::binary | ios_base::_Openmode::app);
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();
    }
}