配色: 字号:
VB_动态创建和删除VB控件
2016-04-07 | 阅:  转:  |  分享 
  
VB_动态创建和删除VB控件1.????概述?在使用VisualBasic??进行程序设计的过程中,如果能在运行时刻动态地创建和删除控件,可以极大地丰富界面的处理和变化。本人在设计网络监控系统时,需要在原理图与实物示意图间切换。切换的过程采用本文介绍控件的动态创建和删除来实现,有效地节省了系统资源,同时也有利于简化界面的维护。下面将就VisualBasic6.0中的控件在运行时刻的创建和删除的两种方法——控件数组和控件集合作详细的阐述。2.????基于控件数组的动态控件的创建与删除?vb??中的控件数组实际上也是一种数组,其中的每个控件具有相同的Name属性,但具有不同的Index属性,在这里Name属性类似于数组的名字,而Index属性类似于数组的下标同时,控件数组也支持普通VBA数组的LBound??、UBound和Count方法,控件数组中的控件可以共享一个事件过程,便于代码的编写和集中处理,这正是使用控件数组的最大的理由。但是控件数组与普通的数组并非完全一样,它不需要定义大小,只有这样我们才可以动态的扩展[kuozhan]它。下面给出利用Load命令动态添加控件和Unload命令动态删除控件的一般方法:(1)??????????????首先在窗体上放置一个TextBox,其Name属性设置为Text1,Index属性设置为0,这样我们就创建了一个TextBox控件数组,其中有一个成员。(2)??????????????在窗体上放置一个命令按钮Command1,在其Click事件中添加如下的代码:LoadText1(1)Text1(1).left=0Text1(1).visible=true(3)??????????????在窗体上放置一个命令按钮Command2,在其Click事件中添加如下的代码:UnloadText1(1)(4)??????????????运行。单击命令按钮Command1,窗体上会出现一个新的文本框;单击命令按钮Command2,窗体上刚出现的新的文本框就被删除。需要注意的是:Load命令创建的控件Text1(1)与设计时已经放在窗体上的控件Text1(0)有完全相同的属性,也包括大小和位置等属性,例外的就是Index属性不一样,Visible属性默认为False,所以必须在Load方法执行之后,执行调整控件位置的语句[yuju],并把其Visible属性设置为True,以便在窗体上可见。Unload命令只能删除动态加载的控件,若删除设计时创建的控件会产生错误[cuowu]。另外,利用上面提到的数组的一些方法,可以有效的简化代码的编写。以下的代码可以删除所有动态创建的Text1控件数组中的控件:?DoWhileText1.Count>1UnloadText1(Text1.Ubound)Loop需要说明[shuoming]的是,菜单数组是控件数组的一种特殊的形式,只是它是在菜单编辑器[bianjiqi]中设置相应的Name和Index属性,而且要求一个菜单控件数组中的菜单项必须是同一级菜单,但是不能创建新的顶级菜单。而动态创建和删除菜单项的方法也使用Load和Unload方法,只是默认情况下其Visible属性是True,而且不用重新设置相应的位置。????3.????基于控件集合的动态控件的创建与删除?VB??中提供一个Controls集合,用以包含当前窗体中的所有的控件,这对于实现一些功能相对复杂的操作相当有好处。而且Controls集合也是集合的一种,它支持一般集合的Count等方法和相应的检索[jiansuo]机制[jizhi]。以下两例就是利用这个控件集合的巧妙实现。要清空当前窗体上的所有的文本框,可以如下实现:DimCtlasControlForEachCtlinControlsIfTypeofCtlisTextboxthenCtl.Text=??””EndifNextCtl也可以利用集合的Count方法如下实现:Fori=0To????Controls.Count-1IfTypeofCtlisTextBoxControls(i).Text=??””EndifNexti当然,控件集合毕竟是一种特殊的集合,下面给出利用Add方法动态添加控件,Remove方法动态删除控件的一般方法:(1)??????????????Controls??集合的Add方法其语法[yufa]格式为:Setmycontrol=controld.Add(ProgId,Name,[Container])在这里,mycontrol是一个自定义的控件对象,若需要新创建的控件对事件做出反应,还要再定义该对象时增加WithEvents关键字ProgId??是库名.控件名形式的控件类的名字,ToolBox??中的控件一般具有类似于VB.CommandButton这样的形式。而ActiveX控件的形式则有所差别,比如若使用Windowless控件库中的控件一般具有类似于MsWless.WlText的形式。Name??参数是想赋给控件的名字,与控件的Name属性相对应。Container??参数是可选的,它代表欲放置控件的容器,默认情况下是放置在窗体上。下例是在窗体上动态创建一个命令按钮,然后单击命令按钮时,执行相应的动作:DimWithEventsmycontrolAsCommandButtonPrivateSubForm_Load()Setmycontrol=Controls.Add("VB.commandbutton","mycontrol")mycontrol.Left=0mycontrol.Caption="my"mycontrol.Visible=TrueEndSubPrivateSubmycontrol_click()MsgBox"Youclickme!",vbExclamationEndSub需要注意,动态创建的控件必须指定相应的属性,而且在默认情况下,其Visible属性是False。(2)??????????????Controls??集合的Remove方法利用Controls集合的Remove方法可以删除用Add方法动态创建的控件。其语法[yufa]格式为:Controls.Remove???“??控件名??”比如以上创建的mycontrol要删除可以使用如下的命令:Controls.Remove"mycontrol"同样应该注意,不能删除一个不存在或者在设计时创建的控件。4.ActiveX????控件的动态创建和删除?以上论述的方法适合于控件在应用程序[yingyongchengxu]工具箱(TOOLBOX)中的情况,而??ActiveX?控件一般在应用程序[yingyongchengxu]运行机器上,但没有在工具箱中,这种情况则需要先进行注册,方法是利用Regsvr32在Windows环境中注册,或者在VB代码中进行注册,方法如下:Shell(Systempath???&???“??regsvr32.exe/s/I"??&??MyControlName,vbHide)???其中Systempath是Regsvr32.exe所在的路径,??MyControlName是控件名字(包括路径)若要撤销,可以如下操作:Shell(Systempath???&???“??regsvr32.exe/s/U"???&??MyControlName,vbHide)???下面讨论注册但是未出现在工具箱(TOOLBOX)中的??ActiveX??控件的情况,这其中也包括VB自带的一些ActiveX控件的使用。具体的方法就是利用VBControlExtender对象。VBControlExtender对象与EventInfo相结合能提供事件陷井捕捉,它提供了一套通用的属性、方法、事件给开发人员,它的一个突出特点是能编程设计控件的事件,声明时若使用WithEvents关键字,则会有个特殊的事件ObjectEvent(InfoAsEventInfo),它能捕捉到对象使用RaiseEvent产生的所有事件,EventInfo数据结构[jiegou][shujujiegou]映射[yingshe]了事件的名称、参数个数和参数的值。VBControlExtender和??EventInfo相结合,采用SelectCase??就可以预先将不同类对象的事件放置一起,各自独立[duli]运作。下面的例子是使用未在工具箱(TOOLBOX)中出现的RichTextBox的方法,其他的??ActiveX??控件的使用方法与此类似:DimWithEventsmyControlAsVBControlExtenderPrivateSubForm_Load()Licenses.Add"RichText.RichTextctrl.1"SetmyControl=Controls.Add("RichText.RichTextctrl.1","mycontrol")myControl.Left=0myControl.Visible=TrueEndSubPrivateSubmyControl_ObjectEvent(InfoAsEventInfo)SelectCaseInfo.NameCase"MouseDown"MsgBox"mousedown"CaseElse‘??其他事件EndSelectEndSub需要注意,Licenses.Add"RichText.RichTextctrl.1"是响应[xiangying]控件的对象编号在VB中的注册,若此控件已经出现在工具箱(TOOLBOX)中,则会出错。另外,若ActiveX控件已经出现在TOOLBOX中,需要动态建立控件,则应该作如下的处理:首先去掉Licenses.Add"RichText.RichTextctrl.1"这一句,然后,在“工程属性窗口[chuangkou]”的“Make”页面下,确保[quebao]“removeinformationaboutunusedActiveXcontrols”不被选中即可。还有,若ActiveX控件已经出现在TOOLBOX中,需要动态建立控件,还可以用类似于前面介绍的控件集合的方法,比如上面示范的RichTextBox的例子还可以如下实现(只是这种方法不再支持ObjectEvent事件):DimWithEventsmyControlAsRichTextLib.RichTextBoxPrivateSubForm_Load()SetmyControl=Controls.Add("RichText.RichTextctrl.1","mycontrol")myControl.Left=0myControl.Visible=TrueEndSubPrivateSubmyControl_Click()MsgBox"click"EndSub5.结束语?通过以上对VisualBasic中的控件动态建立和删除进行了讨论,我们了解到控件数组??适??合于应用程序[yingyongchengxu]中需要该控件,但需要控件实例的具体数量不定的情况;而控件集合则适合于为了完成不同的任务[renwu],制作了多个不同功能的控件,在特定条件[tiaojian]下只需要一个或几个控件的情况对于ActiveX控件,若没有添加到VB工具箱中,当应用程序[yingyongchengxu]执行时,可以根据需要由程序自动加载或者删除。总之,合理地选择[xuanze]使用以上的各种方法,对于提高编程的效率和代码的运行效率都是大有裨益的。以上有关的代码都已在Windows2000Professional??和??VisualBasic6.0??企业版环境下测试通过。''//oooooooooooooooooooooooooooooooooooooooooooooooooooooo''以下是完整的测试代码--------------2011-1-21BYZHJ''//ooooooooooooooooooooooooooooooooooooooooooooooooooooooOptionExplicitDimWithEventsmycontrolAsCommandButton??''这句要放在全局定义Dimx1,y1PrivateSubCommand1_Click()????IfisControlExists("mycontrol")=TrueThen:ExitSub????Setmycontrol=Controls.Add("VB.commandButton","mycontrol")????Withmycontrol????????.Caption="可以拖动我看看!"????????.Left=100????????.Width=3000????????.Visible=True????EndWithEndSubPrivateSubCommand2_Click()????IfisControlExists("mycontrol")=FalseThen:ExitSub????Controls.Remove"mycontrol"EndSubPrivateSubCommand3_Click()????mycontrol_ClickEndSubPrivateSubForm_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)????Me.Caption=X&","&YEndSubPrivateSubmycontrol_Click()????DimobjAsObject????Dimstr????ForEachobjInControls????????str=str&vbCrLf&obj.Name????Next????IfisControlExists("mycontrol")=TrueThen????????MsgBoxstr,,"你点击了我!"????Else????????MsgBoxstr,,"控件已删除!"????EndIfEndSub''//自定义函数,判断控件是否存在FunctionisControlExists(ctlNameAsString)AsBoolean????DimobjAsObject????ForEachobjInControls????????Ifobj.Name=ctlNameThen????????????isControlExists=True????????????ExitFunction????????EndIf????Next????isControlExists=FalseEndFunctionPrivateSubmycontrol_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)????''Me.Caption=X&","&Y????Ifx1>0Andy1>0Then????????Withmycontrol????????????.Left=.Left+(X-x1)????????????.Top=.Top+(Y-y1)????????EndWith????EndIfEndSubPrivateSubmycontrol_MouseDown(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)????x1=X:y1=YEndSubPrivateSubmycontrol_MouseUp(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)????x1=IIf(x1>0,0,x1)????y1=IIf(y1>0,0,y1)EndSub

献花(0)
+1
(本文系yuxb图书首藏)