当前位置:编程学习 > VB >>

为啥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里这么写 
那么,我可以在外部工程比如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

--------------------编程问答--------------------
引用 2 楼 aisac 的回复:
Public Property Get m_dlg()
    Set m_dlg = mdlg
End Property
这样可以返回窗体,事件也可以使用。使用代码可以类似如下:
VB codePrivateSub Command1_Click()Dim clsTmpAsNew clsxx
        clsTmp.m_dlg.ShowSet clsTmp=NothingEnd Sub


这样返回的不是窗体,是Dialogs类对象。我要的是Form对象。 --------------------编程问答-------------------- 帮顶.

头晕的人飘过. --------------------编程问答-------------------- AC,你仔细看一下,mdlg是私有成员变量,不是对外暴露的。你在2楼的代码编译都通不过。

你如果不信我说的,可以自己把这个工程建起来实际试一下。感觉你并没有理解这里面的症结所在。 --------------------编程问答-------------------- 学习中~ --------------------编程问答-------------------- 返回一个object而不是form --------------------编程问答--------------------
引用 7 楼 xxyj6450 的回复:
返回一个object而不是form


谢谢,这个行得通。

第一个疑问还是没有解决:为啥ActiveX部件不让返回窗体,却允许显示窗体?这是什么逻辑啊? 
--------------------编程问答--------------------
引用 8 楼 slowgrace 的回复:
引用 7 楼 xxyj6450 的回复:
返回一个object而不是form


谢谢,这个行得通。

第一个疑问还是没有解决:为啥ActiveX部件不让返回窗体,却允许显示窗体?这是什么逻辑啊?

因为属性的实现代码类似如下:

HRESULT getProperty(属性名称,属性值,属性类型){
return 1;
}
由上面函数可知,属性名称是靠参数传递的,属性值是靠参数返回的,类型也是参数实现的。

由于类型最开始是确定的,所以无法返回用户自定义类型。 --------------------编程问答-------------------- 上面这段话,参考文献是《高级Visual Basic编程》一书,如果我记错了,请指正。 --------------------编程问答-------------------- 我在二楼发的这段代码是加到dialogs类内的。在发之前我已经测试过了。
Public Property Get m_dlg() 
    Set m_dlg = mdlg 
End Property 

--------------------编程问答--------------------
引用 9 楼 aisac 的回复:
引用 8 楼 slowgrace 的回复:
第一个疑问还是没有解决:为啥ActiveX部件不让返回窗体,却允许显示窗体?这是什么逻辑啊?

因为属性的实现代码类似如下:
HRESULT getProperty(属性名称,属性值,属性类型){
return 1;
}
由上面函数可知,属性名称是靠参数传递的,属性值是靠参数返回的,类型也是参数实现的。
由于类型最开始是确定的,所以无法返回用户自定义类型。


表达的很清楚,谢谢。 --------------------编程问答--------------------
引用 11 楼 aisac 的回复:
我在二楼发的这段代码是加到dialogs类内的。在发之前我已经测试过了。
VB codePublicPropertyGet m_dlg()Set m_dlg= mdlgEnd Property


看来你的意思是返回一个变体类型? --------------------编程问答--------------------
引用 13 楼 slowgrace 的回复:
引用 11 楼 aisac 的回复:
我在二楼发的这段代码是加到dialogs类内的。在发之前我已经测试过了。
VB codePublicPropertyGet m_dlg()Set m_dlg= mdlgEnd Property



看来你的意思是返回一个变体类型?

嗯,是的。 --------------------编程问答-------------------- 我没细看,错怪你了,对不起。

貌似对你有成见了,呵呵,我得注意克服一下。 --------------------编程问答-------------------- 编译后运行试试 --------------------编程问答--------------------
引用 16 楼 sysdzw 的回复:
编译后运行试试


?嘛意思?有什么不同么? --------------------编程问答-------------------- 关键是 Form、Control 等类型都是特殊的“混合”类型,有一些只能在 VB 中使用的特性。
如果直接在 ActiveX 部件中暴露出来,那么调用者可以不是 VB 程序,这就无法控制,所以 VB 加了限定。
而按照 2 楼的做法,暴露出来的不是 Form 而是 Object 类型,这是 COM 标准的 IDispatch 接口,无论那个调用者都可以使用。

就是 Form 不可以,Object 可以。 --------------------编程问答-------------------- 大概因为你拿出来显示,程序不知道你调用的资源是调用者的还是activex中的窗体? --------------------编程问答-------------------- 为什么要在外面来直接操作dll内部的窗体呢?我认为这样的设计思路会导致程序混乱,不便于维护 --------------------编程问答--------------------
引用 18 楼 tiger_zhao 的回复:
关键是 Form、Control 等类型都是特殊的“混合”类型,有一些只能在 VB 中使用的特性。
如果直接在 ActiveX 部件中暴露出来,那么调用者可以不是 VB 程序,这就无法控制,所以 VB 加了限定。
而按照 2 楼的做法,暴露出来的不是 Form 而是 Object 类型,这是 COM 标准的 IDispatch 接口,无论那个调用者都可以使用。

就是 Form 不可以,Object 可以。


一语中的,是微软考虑组件跨语言的通用性才这样做滴。vb的Form类不等于其他语言的Form类。
补充:VB ,  非技术类
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,