这是一封邮件,答复一个试图在VB6中通过名称访问窗体的问题。
有个问题想请教一下 vb6列举窗体(form)时用以下语句 for each frm in forms .......... next 这样好像只能列举已经加载的mdi主窗体和mdi子窗体,如果我想列举所有的窗体,包括未加载的和非mdi子窗体,有什么办法呢? 在磁盘上app.path上vb6的所有窗体都是*.frm,这样是可以列举,但找出来的是窗体名字的字符串,由于窗体名字是只读的,我怎么通过字符串的名字得到一个窗体? 另外,得到窗体后我想列举窗体上的所有控件,包括控件类型,是否只有这样一个办法:if typeof picture1 is picturebox then 不知我把问题说清楚了吗? 谢谢!
在VB6中,窗体是一个运行时对象,这种对象只有在程序运行时并且加载后才存在,可以通过遍列Forms集合得到这些对象。而对于没有加载的窗体,可以认为它是不存在的,当然也就无法得到。
如果我理解得没错的话,你想要得到的“窗体”其实不是对象,而是定义(类型)。这里有两个概念:定义(类型),和对象(实例)。打个比方,“人”是一种类型,而“张三”和“李四”都是“人”的具体实例。这两个概念是现代面向对象编程语言的基础,C++,Java,C#...等语言都遵循类型-实例这个范型,但是Javascript不是,VB6也不是(VB.NET是)。VB6不区分类型和实例。比如你新建一个简单的窗体应用程序,你说 Form1 是什么?当你写
Unload Form1时,Form1 是一个窗体对象(实例),而当你写
Dim f As New Form1时,Form1 却是一个类型,f 才是对象,通过这句话,你创建了类型为 Form1、名称为 f 的窗体实例。
解释到这里,想必你能明白你说的“列举所有的窗体,包括未加载的和非mdi子窗体”其实是一个在逻辑上讲不通的目标。不过你既然提出这个问题,背后肯定有合理的需求,我假设你是想在运行时动态地设定某些窗体的属性,比如你希望某些窗体在有些情况下不可用。如果真是这样,我的建议是在窗体的OnLoad事件里写控制当前窗体(或其控件)的代码,当然如果你有几十上百个窗体,这么做确实很麻烦,但是在我所知的范围内,没有别的办法了。把窗体创建为ActiveX(COM)对象也许可行,因为ActiveX也体现了类型-实例概念,但是这应该也不适用于有大量窗体的情形,而且使用ActiveX本身也会增加开发工作量(只是根据常识推断一下,实际上我没动手做过)。
至于遍列窗体上的所有控件,你可以用 Controls 集合,比如
Dim c As Control For Each c In Form1.Controls MsgBox c.Name Next c
我说的这些未必能解决你的实际问题,仅希望对你理解你所使用的编程工具有帮助。
0 评论:
发表评论