实现Office的COM插件

转载 2012年03月27日 08:55:50

其他参考资料

http://www.vckbase.com/document/viewdoc/?id=1749

用VC6.0编写Word插件(Office2007篇)

http://www.vckbase.com/document/viewdoc/?id=1737

用VC6.0编写Word插件(Office2K、XP、03)

------------------------------------------------------------------------------------

以上为本人转载

下面是作者ZDNet China 的文章



实现Office的COM插件
作者: ZDNet China 
2003-08-11 01:43 PM

当软件开发者考虑扩展Microsoft Office时,最常想到方法就是是使用VB了。实际上,用C++和ATL扩展Office是相当容易的。

我将向你演示如何建立项目以及如何把Office插件作为COM对象注册到Office中去。(本文用Outlook来作为插件的主程序。)

项目的建立

让我们建立一个新的ATL项目。首先,添加一个叫着Plugin的简单COM对象。用类向导把_IDTExtensibility2接口添加到Plugin类中。(别忘了选中IsupportErrorInfo复选框。)

类向导会把下述方法添加到Plugin类中:OnConnection、OnDisconnection、OnAddinsUpdate、 OnStartupComplete、OnBeginShutdown。本文只处理OnConnection和OnDisconnection方法。

然后,在Plugin头文件中创建一个类型定义(typedef,它只是用来简化代码的),如下所示:

#define APPID 102
class CPlugin;
typedef IDispEventImpl<APPID, CPlugin, &DIID_ApplicationEvents,
&LIBID_Outlook,9,0> OutLookSink;

我们现在需要在Plugin类的继承列表中添加OutLookSink类:

class ATL_NO_VTABLE CPlugin :
       public IPlugin,
       public IDispatchImpl<_IDTExtensibility2, &__uuidof(_IDTExtensibility2),
               &LIBID_AddInDesignerObjects, /* wMajor = */ 1, /* wMinor = */ 0>,
    public OutLookSink

在Plugin.h文件中为Mso9.dll和Msoutl9.olb引入声明,如下所示:

#import "C:\Program Files\Common Files\Designer\msaddndr.dll" \
raw_interfaces_only, \
raw_native_types, no_namespace, named_guids, auto_search

#import "C:\Program Files\Microsoft Office\Office\mso9.dll" \
rename_namespace("Office") named_guids

#import "C:\Program Files\Microsoft \
 Office\Office\msoutl9.olb" \
rename_namespace("Outlook"), raw_interfaces_only, \
 named_guids

using namespace Office;
using namespace Outlook;

注意,你需要按照你的系统中的文件路径来修正上面那些被引入文件的路径。



你必须把Office扩展作为COM组件注册到Office中去。Visual C++自动产生.rgs文件来控制COM注册。我们将需要添加额外的项目加到.rgs文件来支持Office的自动注册。

在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office键下,有若干个子键,每一个子键对应于系统中安装的每一个Office应用程序。在这些键中有插件关键字(add-in key)。


为了在Office中注册我们的COM对象,我们需要在插件键中添加新键。在HKEY_CURRENT_USER下同样有对应的树来控制单个用户的插件,而HKEY_LOCAL_MACHINE控制整个机器的插件。

下面是.rgs文件中Outlook的插件注册码:

HKCU
{
    NoRemove Software
    {
        NoRemove Microsoft
        {
            NoRemove Office
            {
                NoRemove Outlook
                {
                    NoRemove Addins
                    {
                        ForceRemove OutlookDemo.Plugin.1
                        {
                            val FriendlyName = s 'Outlook Plugin'
                            val Description = s 'An Outlook plugin'
                            val LoadBehavior = d 3
                            val CommandLineSafe = d 0
                        }
                        
                    }
                }
            }
        }
    }
}

这套注册项是为特定用户注册插件的,为了把插件设置为整个系统范围之内可用,只需把HKCU改为HKLM。



LoadBehavior的值控制了主程序运行后插件的行为。为了让主程序开始运行后插件自动运行,把LoadBehavior的值设置为3。如果想让用户手工载入插件,就把LoadBehavior设置为8。

如果你编译了这个项目,你就有了一个Outlook 插件;这个插件实际上没有做任何事,但是它的确是一个可以工作的插件。

我们现在向这个插件添加一些功能。首先,添加一个新的成员变量:

     _ApplicationPtr m_pApp;

