为啥ActiveX部件不让返回窗体,却允许显示窗体?
为啥ActiveX部件不让返回窗体,却允许显示窗体?这是什么逻辑啊?比如,我有一个叫ThingDemo的ActiveX Dll。在其中有一个私有的窗体类叫dlgDemo,还有个公有的Dialogs类,用来供客户端显示dlgDemo对象。
'---------------------------------------------------------------------------------------
' Module : Dialogs
'---------------------------------------------------------------------------------------
Option Explicit
Private WithEvents mdlg As dlgDemo
Private Sub Class_Initialize()
Set mdlg = New dlgDemo
End Sub
Private Sub Class_Terminate()
Unload mdlg
Set mdlg = Nothing
End Sub
Public Sub ShowDialog()
mdlg.Show
End Sub
那么,我可以在外部工程比较Project1的Form1里这么写
Private Sub Form_Click()
Dim dgs as New Dialogs
dgs.ShowDialog
End Sub
像上面这样就可以顺利地显示来自部件的窗体。可是如果我想得到一个对这个窗体的引用,可是费老了劲了也不成。我试了如下这几种方式都不行,因为ActiveX部件不允许返回类型或者参数为私有对象。这个规定我倒是知道,不过的话,它为嘛这样规定啊?是出于什么考虑呢?
另外的话,如果我死活就是要得到来自部件的窗体的引用,有什么办法么?比如传个hwnd出来,然后再恢复成Form?
Public Sub GetForm(xx As Form)
Set xx = mdlg
End Sub
Public Function FormGet() As Form
Set FormGet = mdlg
End Function
Public Property Get MyForm() As Form
Set MyForm = mdlg
End Property
--------------------编程问答-------------------- 更正:
那么,我可以在外部工程
那么,我可以在外部工程比如Project1的Form1里这么写
--------------------编程问答-------------------- Public Property Get m_dlg()
Set m_dlg = mdlg
End Property
这样可以返回窗体,事件也可以使用。使用代码可以类似如下:
Private Sub Command1_Click()
Dim clsTmp As New clsxx
clsTmp.m_dlg.Show
Set clsTmp = Nothing
End Sub
--------------------编程问答--------------------
这样返回的不是窗体,是Dialogs类对象。我要的是Form对象。 --------------------编程问答-------------------- 帮顶.
头晕的人飘过. --------------------编程问答-------------------- AC,你仔细看一下,mdlg是私有成员变量,不是对外暴露的。你在2楼的代码编译都通不过。
你如果不信我说的,可以自己把这个工程建起来实际试一下。感觉你并没有理解这里面的症结所在。 --------------------编程问答-------------------- 学习中~ --------------------编程问答-------------------- 返回一个object而不是form --------------------编程问答--------------------
谢谢,这个行得通。
第一个疑问还是没有解决:为啥ActiveX部件不让返回窗体,却允许显示窗体?这是什么逻辑啊?
--------------------编程问答--------------------
因为属性的实现代码类似如下:
HRESULT getProperty(属性名称,属性值,属性类型){
return 1;
}
由上面函数可知,属性名称是靠参数传递的,属性值是靠参数返回的,类型也是参数实现的。
由于类型最开始是确定的,所以无法返回用户自定义类型。 --------------------编程问答-------------------- 上面这段话,参考文献是《高级Visual Basic编程》一书,如果我记错了,请指正。 --------------------编程问答-------------------- 我在二楼发的这段代码是加到dialogs类内的。在发之前我已经测试过了。
Public Property Get m_dlg()
Set m_dlg = mdlg
End Property
--------------------编程问答--------------------
表达的很清楚,谢谢。 --------------------编程问答--------------------
看来你的意思是返回一个变体类型? --------------------编程问答--------------------
嗯,是的。 --------------------编程问答-------------------- 我没细看,错怪你了,对不起。
貌似对你有成见了,呵呵,我得注意克服一下。 --------------------编程问答-------------------- 编译后运行试试 --------------------编程问答--------------------
?嘛意思?有什么不同么? --------------------编程问答-------------------- 关键是 Form、Control 等类型都是特殊的“混合”类型,有一些只能在 VB 中使用的特性。
如果直接在 ActiveX 部件中暴露出来,那么调用者可以不是 VB 程序,这就无法控制,所以 VB 加了限定。
而按照 2 楼的做法,暴露出来的不是 Form 而是 Object 类型,这是 COM 标准的 IDispatch 接口,无论那个调用者都可以使用。
就是 Form 不可以,Object 可以。 --------------------编程问答-------------------- 大概因为你拿出来显示,程序不知道你调用的资源是调用者的还是activex中的窗体? --------------------编程问答-------------------- 为什么要在外面来直接操作dll内部的窗体呢?我认为这样的设计思路会导致程序混乱,不便于维护 --------------------编程问答--------------------
一语中的,是微软考虑组件跨语言的通用性才这样做滴。vb的Form类不等于其他语言的Form类。
补充:VB , 非技术类