使用com技术对word进行操作,不同于网上流行的使用类型库的方法,直接调用word应用程序对象的接口方法,

以下是一个简单应用的代码:

int main(int argc, char* argv[])
{

// ******************* Declare Some Variables ********************

// Variables that will be used and re-used in our calls
    DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
    VARIANT vResult;
    OLECHAR FAR* szFunction;
    BSTR bstrTemp;

// IDispatch pointers for Word's objects
    IDispatch* pDispDocs;      //Documents collection
    IDispatch* pDispSel;       //Selection object
    IDispatch* pDispActiveDoc; //ActiveDocument object

// DISPID's
    DISPID dispid_Docs;        //Documents property of Application object
    DISPID dispid_DocsAdd;     //Add method of Documents collection
                               //object
    DISPID dispid_Sel;         //Selection property of Applicaiton object
    DISPID dispid_TypeText;    //TypeText method of Selection object
    DISPID dispid_TypePara;    //TypeParagraph method of Selection object
    DISPID dispid_ActiveDoc;   //ActiveDocument property of Application
                               //obj
    DISPID dispid_SaveAs;      //SaveAs method of the Document object
    DISPID dispid_Quit;        //Quit method of the Application object

// ******************** Start Automation ***********************

//Initialize the COM libraries
    ::CoInitialize(NULL);

// Create an instance of the Word application and obtain the pointer
    // to the application's IDispatch interface.
    CLSID clsid;
    CLSIDFromProgID(L"Word.Application", &clsid);

IUnknown* pUnk;
    HRESULT hr = ::CoCreateInstance( clsid, NULL, CLSCTX_SERVER,
                                     IID_IUnknown, (void**) &pUnk);
    IDispatch* pDispApp;
    hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDispApp);

// Get IDispatch* for the Documents collection object
    szFunction = OLESTR("Documents");
    hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_Docs);
    hr = pDispApp->Invoke (dispid_Docs, IID_NULL, LOCALE_USER_DEFAULT,
                           DISPATCH_PROPERTYGET, &dpNoArgs, &vResult,
                           NULL, NULL);
    pDispDocs = vResult.pdispVal;

// Invoke the Add method on the Documents collection object
    // to create a new document in Word
    // Note that the Add method can take up to 3 arguments, all of which
    // are optional. We are not passing it any so we are using an empty
    // DISPPARAMS structure
    szFunction = OLESTR("Add");
    hr = pDispDocs->GetIDsOfNames(IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_DocsAdd);
    hr = pDispDocs->Invoke(dispid_DocsAdd, IID_NULL, LOCALE_USER_DEFAULT,
                           DISPATCH_METHOD, &dpNoArgs, &vResult, NULL,
                           NULL);

// Get IDispatch* for the Selection object
    szFunction = OLESTR("Selection");
    hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_Sel);
    hr = pDispApp->Invoke (dispid_Sel, IID_NULL, LOCALE_USER_DEFAULT,
                           DISPATCH_PROPERTYGET, &dpNoArgs, &vResult,
                           NULL, NULL);
    pDispSel = vResult.pdispVal;

// Get the DISPIDs of the TypeText and TypeParagraph methods of the
    // Selection object.  We'll use these DISPIDs multiple times.
    szFunction = OLESTR("TypeText");
    hr = pDispSel->GetIDsOfNames(IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_TypeText);

szFunction = OLESTR("TypeParagraph");
    hr = pDispSel->GetIDsOfNames(IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_TypePara);

// The TypeText method has and requires only one argument, a string,
    // so set up the DISPPARAMS accordingly
    VARIANT vArgsTypeText[1];
    DISPPARAMS dpTypeText;

bstrTemp = ::SysAllocString(OLESTR("One"));
    vArgsTypeText [0].vt = VT_BSTR;
    vArgsTypeText [0].bstrVal = bstrTemp;
    dpTypeText.cArgs = 1;
    dpTypeText.cNamedArgs = 0;
    dpTypeText.rgvarg = vArgsTypeText;

//Invoke the first TypeText and TypeParagraph pair
    hr = pDispSel->Invoke (dispid_TypeText, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpTypeText, NULL, NULL, NULL);
    hr = pDispSel->Invoke (dispid_TypePara, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpNoArgs, NULL, NULL, NULL);
    ::SysFreeString(bstrTemp);

