一、 新建ATL工程,在ATL项目向导中选中“容许合并代理/存根代码(P)”以及“支持MFC(M)”,以下图所示:app
单击完成,类视图以下所示:函数
二、 接下来为工程新建一个简单的ATL对象,并键入类名ExcelAddin1thCtrl:以下图所示:测试
在下一步中选择“ISupportErrorInfo(I)”ui
三、 为类“ExcelAddin1thCtrl”增长实现接口,右击该类,选择“添加”==》“实现接口”spa
在接下的对话框中,选择”文件“。路径为MSADDNDR.dll文件的位置。通常为插件
C:\Program Files\CommonFiles\DESIGNER\MSADDNDR.DLL代理
在下面的列表框中选择“_IDTExtensibility2接口。点击”完成“xml
四、接下来修改“ExcelAddin1thCtrl.rgs”文件(该文件名与创建的ATL简单对象类名加后缀得来)。对象
源文件内容以下:接口
HKCR
{
NoRemove CLSID
{
ForceRemove {FCC553EC-A0EC-48D6-8857-C0E4269E9664}= s 'ExcelAddin1thCtrl Class'
{
ForceRemoveProgrammable
InprocServer32 = s'%MODULE%'
{
valThreadingModel = s 'Apartment'
}
TypeLib = s '{F535D6BA-FAD9-4398-90EA-053B9CF45D2B}'
Version = s '1.0'
}
}
}
在后面加入
HKCR
{
ExcelAddin1th.ExcelAddin1thCtrl.1= s 'ExcelAddin1thCtrl Class'
{
CLSID = s '{FCC553EC-A0EC-48D6-8857-C0E4269E9664}'
}
ExcelAddin1th.ExcelAddin1thCtrl = s'ExcelAddin1thCtrl Class'
{
CLSID = s '{FCC553EC-A0EC-48D6-8857-C0E4269E9664}'
CurVer = s'ExcelAddin1th.ExcelAddin1thCtrl.1'
}
NoRemove CLSID
{
ForceRemove {FCC553EC-A0EC-48D6-8857-C0E4269E9664}= s 'ExcelAddin1thCtrl Class'
{
ProgID = s'ExcelAddin1th.ExcelAddin1thCtrl.1'
VersionIndependentProgID= s 'ExcelAddin1th.ExcelAddin1thCtrl'
ForceRemoveProgrammable
InprocServer32 = s'%MODULE%'
{
valThreadingModel = s 'Apartment'
}
TypeLib = s '{F535D6BA-FAD9-4398-90EA-053B9CF45D2B}'
Version = s '1.0'
}
}
}
HKCU
{
Software
{
Microsoft
{
Office
{
Excel
{
Addins
{
'ExcelAddin1th.ExcelAddin1thCtrl'
{
val FriendlyName = s'ExcelAddin1th'
val Description = s'ExcelAddin1th'
val LoadBehavior = d'00000003'
val CommandLineSafe = d'00000001'
}
}
}
}
}
}
}
注意:以上由不一样颜色标注的须要对应
五、编译,在Excel中的Com加载项中能够看到已成功注册了“ExcelAddin1th”插件,以下图所示:
六、接着,为插件增长IRibbonExtensibility接口,与上述增长实现接口相似,不过这次实现接口的位置选择“注册表(R)”,在可 以的类型库下拉框中选择Microsoft Office 12.0 Object Library<2.4>,在接口中选择IRibbonExtensibility接口,以下图所示:
此时,类向导将为咱们添加以下所示的一个函数(ExcelAddin1thCtrl.h中):
STDMETHOD(GetCustomUI)(BSTRRibbonID, BSTR * RibbonXml)
{
returnE_NOTIMPL;
}
以及类型库的导入(stdafx.h中):
#import "C:\ProgramFiles\Common Files\Microsoft Shared\OFFICE12\MSO.DLL"raw_interfaces_only, raw_native_types, no_namespace, named_guids, auto_search
编译程序,出现以下所示的错误:
由错误提示可知是类型重定义了,只需将上述的类型库导入修改成以下便可:
#import "C:\ProgramFiles\Common Files\Microsoft Shared\OFFICE12\MSO.DLL"
rename_namespace("Office") named_guids, exclude("pages")
using namespaceOffice;
在接着编译,会出现以下所示一大堆的错误,不用惧怕,其缘由就是类派生自纯虚类没法实例化对象的。根据错误提示,咱们将
STDMETHOD(GetCustomUI)(BSTRRibbonID, BSTR * RibbonXml)
修改成以下便可:
STDMETHOD(raw_GetCustomUI)(BSTRRibbonID, BSTR * RibbonXml)
七、利用IRibbonExtensibility接口增长插件界面,将上述的raw_GetCustomUI函数修改成以下
STDMETHOD(raw_GetCustomUI)(BSTRRibbonID, BSTR * RibbonXml)
{
if(!RibbonXml) {
return E_POINTER;
}
*RibbonXml = SysAllocString(
L"<customUIxmlns=\"http://schemas.microsoft.com/office/2006/01/customui\">"
L" <ribbon>"
L" <tabs>"
L" <tab id=\"CustomTab\""
L" label=\"电子签章\">"
L" <group id=\"CustomGroup\""
L" label=\"电子签章\">"
L" <button id=\"CustomButton\""
L" imageMso=\"HappyFace\""
L" size=\"large\""
L" label=\"用户登陆\""
L" onAction=\"UserLogin\"/>"
L" </group>"
L" </tab>"
L" </tabs>"
L" </ribbon>"
L"</customUI>"
);
return(*RibbonXml ? S_OK : E_OUTOFMEMORY);
}
编译成功后,打开Excel并无看到有关于插件的任何界面。其缘由在如下几个函数
STDMETHOD(OnConnection)(LPDISPATCHApplication, ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, SAFEARRAY * *custom)
{
returnE_NOTIMPL;
}
STDMETHOD(OnDisconnection)(ext_DisconnectModeRemoveMode, SAFEARRAY * * custom)
{
returnE_NOTIMPL;
}
STDMETHOD(OnAddInsUpdate)(SAFEARRAY * *custom)
{
returnE_NOTIMPL;
}
STDMETHOD(OnStartupComplete)(SAFEARRAY* * custom)
{
returnE_NOTIMPL;
}
STDMETHOD(OnBeginShutdown)(SAFEARRAY ** custom)
{
returnE_NOTIMPL;
}
将其返回值修改成S_OK,再次编译,成功显示了插件界面,以下图所示:
当咱们点击用户登陆按钮时发现并无任何响应,那是由于尚未实现RibbonXml中的UserLogin函数。
八、添加响应函数,右键单击“IExcelAddin1thCtrl”接口,选择添加方法,在对话框中的方法名中填写方法名,此方法名需与“RibbonXml”字段中的“OnAction”对应,其余以下图所示:
点击完成,接着在UserLogin函数中添加一个MessageBox查看是否已成功响应按钮消息,编译工程,打开 Excel,点击“用户登陆”按钮,发现并无任何响应,这是为何呢?这是因为IDispatch到IExcelAddin1thCtrl接口的COM 映射不会自动添加,只须要在BEGIN_COM_MAP中加入
COM_INTERFACE_ENTRY2(IDispatch,IExcelAddin1thCtrl)便可。编译,测试成功弹出MessageBox,以下图所示: