Excel插件开发

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

相关文章
相关标签/搜索