开发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,
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,否则编译会出错。