1、问题的提出
有一个activex控件,原来是单独做的一个ocx,现在我把它拿到工程内部。之后我在form中用form.controls.add()添加这个对象,结果发现控件的left, top, width, height, tabindex等属性通通不能用了。
比如像上面这样做工程,那就不会有left, top, width, height, tabindex等属性,很有点奇怪。这时候只有把要添加的对象声明为control,才可以用上述属性,但是同时usercontrol特有的属性却丢失了,看下面的代码:
Private
Sub Form_Load()
'声明为UserControl类型,编译通不过
Dim myCtl As ShapeLabel
’ Set myCtl = Me.Controls.Add(" ControlDemo.ShapeLabel", " sl3") ‘编译通不过 '例0
Set myCtl = Me.Controls.Add(" Project1.ShapeLabel", " sl3") ‘例1
myCtl.Caption = " asdfad" ‘例2
myCtl.Visible = True '以下各句都报编译错:没相应属性 ‘例3
Debug.Print myCtl.Name, myCtl.Left
''声明为Control,有extender的各种属性,但是没办法得到用户控件特有的属性
Dim ctl As Control
Set ctl = Me.Controls.Add(" Project1.ShapeLabel", " sl5") ‘例4
ctl.Caption = " asdfad" '运行时错误,说没这个属性。 ‘例5
ctl.Visible = True ‘例6
Debug.Print ctl.Left, ctl.TabIndex, ctl.Width '这句可以正常运行
End
'声明为UserControl类型,编译通不过
Dim myCtl As ShapeLabel
’ Set myCtl = Me.Controls.Add(" ControlDemo.ShapeLabel", " sl3") ‘编译通不过 '例0
Set myCtl = Me.Controls.Add(" Project1.ShapeLabel", " sl3") ‘例1
myCtl.Caption = " asdfad" ‘例2
myCtl.Visible = True '以下各句都报编译错:没相应属性 ‘例3
Debug.Print myCtl.Name, myCtl.Left
''声明为Control,有extender的各种属性,但是没办法得到用户控件特有的属性
Dim ctl As Control
Set ctl = Me.Controls.Add(" Project1.ShapeLabel", " sl5") ‘例4
ctl.Caption = " asdfad" '运行时错误,说没这个属性。 ‘例5
ctl.Visible = True ‘例6
Debug.Print ctl.Left, ctl.TabIndex, ctl.Width '这句可以正常运行
End
2、理解Extender对象
要理解上面这个问题,先看下面这个图:
这里给我们带来麻烦的Name, Top, and Left等属性其实来自Extender对象。To the user of a control,
extender properties — such as Name, Top, and Left — appear to be part of your control. However, extender properties are really provided by the container your control is placed on. The Extender object of the UserControl gives you, the control designer, access to these properties from within your control. (The read-only Name property of the Extender object returns the name the container (or the user) gives to a specific instance of your control.)
也就是说,我们通常得到的UserControl对象其实包含两套接口,一套是Extender的接口,一套是UserControl特有的接口,不妨
称这时这个对象双毒俱全。很显然,我们在第一节的例子中,没取到Extender接口。
3、为何取不到Extender接口?(例7-例8)
先重复一下我们的问题。在VB6里建个Standard Exe工程,以两种不同方式测试如下这段代码:
Private
Sub Form_Load()
Dim aa As ShapeLabel
Set aa = Me.ShapeLabel1 ‘例7
Debug.Print aa.Left ‘例8
Set aa = Nothing
End Sub
Dim aa As ShapeLabel
Set aa = Me.ShapeLabel1 ‘例7
Debug.Print aa.Left ‘例8
Set aa = Nothing
End Sub
(1)第一种方式,直接在你的部件对话框里直接引用ShapeLabel对应的OCX;第二种方式,把部件里ShapeLabel对应的OCX取消掉,而直接如第一节中的图里那样把ShapeLabel对应的CTL文