【VB开源代码栏目提醒】:网学会员为广大网友收集整理了,VB下Add-Ins的编程 - 计算机教材,希望对大家有所帮助!
摘要 本文从一个具体例子出发阐述了在Visual Basic 5.0环境下进行外接程序Add-Ins开发的原理、关键技术和注意事项并对其相关技术如ActiveX、多态性与接口、事件变量等
VB5新引进的编程概念也做了必要的分析和描述。
关键词外接程序Add-InsActiveX接口多态事件变量 一、 概述 Visual Basic下的Add-Ins即外接程序是扩展
VB编程环境的非常有用的工具。
作为一个开发者我们发现在使用Visual Basic集成开发环境IDE时经常需要重复地干同一件简单的工作如设置所有或一类控件的字体前景及背景颜色改变控件的Tab次序等。
这些简单、单调而重复性的劳动如果由程序自动完成将变得非常方便而Add-Ins正为实现这一功能提供了可能。
与Visual Basic的早期版本不同Visual Basic5.0下的Add-Ins是一种模块化的ActiveX部件可以作为ActiveX DLL或EXE文件进行编译。
另外跟以前的版本相比
VB5下Add-Ins无论从编程思想还是从其扩展模型的对象与结构来说变化都比较大因此
VB5下编写Add-Ins程序与早期版本将会有很大不同。
在这篇文章中我们将从一个具体例子出发阐述
VB5下Add-Ins的编程。
二、 问题的提出 在Visual Basic下进行窗体设计时我们一般希望自己的程序具有风格一致的界面如同类控件具有相同的外观、相同的字体等。
另外我们在设计时还应该考虑到屏幕分辨率的变化对程序的影响例如我们经常发现出现这样的
问题即在某一分辨率如800600下看起来比较好的字体当在另一分辨率下如640480运行时将变得非常难看或者在中文环境下看起来比较舒服但在英文环境下却很不清晰。
这种种原因都使得我们必须调整窗体控件的字体以达到最佳效果。
但如果表单或控件比较多时手工调整将会非常繁琐而且容易出错因此编写一个Add-Ins以实现字体的自动调整将会非常实用。
本文中的例子即是用来实现此功能的。
三、 编程方法 编写Add-Ins的最简单方法是首先利用
VB5的编程模板生成一个Add-Ins的框架然后在此框架上进一步实现自己的
代码。
具体方法是在
VB5的“文件”菜单下选择“新建工程”然后在弹出的窗口中选择“外接程序”英文版中是“Add-Ins”即可。
这时
VB5将生成一个名为MyAddin的工程该工程中包括一个窗体frm AddIn一个模块AddIn以及一个类模块Connect。
下面我们对这些部分分别做一简单分析。
1 类模块Connect 整个类模块Connect的
代码均是由模板自动生成的大大方便了程序员编程但其源
代码中有一些比较重要的概念与方法对我们理解
VB Add-Ins甚至
VB面向对象编程均有很大好处。
下面我们对如下几点做一简单介绍源
代码由于是
VB自动产生这里就没有列出了。
1实现IDTExtensibility接口 所有的
VB外接程序都必须实现IDTExtensibility接口该接口包含了当外接程序与Visual Basic连接时Visual Basic调用的一些方法无论是通过外接程序管理器还是其它一些手段。
接口是
VB5引入的新概念是Visual Basic提供多态性的一种重要手段。
我们知道面向对象的语言一般都提供多态性。
如C语言通过类的继承关系子类重载父类的方法以实现其不同的特性或父类仅提供方法框架即无函数体的虚函数而子类具体实现其
代码。
简单地说多态意味着许多类可以提供同样的属性或者方法而且调用者在调用这些属性或方法之前不必知道某个对象属于什么类。
严格来说Visual Basic不是完整意义上的面向对象编程语言但它也能实现多态性不过这种多态性不是通过继承来实现的而是通过多重ActiveX接口来提供的。
多态性具体实现方法简单来说首先是建立一个类模块然后在该模块中声明一些子程序Sub但不实现其
代码这样该类模块可以说是一个抽象类也即接口然后建立其它的类模块在这些类模块的声明部分中使用Implements语句表明该类实现了上述接口接下来就可以实现接口
代码也即接口的方法了。
这种用Implements语句的方法可以说与
Java语言比较相似。
至于这方面的详细信息可参看
VB的帮助或联机手册。
在类模块Connect中使用Implements IDTExtensibility语句声明该类实现了IDTExtensibility接口。
因此类模块Connect中实现了该接口包括的四个方法OnAddInsUpdateOnConnectionOnDisconnectionOnStartupComplete的
代码例如一条语句、过程调用、注释等等。
如果过程是空的话它会被编译器删掉。
如果实在没有
代码可往这些过程里加的话就插入注释。
这是因为既然实现了接口就必须提供接口的所有方法的
代码。
这四种方法中比较关键的是OnConnection和OnDisconnection方法其中OnConnection方法当一个外接程序通过“外接程序管理器”对话框或另一个个接程序与Visual BasicIDE连接时被调用。
我们一般在该方法中保存当前Visual Basic会话期实例挂接
VB菜单工具栏或显示初始窗口以便用户使用该外接程序。
而OnDisconnection方法当外接程序通过编程或“外接程序管理器”对话框与Visual BasicIDE分离时被调用。
我们一般在该方法中卸掉菜单、工具栏、
程序窗体以及做保存设置等工作。
2挂接Visual BasicIDE菜单 在接口IDTExtensibility的OnConnection方法
代码中一般来说大多数情况下需要挂接Visual BasicIDE菜单当然也可以是工具栏以便用户可随时使用该程序。
挂接菜单的
代码如下 Set MCBmenuCommandBar AddToAddinCommandBar My Addin sink the event Set Me.MenuHandler VBinst.Events.CommandBarEvents mcbMenuCommandBar 其中AddToAddInCommandBar 函数的
代码如下 Function AddToAddInCommandBar sCaption As StringAs-Office.CommandBarControl Dim cbMenuCommandBar As Office.CommandBarControl Dim cbMenu As Object On Error Go To AddToAddInCommandBarErr see if we can find the Add-ins menu Set cbMenuVbinstance.CommandBars Add-ins If cbMenu is Nothing Then not available so we fail Exit Function End if add it to the command bar Set cbMenuCommandBarcbMenu.Controls.Add1 set the caption cbMenuCommandBar.Caption sCaption Set AddToAddInCommandBar cbMenuCommandBar Exit Function AddToAddInCommandBarErr: End Function 写上面的
代码中mcbMenuCommandBar变量定义为 Dim mcbMenuCommandBar As Office.CommandBarControl MenuHandler变量定义为 Public WithEvents MenuHandler As CommandBarEvents 这里需要指出的是MenuHandler是WithEvents变量凡是WithEvents变量均表明该变量是一个用来响应由ActiveX对象触发的事件的对象变更。
也就是说该变量是拥有事件的因此可以编写该变量的事件
代码。
在上述
代码中将事件对象VBInst.Events.Comman-dBarEventsmcbMenuCommandBar赋予MenuHandler变量则表示当发生有关mcbMenuC-ommandBar菜单项的事件时由该变量的
代码进行处理。
在类模块中我们发现就存在MenuHandler-Click事件
代码该
代码用以显示窗体对话。
在AddToAddInCommandBar函数中VBInstance是在OnConnection方法保存的会话期实例所有Add-Ins的调用都需要此实例。
使用VBInstance. CommandBars“Add-Ins”将获得Add-Ins菜单条对象在中文
VB5下是“外接程序”菜单条请注意该“Add-Ins”是不会本地化的因此无论是在中文还是英文
VB5下抱歉获得上菜单条对象。
代码Set cbMenuCommandBarcbMenu.Controls.Add1在该菜单下添加一新的菜单项“My AddIn”使用了cbMenu.Controls的Add方法。
关于菜单条的层次关系及相应的属性及方法可以参看
VB关于外接程序的帮助或联机手册。
但通过笔者的实践认为最好的方法是使用F2打开
VB的浏览器其类之间的层次关系以及对象事件方法属性一目了然。
关于类Connect中的其它方面的
代码一般来说比较容易理解这里就不叙述了。
3. 模块AddIn 模块AddIn比较简单仅包含一个子程序 Sub AddToINI Dim ErrCode As Long ErrCodeWritePrivateProfileString Add-Ins32My AddIn.Connect0vbaddin.ini End Sub 该程序可以在立即窗口中运行以便将关于此外接程序的信息添加到Windows目录下的vbaddin.ini文件中去这样
VB的外接程序管理器就可以认识该程序并可将其挂接到
VB的IDE环境中。
该程序所做的
工作很简单只是在vbaddin.ini文件的Add-Ins32下添加一行My AddIn.Connect0表明My AddIn没有挂接到IDE环境中若My AddIn.Connect1则
VB启动时自动挂接该程序。
4. 窗体frm AddIn 窗体frm AddIn中的
代码是由用户编写的模板仅给出了一个框架。
针对我们上面提出的具体问题我们设计了一个简单的用户界面包括如下控件 1标签Label1:CaptionAll controls In SelectedForm: 2
列表框List1:用于显示表单中的所有控制。
3命令按钮fontButton 0:Caption Select Font用于将选中的窗体上所有控制的字体设为缺省字体。
注缺省字体为宋体9号字这种字体在中文环境不同分辨率下效果都比较好。
4命令按钮fontButton 1:Caption Select Font选择该按钮后将弹出选择字体然后程序将选中的窗体上所有控制的字体均设为用户选择的字体。
5命令按钮ExitButton:CaptionExit用于退出此程序实际上的工作只是隐藏了窗体frm AddIn。
外接程序的真正退出还是需要外接程序管理器中删去。
6通用对话框CommonDialog1:用于弹出选择字体的通用对话框便于用户从中选择所需字体。
下面是窗体
代码 Public VBInstance As vbide.VBE Public Connect As Connect Dim mcmpCurrentForm As VBComponent Option Explicit Private Sub ChangeFont NewFontName As StringNewFontSize As IntegerNewFontBold As BooleanNewFontltalic As Boolean Dim control As VBControl On Error Resume Next List1.Clear Set mcmpCurrentForm VBInstance.SelectedVBComponent If mcmpCurrentForm.Typevbext-ct-VBForm And- mcmpCurrentForm.Typevbext-ct-UseControl And- mcmpCurrentForm.Typevbext-ct-DocObject And- mcmpCurrentForm.Typevbext-ct-PropPage Then Exit Sub End if For Each control in mcmpCurrentForm.Designer.VBControls List.AddItem control.ControlObject.Name control.ControlObject.FontName NewFontName control.ControlObject.FontSize NewFontSize control.ControlObject.FontBole NewFontBole control.ControlObject.FontItalic NewFontItalic Next End Sub Private Sub ExitButton-Click Index As Integer Connect.Hide End Sub Private Sub FontButton-Click Index As Integer Select Case Index Case 0 ChangeFont 宋体9FalseFalse Case 1 With CommonDialog1 .Flags cdlCFBoth .ShowFont ChangeFont.FontName.FontSize.FontBold.FontItalic End With End Select End Sub 上面的
代码比较简单关键的
代码在于获取屏幕上的所有控制在Visual Basic5.0下与早期版本不同它利用了VBComponent对象的Designer属性获取屏幕上的
设计器它可以是窗体也可以是ActiveX控件或ActiveX
文档等然后通过该设计器来获得设计器上的用户控制。
上述
代码中首先将mcmpCurrenForm变量被设为当前选中的构件然后判断它是否是窗体用户控件ActiveX
文档或属性页如果是则获取其设计器即Designer对象然后通过Designer对象的VBControls属性获得其上所有控制的集合这样就可以操作该集合中的每一个VBControls控制了。
对每一个控制通过其ControlObject 属性可以获得其相应的屏幕上的控制对象然后就可以设置该对象的任意属性了。
在上述
代码中也可以使用control.PropertiesFontname取代control.ControlObject.FontName其结果是一样的。
另外为了防止对没有Font属性的控制进行该属性设置将导致错误发生在程序的开头使用了On Error Resume Next语句以忽略这些错误。
下面是该程序的用户界面 四、 进一步的改进 对上述程序还可做进一步的改进下面列出几种改进思想及编程方案。
1、 设置控制的其它属性 上述
代码主要用来设置控制的字体但基于同样的原理我们只要对
代码稍加改变就可以设置控制的其它属性如前景色背景色可见或不可见等。
2、 为当前工程中的所有窗体设置控制属性 在上述
代码中是对当前选中的窗体里的控制设置字体但有时我们需要将工程中的所有窗体中的所有控制一次设置其属性而不是每次选择一个窗体进行设置。
这时可以采用如下方法首先用VBE即当前会话期实例的ActiveVBProject属性获得当前的工程然后通过其VBComponents属性获得当前工程中的所有组件集合针对每一组件判断它是否为窗体或 ActiveX控件等剩下的
代码就和上面基本一样了。
3、 仅为选中的控制设置属性 若只是需要为选中的控制设置属性则可以利用VBForm 对象的SelectedVBControls属性获得当前选中的所有控制的集合然后对其包含的控制设置属性即可。
也可利用VBControl的InSelection属性判断该控制是否被选中然后仅对选中的控制设置属性即可。
4、 当控件被添加到窗体时自动为它设置属性 要实现当控件被添加到窗体时自动为它设置属性的功能需要用到VBE的事件对象即与上面提到的为菜单提供事件
代码的方法一样。
首先声明一个事件变量Public WithEvents CtlHandler As VBControlsEvents然后在接口IDTExtensibility的OnConnection方法
代码中挂接控制事件处理Set Me.CtlHandlerVBInstance.Events.VBControlsEvents NothingNothi-ng这样就可以进行事件处理了。
而进行事件处理的
代码可写在CtlHandler变量的ItemAdded
代码中如下 Private Sub CtlHandler-ItemAddec ByVal VBControl As VBIDE.VBControl 这里可加入所需要的
代码。
End Sub 当然除上述改进外我们还可以提出更多的改进
方案以丰富原程序的功能。
总之由于
VB显露其IDE包括窗口、工程、控制甚至事件、
代码等各个部分的接口使得我们能非常简单而有效地控制自己的编程活动和定制自己的界面从而节省了编程时间提高了工作效率也减少了错误的发生。