• 开发OFFICE插件总结(转)


    前段时间做了个关于PPT的插件开发,简单总结一下。

    1. VC6.0中使用VBA
        在VC6.0中,可以使用导入类型库功能,即可连接到所需的OLB文件,并且可以选择导入的类。然后可以直接声明对象,如_Application m_app。需要注意的是,导入的类只能是实体类,包含虚函数的类都无法包含进来。

    2. VS2005中使用VBA
        VS2005中,由于没有导入类型库功能,可以使用VC6.0中生成的.H文件,并连接到OLB文件。使用方法和VC6.0中基本相同。

    3. VS2005中开发插件
        VS2005中,可以直接利用Project Wizard来开发OFFICE插件程序。
        生成的程序框架包含Connect.h,Connect.cpp,类CConnect中包含插件的加载事件处理函数。
        需要导入文件:
    1 #import "mso9.dll" rename_namespace("Office") \
    2 rename("RGB","OfficeRGB") \
    3 rename("DocumentProperties","OfficeDocumentProperties")
    4 using namespace Office;
    5 #import "VBE6EXT.olb" rename_namespace("VBE6")
    6 using namespace VBE6;
    7 #import "MSPPT9.OLB" named_guids,rename_namespace("MSPPT") \
    8 rename("RGB","PPTRGB")
    9 using namespace MSPPT;
        VBA对象的使用和前两点有些不同,例如:
    1 CComPtr<IDispatch> m_pApplication;
    2 pApplication->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pApplication);
    3 MSPPT::_ApplicationPtr pApp;
    4 m_pApplication->QueryInterface(__uuidof(MSPPT::_ApplicationPtr),(LPVOID*)&pApp);
        该调用方法缺点是调用比较麻烦,但是优点是可以使用虚函数。例如_Application类中的get_HWND方法。
     
    4. VS2005中开发插件-事件的加入
       
    PPT中的提供的事件及注册消息号如下表(详细请参见MSDN文章How to handle PowerPoint 2000 events or PowerPoint 2002 events by using Visual C++ .NET 2002 or Visual C++ .NET 2003 and Microsoft Foundation Classes):
    DISPID Method Name PowerPoint 2002 Only
    2001 WindowSelectionChange  
    2002 WindowBeforeRightClick  
    2003 WindowBeforeDoubleClick  
    2004 PresentationClose  
    2005 PresentationSave  
    2006 PresentationOpen  
    2007 NewPresentation  
    2008 PresentationNewSlide  
    2009 WindowActivate  
    2010 WindowDeactivate  
    2011 SlideShowBegin  
    2012 SlideShowNextBuild  
    2013 SlideShowNextSlide  
    2014 SlideShowEnd  
    2015 PresentationPrint  
    2016 SlideSelectionChanged x
    2017 ColorSchemeChanged x
    2018 PresentationBeforeSave x
    2019 SlideShowNextClick x

        首先在OnConnection函数中连接到事件源(establish a connection with the event source represented by pUnk),如下:
    1 pApplication->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pApplication);
    2 pAddInInst->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pAddInInstance);
    3 EApplicationEvents::DispEventAdvise(m_pApplication);
        同样,OnDisconnection中断开事件的连接:
    1 EApplicationEvents::DispEventUnadvise(m_pApplication)
        注册事件函数,以PRESENTATIONOPEN事件为例,Connect.h中的代码如下:
     1 _ATL_FUNC_INFO OnPresentationOpenInfo ={CC_STDCALL,VT_EMPTY,1,VT_DISPATCH};
     2 #define PPTADDIN_PRESENTATIONOPEN        2006
     3 class ATL_NO_VTABLE CConnect : 
     4     public CComObjectRootEx<CComSingleThreadModel>,
     5     public CComCoClass<CConnect, &CLSID_Connect>,
     6     public IDispatchImpl<AddInDesignerObjects::_IDTExtensibility2, &AddInDesignerObjects::IID__IDTExtensibility2, &AddInDesignerObjects::LIBID_AddInDesignerObjects, 10>,
     7     public IDispEventSimpleImpl<1,CConnect,&__uuidof(MSPPT::EApplication)>
     8 {
     9 public:
    10     typedef IDispEventSimpleImpl<1,CConnect,&__uuidof(MSPPT::EApplication)> EApplicationEvents;
    11     CConnect()
    12     {
    13     }
    14 
    15 DECLARE_REGISTRY_RESOURCEID(IDR_ADDIN)
    16 DECLARE_NOT_AGGREGATABLE(CConnect)
    17 
    18 BEGIN_COM_MAP(CConnect)
    19     COM_INTERFACE_ENTRY(IDispatch)
    20     COM_INTERFACE_ENTRY(AddInDesignerObjects::IDTExtensibility2)
    21 END_COM_MAP()
    22 
    23 BEGIN_SINK_MAP(CConnect)
    24     SINK_ENTRY_INFO(1, __uuidof(MSPPT::EApplication),/*dispid*/ 2006, OnPresentationOpen, &OnPresentationOpenInfo)
    25     
    26 END_SINK_MAP()
    27 
    28     DECLARE_PROTECT_FINAL_CONSTRUCT()
    29 
    30     HRESULT FinalConstruct()
    31     {
    32         return S_OK;
    33     }
    34 
    35     void FinalRelease() 
    36     {
    37     }
    38 
    39 public:
    40     //IDTExtensibility2 implementation:
    41     STDMETHOD(OnConnection)(IDispatch * Application, AddInDesignerObjects::ext_ConnectMode ConnectMode, IDispatch *AddInInst, SAFEARRAY **custom);
    42     STDMETHOD(OnDisconnection)(AddInDesignerObjects::ext_DisconnectMode RemoveMode, SAFEARRAY **custom );
    43     STDMETHOD(OnAddInsUpdate)(SAFEARRAY **custom );
    44     STDMETHOD(OnStartupComplete)(SAFEARRAY **custom );
    45     STDMETHOD(OnBeginShutdown)(SAFEARRAY **custom );
    46 private:
    47     CComPtr<IDispatch> m_pApplication;
    48     CComPtr<IDispatch> m_pAddInInstance;
    49 
    50 protected:
    51     typedef IDispEventSimpleImpl</*nID =*/ 1,CConnect, &__uuidof(MSPPT::EApplication)> ApplicationEvents;
    52     void __stdcall OnPresentationOpen(IDispatch * pres);
    53 };

        Connect.cpp中添加OnPresentationOpen的源代码。
        需要注意的是OnPresentationOpen函数的调用方式是__stdcall,否则编译会出错。
  • 相关阅读:
    Oracle的列操作(增加列,修改列,删除列),包括操作多列
    txt文本怎么去除重复项
    Javascript去掉字符串前后空格
    Js作用域链及变量作用域
    js变量以及其作用域详解
    如何在sqlserver 的函数或存储过程中抛出异常。
    存储过程如何处理异常
    设置VS2010和IE8 调试ATL控件<转>
    YUV图像合成原理<转>
    VS2013 查看程序各个函数的CPU利用率<转>
  • 原文地址:https://www.cnblogs.com/feng801/p/1392866.html
Copyright © 2020-2023  润新知