本文介绍如何使用 Visual C++.NET 在单文档界面 (SDI) Microsoft 基础类 (MFC) 应用程序中将 Word 文档嵌入
View
对象。
创建嵌入 Word 文档的 MFC 应用程序
下列步骤介绍如何嵌入一个 Word 文档并自动化文档将数据添加到单元格。- 启动 Microsoft Visual Studio .NET。在文件菜单上,单击新建,然后单击项目。 在项目类型下面单击 Visual C++ 项目,然后单击模板下面的 MFC 应用程序。 将该项目命名为 Embed_Word。
- 显示 MFC 应用程序向导时,请按照下列步骤操作:
- 单击应用程序类型,然后选择单文档。
- 单击复合文档支持,然后选择容器。
- 单击完成以接受所有其他默认设置。
- 从 Word 对象库添加接口。为此,请按照下列步骤操作:
- 在项目菜单上,单击添加类。
- 从模板列表中选择类型库中的 MFC 类,然后单击打开。 将显示“从类型库添加类向导”。
- 在可用类型库列表中,找到 Microsoft Word 版本 对象库。 Word 2000 的版本是 9.0,Word 2002 的版本是 10.0。
- 添加下面的接口:
- _Document
- Range
- 单击完成。
- 将下面一行代码添加到 Cntritem.h 中,用作 CEmbed_WordCntrItem 类的公共成员函数:
LPDISPATCH GetIDispatch();
- 将 GetIDispatch 方法添加到 Cntritem.cpp 中,如下所示:
/******************************************************************* * This method returns the IDispatch* for the application that is linked to * this container. ********************************************************************/ LPDISPATCH CEmbed_WordCntrItem::GetIDispatch() { //The this and m_lpObject pointers must be valid for this function //to work correctly. The m_lpObject is the IUnknown pointer to // this object. ASSERT_VALID(this); ASSERT(m_lpObject != NULL); LPUNKNOWN lpUnk = m_lpObject; //The embedded application must be running in order for the rest //of the function to work. Run(); //QI for the IOleLink interface of m_lpObject. LPOLELINK lpOleLink = NULL; if (m_lpObject->QueryInterface(IID_IOleLink, (LPVOID FAR*)&lpOleLink) == NOERROR) { ASSERT(lpOleLink != NULL); lpUnk = NULL; //Retrieve the IUnknown interface to the linked application. if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR) { TRACE0("Warning: Link is not connected!\n"); lpOleLink->Release(); return NULL; } ASSERT(lpUnk != NULL); } //QI for the IDispatch interface of the linked application. LPDISPATCH lpDispatch = NULL; if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch) !=NOERROR) { TRACE0("Warning: does not support IDispatch!\n"); return NULL; } //After you verify that it is valid, return the IDispatch //interface to the caller. ASSERT(lpDispatch != NULL); return lpDispatch; }
- 将下面一行代码添加到 Embed_wordview.h 中,用作 CEmbed_WordView 类的公共方法:
void EmbedAutomateWord();
- 将下面一行代码添加到 Embed_wordview.cpp 中:
#include "CDocument0.h" #include "CRange.h" /******************************************************************** * This method encapsulates the process of embedding an Word * document in a View object and automating that document to add * some text. ********************************************************************/ void CEmbed_WordView::EmbedAutomateWord() { //Change the cursor so that the user knows that something exciting is going //on. BeginWaitCursor(); CEmbed_WordCntrItem* pItem = NULL; TRY { //Get the document that is associated with this view, and be sure that it is //valid. CEmbed_WordDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //Create a new item associated with this document, and be sure that it is //valid. pItem = new CEmbed_WordCntrItem(pDoc); ASSERT_VALID(pItem); // Get the Class ID for the Word document. // This is used in creation. CLSID clsid; if(FAILED(::CLSIDFromProgID(L"Word.document",&clsid))) //Any exception will do. You just need to break out of the //TRY statement. AfxThrowMemoryException(); // Create the Word embedded item. if(!pItem->CreateNewItem(clsid)) //Any exception will do. You just need to break out of the //TRY statement. AfxThrowMemoryException(); //Make sure that the new CContainerItem is valid. ASSERT_VALID(pItem); // Start the server to edit the item. pItem->DoVerb(OLEIVERB_SHOW, this); // As an arbitrary user interface design, this sets the // selection to the last item inserted. m_pSelection = pItem; // Set selection to the last inserted item. pDoc->UpdateAllViews(NULL); //Query for the dispatch pointer for the embedded object. In //this case, this is the Word document. LPDISPATCH lpDisp; lpDisp = pItem->GetIDispatch(); //Add text to the embedded Word document. CDocument0 wdDoc; CRange wdRange; //set CDocument0 wdDoc to use lpDisp, the IDispatch* of the //actual document. wdDoc.AttachDispatch(lpDisp); //Get a CRange object for the document. wdRange = wdDoc.Range(COleVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ), COleVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ) ); //Fill the range with the string "Hello, World!" wdRange.put_Text( "Hello, World!" ); } //Clean up if something went wrong. CATCH(CException, e) { if (pItem != NULL) { ASSERT_VALID(pItem); pItem->Delete(); } AfxMessageBox(IDP_FAILED_TO_CREATE); } END_CATCH //Set the cursor back to normal so the user knows exciting stuff //is no longer happening. EndWaitCursor(); }
- 将 Embed_wordview.cpp 中的 CEmbed_WordView::OnInsertObject 的代码替换为以下代码:
void CEmbed_WordView::OnInsertObject() { EmbedAutomateWord(); }
测试应用程序
- 按 F5 以生成并运行应用程序。
- 在应用程序的编辑菜单上,单击插入新对象。
- 检查结果。 一个新 Word 文档嵌入到了 View 对象中,包含的文本为“Hello, World!”。