一、 新建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,以下圖所示: