開發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對象的使用和前兩點有些不同,例如: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;
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方法。2 pApplication->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pApplication);
3 MSPPT::_ApplicationPtr pApp;
4 m_pApplication->QueryInterface(__uuidof(MSPPT::_ApplicationPtr),(LPVOID*)&pApp);
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中斷開事件的連接:2 pAddInInst->QueryInterface(__uuidof(IDispatch), (LPVOID*)&m_pAddInInstance);
3 EApplicationEvents::DispEventAdvise(m_pApplication);
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, 1, 0>,
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 };
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, 1, 0>,
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,否則編譯會出錯。