Excel插件开发

来源:互联网 发布:淘宝一千零一夜在哪 编辑:程序博客网 时间:2024/05/21 22:36

1、  新建ATL工程,在ATL项目向导中选中“允许合并代理/存根代码(P)”以及“支持MFC(M)”,如下图所示:


单击完成,类视图如下所示:


2、  接下来为工程新建一个简单的ATL对象,并键入类名ExcelAddin1thCtrl:如下图所示:



在下一步中选择“ISupportErrorInfo(I)”


3、  为类“ExcelAddin1thCtrl”增加实现接口,右击该类,选择“添加”==》“实现接口”


在接下的对话框中,选择”文件“。路径为MSADDNDR.dll文件的位置。一般为

C:\Program Files\CommonFiles\DESIGNER\MSADDNDR.DLL

在下面的列表框中选择“_IDTExtensibility2接口。点击”完成“



4、接下来修改“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'

                 }

               }

             }

          }

       }

   }

}

注意:以上由不同颜色标注的需要对应

5、编译,在Excel中的Com加载项中可以看到已成功注册了“ExcelAddin1th”插件,如下图所示:


6、接着,为插件增加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)

7、利用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函数。

8、添加响应函数,右键单击“IExcelAddin1thCtrl”接口,选择添加方法,在对话框中的方法名中填写方法名,此方法名需与“RibbonXml”字段中的“OnAction”对应,其他如下图所示:


点击完成,接着在UserLogin函数中添加一个MessageBox查看是否已成功响应按钮消息,编译工程,打开Excel,点击“用户登录”按钮,发现并没有任何响应,这是为什么呢?这是由于IDispatch到IExcelAddin1thCtrl接口的COM映射不会自动添加,只需要在BEGIN_COM_MAP中加入

COM_INTERFACE_ENTRY2(IDispatch,IExcelAddin1thCtrl)即可。编译,测试成功弹出MessageBox,如下图所示:



原创粉丝点击