//Invoke the second TypeText and TypeParagraph pair
    bstrTemp = ::SysAllocString(OLESTR("Two"));
    hr = pDispSel->Invoke (dispid_TypeText, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpTypeText, NULL, NULL, NULL);
    hr = pDispSel->Invoke (dispid_TypePara, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpNoArgs, NULL, NULL, NULL);
    ::SysFreeString(bstrTemp);

//Invoke the third TypeText and TypeParagraph pair
    bstrTemp = ::SysAllocString(OLESTR("Three"));
    hr = pDispSel->Invoke (dispid_TypeText, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpTypeText, NULL, NULL, NULL);
    hr = pDispSel->Invoke (dispid_TypePara, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                           &dpNoArgs, NULL, NULL, NULL);
    ::SysFreeString(bstrTemp);

// Get IDispatch* for the ActiveDocument object
    szFunction = OLESTR("ActiveDocument");
    hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT,
                                  &dispid_ActiveDoc);
    hr = pDispApp->Invoke (dispid_ActiveDoc, IID_NULL,
                           LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
                           &dpNoArgs, &vResult, NULL, NULL);
    pDispActiveDoc = vResult.pdispVal;

//Set up the DISPPARAMS for the SaveAs method (11 arguments)
    VARIANT vArgsSaveAs[11];
    DISPPARAMS dpSaveAs;
    dpSaveAs.cArgs = 11;
    dpSaveAs.cNamedArgs = 0;
    dpSaveAs.rgvarg = vArgsSaveAs;

BSTR bstrEmptyString;
    bstrEmptyString = ::SysAllocString(OLESTR(""));

VARIANT vFalse;
    vFalse.vt = VT_BOOL;
    vFalse.boolVal = FALSE;

//TRY THIS:
    //To see the error handler in action, change the following
    //line to:
    //
    //     bstrTemp = ::SysAllocString(OLESTR("c://badpath//doc1.doc"));
    bstrTemp = ::SysAllocString(OLESTR("c://doc1.doc"));

//TRY THIS:
    //To see the error handler in action, change the following
    //line to:
    //
    //   vArgsSaveAs[10].vt = VT_I4;        
    vArgsSaveAs[10].vt = VT_BSTR;        
    vArgsSaveAs[10].bstrVal = bstrTemp;        //Filename
    vArgsSaveAs[9].vt = VT_I4;           
    vArgsSaveAs[9].lVal = 0;                   //FileFormat
    vArgsSaveAs[8] = vFalse;                   //LockComments
    vArgsSaveAs[7].vt = VT_BSTR;
    vArgsSaveAs[7].bstrVal = bstrEmptyString;  //Password
    vArgsSaveAs[6].vt = VT_BOOL;     
    vArgsSaveAs[6].boolVal = TRUE;             //AddToRecentFiles
    vArgsSaveAs[5].vt = VT_BSTR;
    vArgsSaveAs[5].bstrVal = bstrEmptyString;  //WritePassword
    vArgsSaveAs[4] = vFalse;                   //ReadOnlyRecommended
    vArgsSaveAs[3] = vFalse;                   //EmbedTrueTypeFonts
    vArgsSaveAs[2] = vFalse;                   //SaveNativePictureFormat
    vArgsSaveAs[1] = vFalse;                   //SaveFormsData
    vArgsSaveAs[0] = vFalse;                   //SaveAsOCELetter

//Invoke the SaveAs method
    szFunction = OLESTR("SaveAs");
    hr = pDispActiveDoc->GetIDsOfNames(IID_NULL, &szFunction, 1,
                                  LOCALE_USER_DEFAULT, &dispid_SaveAs);
    EXCEPINFO excep;
    hr = pDispActiveDoc->Invoke(dispid_SaveAs, IID_NULL,
                                LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                                &dpSaveAs, NULL, &excep, NULL);
    if (FAILED(hr))
    {
        ErrHandler(hr, excep);
    }

::SysFreeString(bstrEmptyString);

//Invoke the Quit method
    szFunction = OLESTR("Quit");
    hr = pDispApp->GetIDsOfNames(IID_NULL, &szFunction, 1,
                                 LOCALE_USER_DEFAULT, &dispid_Quit);
    hr = pDispApp->Invoke (dispid_Quit, IID_NULL, LOCALE_USER_DEFAULT,
                           DISPATCH_METHOD, &dpNoArgs, NULL, NULL, NULL);

//Clean-up
    ::SysFreeString(bstrTemp);
    pDispActiveDoc->Release();
    pDispSel->Release();
    pDispDocs->Release();
    pDispApp->Release();
    pUnk->Release();

::CoUninitialize();

return 0;

}

以上程序创建了一个空文档,在其中键入几条文字并保存,然后退出。

就这么几个功能却要写这么多代码,是不是很烦?因为这是很底层的代码。使用类型库,也只不过是对这些代码

的封装,在这里不需要导入类型库,只要机器上装有word,程序就能运行,不需要看word版本的脸色。如果嫌

麻烦,完全可以把一些功能封装成自己的类,自己动手,丰衣足食。

需要注意的两点问题如下:

在使用完接口指针后,必须释放;

使用完应用程序对象后,必须退出。

在这里word和excel是不一样的。word只要执行"Quit"方法,不管内存中接口引用计数是否为0,直接退出,当然

退出前是会做一些对象内部的清理工作,但不处理引用计数。在退出后,我们需要执行接口的Release()操作,这

时候会产生一个RPC服务器不可用的异常,说得也是,word都退出了,还怎么Release()啊,但这是应该做的,目

的是使引用计数清零。excel的做法是只要内存中还有接口,就退出不了,除非你把接口清干净了。以下是微软技

术支持网站上的原话:(机器翻译的,凑和着能看)

PRB: Office 应用程序仍保留在内存程序完成后

症状

Office application are automating continues to your Visual C++ program finishes...

<script type=text/javascript> loadTOCNode(1, 'symptoms'); </script>

Office application are automating continues to your Visual C++ program finishes executing after reside in memory。

原因

最有可能该应用程序是仍然在内存中,因为您忘记了要释放的收购的接口。

<script type=text/javascript> loadTOCNode(1, 'cause'); </script>

最有可能该应用程序是仍然在内存中,因为您忘记了要释放的收购的接口。

解决方案

下面是一些一般性建议并尝试确定问题的原因时需要的事项查找: 如果您使用 # import,则很可能您可能正在运行到与其关联的引用计数错误之一。 通常这些错误可以...

<script type=text/javascript> loadTOCNode(1, 'resolution'); </script>

下面是一些一般性建议并尝试确定问题的原因时需要的事项查找:

  • 如果您使用 # import,则很可能您可能正在运行到与其关联的引用计数错误之一。 通常这些错误可以工作周围,但通常它首选使用其他自动化方法之一。 # import 不能正常工作很好地与 Office 应用程序,因为它的类型库和使用是相当复杂。 此外,这样的引用计算问题是难以跟踪大量接口级别 COM 调用的因为这样使用 # import 时。
  • check to see if are calling any methods,such as Open or New,that return IDispatch * (LPDISPATCH),and ignoring return value. if are,then are abandoning this returned 的 interface and will need to change your code so that release this IDispatch * when no longer needed.
  • 逐渐注释掉,直到该问题会消失,然后将其添加您的代码部分回到跟踪该问题开始处慎。
  • 请注意某些应用程序将保持运行如果用户具有"涉及"应用程序。 如果您要使其自动运行时,出现这种情况,然后在应用程序将可能保持以后运行。 Office 应用程序在应用程序对象,您可以读 / 写若要更改此行为上有一个"UserControl"属性。
  • also,some applications will decide to stay running if enough user-interface"action"has occurred。 if intend for to exit application,then its Quit() method call on Application object。 Word will shut down regardless of its reference count is called Quit when。 this isn't expected 的 COM behavior。 Excel,however,will properly just hide itself but stay running until all outstanding interfaces are released。 一般情况下,您应该释放所有未完成的引用,并只调用 Quit() 如果希望应用程序退出。

