您的位置:首页 > 编程语言 > C语言/C++

使用 C++ .NET 和 MFC 嵌入并自动化 Word 文档

2013-06-04 21:35 453 查看
本文介绍如何使用 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();
}


备注EmbedAutomateWord 只是 OnInsertObject 的一种特殊情况,它使用户可以从可用 OLE 对象列表中选择对象来插入到应用程序中。 您将重写该行为,因为此演示不需要这种行为。


测试应用程序

按 F5 以生成并运行应用程序。
在应用程序的编辑菜单上,单击插入新对象
检查结果。 一个新 Word 文档嵌入到了 View 对象中,包含的文本为“Hello, World!”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: