C++编写PowerPoint插件(一):第一个插件程序

本系列描述的是如何使用C++/COM来编写PowerPoint插件,使用的开发工具是 Visual Studio 2017。

前言

此处的“插件”,官方的翻译是“加载项”。一个是Addin, 一个是Plugin。

项目上需要实现一个Office/WPS都通用的插件,来实现业务系统与Office/WPS的联动。

那么实现Office/WPS的插件都有哪些方式呢?

Office插件的实现方式

COM

COM (Component Object Model, 组件对象模型)是微软的一套软件组件的二进制接口标准。

Office插件就是一个实现了IDTExtensibility2和IRibbonExtensibility两个接口的COM组件。IDTExtensibility2提供了Office插件接口,IRibbonExtensibility提供了Ribbon界面接口。

VSTO

VSTO (Visual Studio Tools for Office) 是指Visual Studio 为 Office开发人员提供的一系统工具。

通过VSTO, 可以方便的创建Office插件。从本质上讲, VTSO也是使用的COM。它使用 COM 包装器 (RCW) 通过托管 API 与 Office 进行通信。

runtime-callable-wrapper.gif

Web

基于较新版本的Office, 提供了基于Web技术的Office加载项。

COM 或 VSTO 加载项是旧 Office 集成解决方案,仅在 Windows 版 Office 上运行。与 COM 加载项不同,Office 加载项不涉及在用户设备或 Office 客户端中运行的代码。对于 Office 加载项,该应用程序(例如 Excel)会读取加载项清单,并挂钩 UI 中的加载项自定义功能区按钮和菜单命令。如果需要,它加载加载项的 JavaScript 和 HTML 代码,此代码在沙盒中的浏览器上下文范围内执行。

意思是Office内嵌了一个浏览器,自定义功能区中的按钮对应一个Web页面。页面与页面之间共享上下文,且提供了Office JavaScript API用来与Office进行通信。

WPS 插件的实现方式

复用 Office的COM插件

通过注册表的配置,WPS可以直接使用Office中COM实现的插件。

包括基于COM实现的插件以及VSTO实现的插件。

Web

和Office加载项 类似, WPS也使用Web技术玩了一套插件机制。官方称为WPS加载项。

不能说大概一致,只能说一模一样。

WPS内嵌了一个Chromium 开源浏览器,自定义功能区中的按钮对应一个Web页面。页面与页面之间共享上下文,且提供了wpsjs用来与WPS进行通信。

为什么使用COM

  • 项目上需要同时支持Office和WPS,这一条打枪了Web的方式
  • VSTO依赖.NET Framework,这可能带来部署的问题,如果部署时还需要安装一个.NET Framework,多不爽啊。打枪VSTO
  • 可以用C++开发

COM的缺点

  • 健壮性差。这是因为COM插件是与Office主进程在同一个进程间通信的,如果插件出什么问题,可能会影响到Office本身
  • 这是20年前的技术,文档少。

接下来我们就一步一步的实现第一个插件程序。

实现第一个插件程序

Step 1:创建一个ATL项目

  1. 打开 Visual Studio 2017

  2. 创建一个ATL项目

    build-cplusplus-addin-for-ppt-1.png
  3. 在ATL项目设置页,保持默认设置,点击确定

build-cplusplus-addin-for-ppt-2.png

确定后会生成初始工程代码,此时会看到该项目下有两个工程:NativePPTAddin和NativePPTAddinPS。

NativePPTAddinPS中的PS是指Proxy/Stub,当我们开发的组件需要用到代理/存根时,会用到此工程。

在这个例子中,此工程无用,后面所有的操作都是在NativePPTAddin工程进行的。

Step 2:添加一个ATL对象

  1. 右键点击NativePPTAddin工程,添加 -> 新建项。

  2. 选择 ATL 简单对象

build-cplusplus-addin-for-ppt-3.png
  1. 在ATL简单对象的向导页中,ProgID中输入 NativePPTAddin.Connect
build-cplusplus-addin-for-ppt-4.png

点击完成后,工程中会生成Connect.h/Connect.cpp这两个文件。

Step 3:实现接口

  1. 切换到类视图,展开NativePPTAddin节点

  2. 右键CConnect节点,添加 -> 实现接口

build-cplusplus-addin-for-ppt-5.png
  1. 在向导中,实现接口的位置选择注册表 ,可用类型库选择Microsoft Add-In Designer<1.0>
build-cplusplus-addin-for-ppt-6.png

_IDTExtensibility2 从可用接口框移动到实现接口中

  1. 点击确定,CConnect类已经继承了_IDTExtensibility2相关的接口。

    class ATL_NO_VTABLE CConnect :
     public CComObjectRootEx,
     public CComCoClass,
     public IDispatchImpl,
        public IDispatchImpl<_IDTExtensibility2, &__uuidof(_IDTExtensibility2), &LIBID_AddInDesignerObjects, /* wMajor = */ 1, /* wMinor = */ 0>
    

    _IDTExtensibility2是所有Office插件必须要实现的接口,它定义了插件与Office之间的通信。

Step 4:启动PPT试一下

  1. 打开Connect.h

  2. 将所有方法中的E_NOTIMPL替换成S_OK

  3. 在OnConnection函数中添加如下代码进行测试

    ::MessageBoxW(NULL, L"OnConnection", L"Native PPT Addin", MB_OK);
    return S_OK;
    
  4. 打开资源文件中的Connect.rgs,在末尾添加注册表信息

    HKCU
    {
        NoRemove Software
        {
            NoRemove Microsoft
            {
                NoRemove Office
                {
                    NoRemove PowerPoint
                    {
                        NoRemove Addins
                        {
                            NativePPTAddin.Connect
                            {
                                val Description = s 'Native PPT Addin'
                                val FriendlyName = s 'Native PPT Addin (ATL)'
                                val LoadBehavior = d 3
                                val CommandLineSafe = d 1
                            }
                        }
                    }
                }
            }
        }
    }
    

    PowerPoint在启动时会读取该注册表项的值,LoadBehavior 为 3表示在启动时自动加载。更详细的信息请参阅这里。

    此时,如果您构建项目,则会正确的注册表项将放入注册表中。

  5. 右键点击NativePPTAddin工程,点击属性,设置调试命令

build-cplusplus-addin-for-ppt-7.png

点击确定。

Step 5: 启动调试

  1. 启动调试,PowerPoint启动时,将会弹出一个消息框
build-cplusplus-addin-for-ppt-8.png

下一篇我们将演示如何为在PowerPoint功能区添加一个Tab页,以及在Tab页添加按钮。

完整的代码在这里。

Reference

  • https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2010/ee941475(v=office.14)

你可能感兴趣的:(C++编写PowerPoint插件(一):第一个插件程序)