用com操作word相关推荐

  1. python操作word文档(python-docx)

    python操作word文档(python-docx) 1. 效果图 1.1 python-docx文档标题段落(等级.加粗.斜体.居中)效果图 1.2 python-docx字体(加粗.斜体.居中. ...

  2. phpexcel_cell 获取表格样式_Java 操作Word表格——创建嵌套表格、添加/复制表格行或列、设置表格是否禁止跨页断行...

    精品推荐 国内稀缺优秀Java全栈课程-Vue+SpringBoot通讯录系统全新发布! Docker快速手上视频教程(无废话版)[免费] 作者:E-iceblue https://www.cnblo ...

  3. python在windows下操作word的方法的代码

    把写内容过程经常用的一些内容收藏起来,下边内容内容是关于python在windows下操作word的方法的内容,希望能对各位朋友有些好处. import win32com from win32com. ...

  4. python入门教程2word-使用python操作word

    前言 最近工作中,需要将查询的一段时间的数据可视化,并导出为word格式.由于对word操作不熟悉,查阅了一下相关文档,这里简要记录一下如何使用python操作word. 说明 该代码记录了对word ...

  5. python入门教程2word-python操作word入门

    1.安装pywin32 http://sourceforge.net/projects/pywin32 在files里去找适合你的python版本.截止此文,最新版本是pywin32-219快捷路径: ...

  6. python入门教程2word-入门干货:Python操作Word文件经验分享

    原标题:入门干货:Python操作Word文件经验分享 导读:Microsoft Word在当前使用中是占有巨大优势的文字处理器,这使得Word专用的档案格式Word 文件(.docx)成为事实上最通 ...

  7. java word表格_java操作word的表格

    java操作word的表格 最近项目中需要把提交的页面表单的数据动态写在word模板中,简单的写了个工具类.里面有怎眼操作word 中表格的内容,可以在word中已有的表格后面添加行并且可以增加内容. ...

  8. ASP.NET操作Word文档(转)

    ASP.NET操作Word文档(转) 操作WORD配置说明 引入:Word的对象库文件"MSWORD.OLB"(word 2000为MSWORD9.OLB) 1.运行Dcomcnf ...

  9. word python 域 操作_python实现在windows下操作word的方法

    本文实例讲述了python实现在windows下操作word的方法.分享给大家供大家参考.具体实现方法如下: import win32com from win32com.client import D ...

  10. Python 操作Word文档插入图片和表格实例演示

    Python 操作Word文档插入图片和表格实例演示 效果图 实现过程 ① python-docx 库安装 ② word 文档插入图片演示 ③ word 文档插入表格演示 [ 文章推荐 ] Pytho ...

最新文章

  1. [转]C#日期格式化 文档
  2. mysql数据库优化看的书_MySQL 数据库优化,看这篇就够了
  3. 异步fifo_跨时钟域同步(异步FIFO)
  4. 速度申请!2020年度腾讯犀牛鸟精英人才培养计划今日发布
  5. java 1 0_【Java】1.0 开发环境
  6. UML类图中会涉及到的一些概念、关系
  7. python爬虫淘宝视频_Python2爬虫:以抓取淘宝MM为例(实战)
  8. python requests form data_Python requests模块 multipart/form-data类型文件上传
  9. 拒绝捞回中的效果评估与策略二次调用
  10. 类型的取值范围_Java基础类型取值范围,从基础的理解加深记忆
  11. python数学实验与建模_Python数学
  12. 细说分布式Redis架构设计和那些踩过的坑
  13. Chromium OS编译手记
  14. linux添加软件源命令,Linux 添加源
  15. Java读取计算 PPT,Word,excel的页数
  16. 分享一下个人3年的运维经验
  17. 就业形势严峻,应届生应该如何做好职业规划?
  18. java cryptography_Java密码体系结构简介:Java Cryptography Architecture (JCA) Reference Guide...
  19. i51235u和i512500h区别 i5 1235u和i5 12500h哪个好
  20. 如何实现点击收藏,图标变色;再次点击,取消收藏,图标变回原来的颜色,且能把已收藏的项发送请求给后端

热门文章

  1. 花菁荧光染料Cy3/Cy5/Cy7标记COX-2环氧合酶,Cy3/Cy5/Cy7-Cyclooxygenase-2
  2. Sqoop使用与原理
  3. 2021超新Python安装
  4. python图像处理:图像融合
  5. 2023年2月访问学者博士后热门国家出入境政策变化汇总
  6. 联想G450笔记本开机后屏幕黑屏的解决办法
  7. 七年级计算机c语言测试题,2017年初一下学期数学期末检测试题
  8. vue过滤器filter中this指向问题
  9. 小米VR一体机游戏开发日记(第一天)
  10. 查看MySQL初始密码、解决MySQL5.7修改密码以及密码认证失败(Your password does not satisfy the current policy requirements)