IUnknown
??
VB6拾遗:IUnknown接口与COM对象 http://demon.tw/programming/vb6-repick-iunknown-com.html VB6是建立在COM之上的,所有的COM对象都必须实现IUnknown接口。
IUnknown接口的IDL定义如下: VB6是建立在COM之上的,所有的COM对象都必须实现IUnknown接口。
IUnknown接口的IDL定义如下:
QueryInterface用于接口查询,AddRef和Release用于引用计数。 QueryInterface用于查询组件实现的其它接口,说白了也就是看看这个组件的父类中还有哪些接口类,AddRef用于增加引用计数,Release用于减少引用计数。引用计数也是COM中的一个非常重要的概念。大体上简单的说来可以这么理解,COM组件是个DLL,当客户程序要用它时就要把它装到内存里。另一方面,一个组件也不是只给你一个人用的,可能会有很多个程序同时都要用到它。但实际上DLL只装载了一次,即内存中只有一个COM组件,那COM组件由谁来释放?由客户程序吗?不可能,因为如果你释放了组件,那别人怎么用,所以只能由COM组件自己来负责。所以出现了引用计数的概念,COM维持一个计数,记录当前有多少人在用它,每多一次调用计数就加一,少一个客户用它就减一,当最后一个客户释放它的时侯,COM知道已经没有人用它了,它的使用已经结束了,那它就把它自己给释放了。 引用计数是COM编程里非常容易出错的一个地方,但所幸VC的各种各样的类库里已经基本上把AddRef的调用给隐含了,在我的印象里,我编程的时侯还从来没有调用过AddRef,我们只需在适当的时侯调用Release。至少有两个时侯要记住调用Release,第一个是调用了 COM是很复杂的东西,不是一两句话能够说得清楚的,感兴趣的话可以看看《COM原理与应用》、《COM技术内幕》、《COM本质论》等书籍。 VB6将复杂的COM都隐藏起来了,使得COM对象使用起来非常的简单: Sub Main() Dim o1 As Collection Dim o2 As Object Dim o3 As Control Set o1 = New Collection Set o2 = o1 Set o3 = o1 End Sub 生成的汇编代码如下:
__vbaNew函数用于创建对象,__vbaObjSet用于将对象变量指向内存中的对象。 当用一个对象变量给另一个对象变量赋值时,如果两边变量的类型相同,Set赋值时使用__vbaObjSetAddref函数,使其指向同一个对象,并调用该对象的AddRef函数增加引用计数;如果变量的类型不同,Set赋值前调用__vbaCastObj函数,__vbaCastObj内部调用对象的QueryInterface查询对象是否实现了相应的接口,实现了的话则用__vbaObjSet赋值,否则抛出异常“类型不匹配”。 当变量超出作用范围时需要调用__vbaFreeObj函数,与函数的名称不符,该函数并不一定会释放对象所占用的内存,而只是调用对象的Release函数减少引用计数,只有当对象的引用计数为0时对象所占的内存才会被释放。
vb中有指针吗?(实例为双向循环链表) https://zhidao.baidu.com/question/47259296.html VB的指针挺简单的,用着也很方便,其实对象变量就可以看成是指针,当你用Set A=Obj时,A就是指向Obj的地址,不用API就可以,当然用API可以实现更为高级的结构。 先定义一个结点类,类名为Node,代码为: Private Sub Class_Initialize() Private Sub Class_Terminate() Private Sub Form_Load() Public Sub CreateLinkList() Public Sub PrintList() List2.AddItem "Backwards" Public Sub DeleteList() Public Sub InsertNode(head As Node,data As Single) 结果类的构造器Class_Initialize()过程,类的析构Class_Termainate()过程,结点内存的分配和回收都由类自身完成,还有多态,pHead As Object;Set pHead =New Node;Set pHead.pPrev = p;指向基类的指针指向了子类,并调用了子类的属性,是不是挺像C++的代码? 链表有了,二叉树,由临接表构成的图等数据结构都很容易实现了吧,实际上用VB能构造很复杂的数据结构,上面的代码只是简单的示例,实际可以做的更完善。 上面三个方法并没有在Microsoft的正式文档资料中公布(包括MSDN),但查看VB6的基本动态运行库MSVBVM60.DLL可以发现这三个方法: [entry(0x60000006),hidden]
VB6编程技术大全中实例(并非原文,稍微编辑一下) § 7-4-2 集合类 集合类保存了私有集合变量的引用,并连接到外部界面,以使客户代码相信它正在交互处理真正的Collection。基于之上的目的,要增强已有的类(Invoice)的功能,就要再建立一个集合类(InvoiceLines)
Private m_InvoiceLines as New Collection
Sub Add( newItem As CinvoiceLine,Optional Key As Variant,Optional Before As Variant,Optional After As Variant,) m_InvoiceLines.Add newItem,Key End Sub Sub Remove( index As Variant,) m_InvoiceLines.Remove index End Sub Function Item(index As Variant) As CInvoiceLine Set Item = m_InvoiceLines.Item(index) End Function Property Get Count( ) As Long Count = m_InvoiceLines.Count End Property 还要做两件事,才能让集合类完美模仿标准的Collection:1)支持缺省项,2)支持枚举项 1)使Item成为缺省成员 当处理Collection对象时,代码中常常省略Item成员的名字。为了在集合类中也支持此特性,只需要让Item成为类的缺省成员,可以从Tools主菜单中选择Procedure Attribute,在对话框顶部的组合框中选择Item,扩展对话框(即Procedure Attribute对话框下端显示增加选项),并在ProcID字段中键入或在下拉式列表中选择0(缺省) 在§ 6-2-5 属性 一节中 2、类的缺省成员 大多数VB控件及内部对象都有一个缺省属性或者方法。例如Collection有一个缺省的Item方法。如果在表达式中省略了成员名,VB这是指特定的对象,所以这种数据项认为是缺省成员。按照下列方法,甚至可以对自己的类实现同样的机制: a、在代码窗口中的属性或者方法定义处单击鼠标,从“工具Tools”中调用过程“属性Attribute”,然后如果数据项的名字还没有显示,就在组合框的最顶端选择数据项的名字。 b、另一方面,按下F2打开Object Browser,在最左端的窗格中选择类模块的名字:在最右端的窗格中,在要成为缺省成员的数据项上单击鼠标,然后从出现的弹出菜单中选择Property,如图6-6 c、一旦所感兴趣的数据项以高亮方式显示在最顶端的Name组合框中,单击“高级Advanced”按钮,扩展Procedure Attribute对话框,如图6-7 d、在Procedure ID组合框中选择“缺省default”项;另一方面还可以在组合框的编辑区内输入0 e、单击OK按钮,确定生效并关闭对话框。在Object Browser中,在该成员名旁边已经出现一个小圆指示符。这证明它已经成为类的缺省成员。 一个类只能有一个缺省方法或者属性。如果出现第二个缺省项,报错! 2)为枚举项增加支持 首先添加下面的过程到类模块中 Function NewEnum( ) As IUnknown SetNewEnum = m_InvoiceLines.[_NewEnum] End Function 然后激活Procedure Attribute对话框,选择NewEnum成员,为它分配ProcID等于-4,选择复选框Hide This Member,关闭对话框 OLE协议规定类必须通过一个ProcID等于-4的函数提供此枚举器对象
关于《过程属性对话框》 Setting the Procedure Attributes https://msdn.microsoft.com/en-us/library/aa260636(v=vs.60).aspx
??
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |