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

为何部件不能返回ActiveX控件的引用给客户端

--------------------编程问答-------------------- 专属的东西,随便都可以拿来用,还要VB干嘛 --------------------编程问答-------------------- ActiveX控件不是VB专属的,比如,VC程序员也可以写ActiveX控件的。 --------------------编程问答-------------------- 大凡车都有轮胎,自行车的能换到宝马上?( ⊙ o ⊙ ) --------------------编程问答-------------------- 我都是用Varaint或Ojbect返回 --------------------编程问答-------------------- 就在这段话下面有描述,其中之一的原因:
MSDN:
如果由于部件中所有公用对象的引用均被释放而使部件被关闭,则所有的私有对象也将被毁坏,即使客户端仍然在引用这些对象。
--------------------编程问答-------------------- 程序和控件中的信息交互是通过控件定义的属性交互的,只有定义的才能交互,否则不能交互,下面举例说明
1. 下面的控件属性为控件的版本号,只能调用显示,不能更改 i= 控件对象.Ver  '得到版本号
Public Property Get Ver() As String
    Ver = App.Major & "." & App.Minor & "." & App.Revision
End Property
2. 下面的控件属性为传入一字符串,调用 call 控件对象.AddTxt "sssss"
Public Sub AddTxt(ByVal sTxt As String)
    sPrnStr = sPrnStr & sTxt
End Sub
3. 下面的是控件的初始化动作,仅在控件内部调用有效,控件外不能调用
Private Sub UserControl_Initialize()
    sThickness = "2,4"
End Sub
--------------------编程问答--------------------
引用 5 楼 tiger_zhao 的回复:
就在这段话下面有描述,其中之一的原因:
MSDN:如果由于部件中所有公用对象的引用均被释放而使部件被关闭,则所有的私有对象也将被毁坏,即使客户端仍然在引用这些对象。


这里我有点晕。比如在一个ActiveX Dll工程里,用工程-部件引入工程的ActiveX控件,这个控件是私有的? --------------------编程问答-------------------- 比如像下面这样是不允许的,可是我不明白它为啥不允许?

'A public class module in an ActiveX Dll Component
Private m_tree As TreeView

Public Property Get Tree() As TreeView
    Set Tree = m_tree
End Property
--------------------编程问答-------------------- 部件的接口定义(TypeLib)是公共可见的。
但是控件实例是最终必定依赖与某个窗口,可以认为是某个窗口的私有成员。
如果你将控件实例的引用传递到外部,窗体卸载会导致控件实例的卸载,外部引用的控件对象处于不完整的状态,容易出错。
如果组件也卸载了,那么对象 VTable 中的函数指针也是不可用的,容易导致崩溃。 --------------------编程问答--------------------
引用 8 楼 slowgrace 的回复:
比如像下面这样是不允许的,可是我不明白它为啥不允许?

VB code'A public class module in an ActiveX Dll ComponentPrivate m_treeAs TreeViewPublicPropertyGet Tree()As TreeViewSet Tree= m_treeEnd Property

 Object吧,如楼上所说,控件依赖窗体而存在,类不是窗体,能容纳这个Treeview这个成员么? --------------------编程问答--------------------
引用 9 楼 tiger_zhao 的回复:
部件的接口定义(TypeLib)是公共可见的。
但是控件实例是最终必定依赖与某个窗口,可以认为是某个窗口的私有成员。
如果你将控件实例的引用传递到外部,窗体卸载会导致控件实例的卸载,外部引用的控件对象处于不完整的状态,容易出错。
如果组件也卸载了,那么对象 VTable 中的函数指针也是不可用的,容易导致崩溃。


可是你看下面这段:

Classes can have properties and methods of any public data type supported by Automation. This includes all arguments of properties and methods, as well their return values. The allowed data types include: 

Public objects provided by another component, such as DAO or a component authored using Visual Basic.

难道我不能认为ActiveX Control对象,比如我自己编的一个ShapeLabel控件,满足以上条件么?难道它不正是a component authored using Visual Basic的Public objects 么?既然满足这个规定,那其实我本来应该也可以它作为返回数据类型的吧?

类比一下,如果我能返回DAO的RecordSet,那我为嘛就不能返回ControDemo的ShapeLabel?它们不都是部件的公共对象么?怎么到了ActiveX Control这里,就变成私有的了?

按照你的解释,因为ActiveX Control实际依赖于某个窗体存在,因而是私有的;那如果我在部件内部也用了RecordSet,之后把它的引用返回给客户端,那不是也同样存在危险么?如果为了安全,应该干脆禁止返回所有对象才对?

我是不是哪里又搞混了?越写越乱。 --------------------编程问答-------------------- 比如上面8楼这段代码,报编译错:Private object modules cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types." 

如果把TreeView改成ADODB.Recordset,就不会有这个错。为嘛ADODB.Recordset就不被当做“Private object module ”,TreeView却会被当做“Private object module ”? --------------------编程问答-------------------- TreeView属于窗体,是依赖于窗体而存在的对象,而Recordset不是。。。 --------------------编程问答-------------------- 控件、窗体都不是简单对象。 --------------------编程问答-------------------- 感觉,是Private还是Public,其实是一种硬性规定。我只要死记硬背就好了。你看MSDN是这么说所谓“私有对象的”:

“Private objects are private for a reason, usually because they were not designed to be used outside your project.”

这和这个帖子18楼你的回复也是一致的。 --------------------编程问答-------------------- 没错,车辆右行只是因为规则就是这样设计的。
补充:VB ,  非技术类
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,