然后设置OnConnection方法:

    STDMETHOD(OnConnection)(LPDISPATCH Application,
                                                            ext_ConnectMode ConnectMode,
                                                            LPDISPATCH AddInInst,
                                                            SAFEARRAY * * custom)
    {
             HRESULT rslt = S_OK;
             try{
                  m_pApp = Application;
                  OutLookSynch::DispEventAdvise(m_pApp);
             }catch(_com_error &e){
                  OutputDebugString(e.ErrorMessage());
                                    rslt = E_UNEXPECTED;                
             }
             return rslt;
    }

再设置与之对应的OnDisconnection方法,如下所示:

    STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode,SAFEARRAY
* * custom)
      {
                 HRESULT rslt = S_OK;
                 try{
                       OutLookSynch::DispEventUnadvise(m_pApp);
                 }catch(_com_error &e){
                       OutputDebugString(e.ErrorMessage());
                       rslt = E_UNEXPECTED;
                 }
                 return rslt;
    } 

现在我们可以收到好几种事件,例如,OnNewMail事件。得到事件的信息以及它们的ID的最好方法就是打开MSVC工具菜单上的OLE/COM观察器(viewer)。

  1. 进入File菜单并选择View Typelib。
  2. 浏览Msoutl9.olb文件。
  3. Scroll down ApplicationEvents的dispinterface。注意OnNewMail事件的ID号为0x0000f003.。
  4. 向Cplugin类添加一个叫着OnNewMail的方法。
  5. 建立一个Sink映射来把OnNewMail方法关联到OnNewMail事件。

    BEGIN_SINK_MAP(CPlugin)
              SINK_ENTRY_EX(APPID, Outlook::DIID_ApplicationEvents, /
0x0000f003, OnNewMail)
    END_SINK_MAP()

现在我们只需要完成OnNewMail事件处理函数了。

    void _stdcall OnNewMail(){
           MessageBox(NULL, "New Mail", NULL, MB_OK);
    }

如果你想消除这些讨厌的弹出式对话框(由该项目所创建),那么最简单方法就是遵循下面的步骤:

  1. 进入Outlook的Tools | Options菜单项。
  2. 选择Other标签。
  3. 点击Advanced Options按钮。
  4. 点击COM 的插件按钮。
  5. 选中Outlook的Plugin项并点击Remove。
如你所见,Office的COM插件实现起来相对来说并不麻烦甚至可以说很轻松。创建一个COM Office插件最困难的计算出所有参数的初值。不过一旦你发现可以在OLE/COM查看器中得到这些信息,这也就不成问题了。

用VC6.0编写Word插件(Office2007篇)

 用VC6.0编写Word插件(Office2007篇) 作者:hjphy 下载源代码简介   微软在06年底推出了两个重量级的产品:Vista和Office 2007。在O...

CEF3:与 JavaScript 整合(一)

CEF 中的 JavaScript CEF 利用 V8 JS 引擎来实现 JS。 浏览器中的每一个 frame 都有自己的 JS 上下文,JS 只能在该上下文中执行。 JS 只能在渲染进程中的 T...

在 Office 系列软件中创建 COM 插件工具条,并实现工具条上的弹出菜单

前两天,在CSDN瞎逛悠,见一老兄问到此问,却没有人作答(顶的人倒还不少,国内的论坛是不是都这样?),还发了些牢骚,俺也顺便跟着发了点牢骚:) 于是坐下来静下心研究了一下,今日终于成了正果,不敢私吞...

【outlook plugin】Office2000下内部COM插件的编程实现 译者:徐景周

下载示例源代码 简介 你也许曾在Office2000下的Word2000、Access2000、Excel2000、PowerPoint2000等软件中的工具条或菜单条资源中,看到一些其它软件...

【outlook plugin】利用VC++/ATL开发Office 2003 COM插件

利用VC++/ATL开发Office 2003 COM插件 最近,我为一个客户写了一个Outlook2003的COM插件。当我为这个工程写代码的时候,我遇到了很多用C++无法解决的问题。对于一个...

C++实现Office插件

  • 2017年06月08日 08:46
  • 13KB
  • 下载

关于配置部署.net项目调用OFFICE的COM控件

.NET开发时有时会需要调用OFFICE的COM控件,那么首先服务器就需要安装OFFICE的环境,当然,用直接注册调用的COM控件也是可以的,但我没试验过。 配置成功的例子: 一、一个网站项目...
  • atco
  • atco
  • 2011年11月05日 12:08
  • 2051

由COM实现最简单的插件示例

  • 2013年08月23日 18:00
  • 160KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现Office的COM插件
举报原因:
原因补充:

(最多只允许输入30个字)