如何枚举引用的 ActiveX DLL 对象并一次清空?

东方之珠 2008-04-02 09:57:02
我们知道,可用下列代码,一次性卸载所有窗体并退出,窗体再多也无一漏网!简直是高效!

Dim Frm As Form
For Each Frm In Forms
Unload Frm
Next
End


但是,在卸载窗体前,在标准模块里面定义了很多引用的 ActiveX DLL 对象,总要清空吧!至少有20个,每一个名字都不一样,也没规律,如果每一个都用set A=nothing,那也太繁琐了。有没有像上面卸载窗体一样那样高效的清空代码?捉摸了半天没找到方法!


...全文
134 点赞 收藏 24
写回复
24 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
东方之珠 2008-04-06
唉!看来是没人帮忙了,当成散分吧。谢谢各位同仁参与
回复
fj182 2008-04-04
实在搞不懂楼主为什么要这么做,难道你写代码是为了给别人看的?
我认为如果如果对象没有使用某些系统资源,如IO,GDI等等,即使你不去释放它,离开它的作用域就会自动释放,写不写 set nothing 效果是一样的。而某些对象(如 Form,DB Connection)等,既使 Set Nothing也不一定释放资源,如要释放Form,要用 Unload,释放 DB Connection,要用 Close....
既然不能保证 Set Nothing就一定能释放资源,那非要对每一个对象的引用都去 Set Nothing就成了形式主义了。
通常情况下,我会对需要特殊处理的对象再包装一次,以保证能正常释放。如把 DB Connection 放到类里,在类的 Terminate 事件里强制释放.而用这个类实例化的对象就不用去显式释放了。
回复
qiu5208 2008-04-04
摸看明白要干什么,帮顶
回复
东方之珠 2008-04-04
[Quote=引用 20 楼 forbearORfolie 的回复:]
不过回头想想,你有时间一个一个的ADD到集合中,还不如一个一个的set nothing呢
[/Quote]

你很有经济头脑,会精打细算!
回复
东方之珠 2008-04-04
To chm666:
刘老师,您有什么高招吗?不要卖关子了,有什么好招,就让大家见识一下,如果分不够再加100!
回复
forbearORfolie 2008-04-04
不过回头想想,你有时间一个一个的ADD到集合中,还不如一个一个的set nothing呢
回复
forbearORfolie 2008-04-04
我就是看20个Set A=Nothing不顺眼!
哈哈~~~
回复
东方之珠 2008-04-04
我的目的很明确:写一个卸载所有窗体,释放所有对象,然后退出程序的模块Quit。

Form1窗体模块:
Option Explicit
Private Sub Form_Load()
'对象实例化
Set a1 = New Cls1
Set b2 = New Cls2
Set c3 = New Cls3
Set d4 = New Cls4
Set e5 = New Cls5
Set f6 = New Cls6
Set g7 = New Cls7
Set h8 = New Cls8
Set i9 = New Cls9
Set j10 = New Cls10

'加入集合
ActiveXDll_Objs.Add a1
ActiveXDll_Objs.Add b2
ActiveXDll_Objs.Add c3
ActiveXDll_Objs.Add d4
ActiveXDll_Objs.Add e5
ActiveXDll_Objs.Add f6
ActiveXDll_Objs.Add g7
ActiveXDll_Objs.Add h8
ActiveXDll_Objs.Add i9
ActiveXDll_Objs.Add j10
End Sub


标准模块Module1:
Option Explicit

'定义ActiveX Dll对象,都是来自不同的ActiveX Dll
Public a1 As Cls1
Public b2 As Cls2
Public c3 As Cls3
Public d4 As Cls4
Public e5 As Cls5
Public f6 As Cls6
Public g7 As Cls7
Public h8 As Cls8
Public i9 As Cls9
Public j10 As Cls10

'定义ActiveX Dll对象集合并实例化
Public ActiveXDll_Objs As New Collection


'卸载所有窗体,释放所有对象,然后退出
Public Sub Quit()

'释放所有对象
Dim Obj As Object
For Each Obj In ActiveXDll_Objs
Set Obj = Nothing
Next

Set ActiveXDll_Objs = Nothing

'卸载所有窗体
Dim Frm As Form
For Each Frm In Forms
Unload Frm
Next

'终止程序
End

End Sub



=============================================================
上面的写法不失为一个方法,但不是很理想!
我用真正的12个ActiveX Dll类对象作了测试,结果EXE文件多了4k。
后来,仔细一想,集合占的空间比较大,把每个对象加入集合是要付出代价的,还不如写20个:Set A=Nothing,我就是看20个Set A=Nothing不顺眼!







回复
东方之珠 2008-04-03
不行! 设置Set Form1=Nothing,标准模块里面的ActiveX DLL 对象不能被释放!
回复
cbm6666 2008-04-03
在Unload时 Set Form1 = Nothing 所引用的对像应该会自动释放的吧?
回复
东方之珠 2008-04-03
自己顶一下.
回复
东方之珠 2008-04-03
阿勇的想法启发了我,谢谢你!下午,我一直在想这个问题:VB中有Forms、Controls和Printers等集合,而标准模块、类模块不是集合,不能用For Each枚举其中的对象,但可以定义一个Modul1对象,这又有什么用呢?我也不知道,但解决我的问题没有用。因此,要用For Each枚举的话,就得从集合做起,从定义对象做起。
名称各不相同的ActiveX DLL对象(要做到见名知义,就得各不相同)来自各不相同的ActiveX DLL。为什么要定义在标准模块里面呢?因为很多窗体要用到。如果定义在一个主窗体里面,这样其他窗体引用起来很麻烦,好处是窗体一卸载全都没了。
我试一下,看看效果如何!再次感谢你!
回复
东方之珠 2008-04-03
[Quote=引用 11 楼 cbm666 的回复:]
我是能枚举这个exe所有引用到的 DLL与OCX, 再来你要干啥 ?
[/Quote]

当然欢迎刘老师啦!你那张图我电脑没显示出来,也不知道是啥好东东?
回复
zzyong00 2008-04-03
Dim col As New Collection
Public Function aa()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
col.Add fso

End Function
Public Function ab()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
col.Add fso

End Function

Public Function ac()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
col.Add fso

End Function
Public Function release()
Dim fso As Object
For Each fso In col
Set fso = Nothing
Next

End Function

Sub main()
aa
ab
ac
Debug.Print col.Count
release
End Sub
回复
zzyong00 2008-04-03
To chenjl1031 :
我也没想到什么好方法,
不过在定义ActiveX DLL 对象时,先定义一个集合对象collection
将每一个定义的ActiveX DLL 对象都保存在集合对象中,释放时,遍历哪个集合,给每个对象赋为nothing,
不知如何?
回复
forbearORfolie 2008-04-03
实例化的无界面引用,一般来说类似于数据库连接,养成个习惯,当某个object不用的时候就nothing,用的时候再new,在模块里写个通用的清理过程,主窗体退出的时候调用。
回复
cbm6666 2008-04-03
我是能枚举这个exe所有引用到的 DLL与OCX, 再来你要干啥 ?

回复
东方之珠 2008-04-03
to zzyong00(阿勇):
有没有枚举标准模块里面定义的ActiveX DLL 对象的办法?这些对象名称没有规律,并且很多,而且还来自多个ActiveX DLL ,一个一个释放效率太低。如果定义在窗体内,或者说定义成数组,那就不用说了。用Set Form1=Nothing不行,我试过了,这个只对窗体内的有效。你有没有办法?
回复
zzyong00 2008-04-03
哦,刚才又看了下楼主的意思,上面算我没说!
回复
zzyong00 2008-04-03
[Quote=引用 6 楼 chenjl1031 的回复:]
不行! 设置Set Form1=Nothing,标准模块里面的ActiveX DLL 对象不能被释放!
[/Quote]
哪在标准模块时在的A DLL对象有没有用?如果没有用,就 set activexdll对象=nothing
如果有用!哪为什么要在窗口释放时释放呢?
回复
加载更多回复
相关推荐
发帖
VB基础类
创建于2007-09-28

7491

社区成员

VB 基础类
申请成为版主
帖子事件
创建了帖子
2008-04-02 09:57
社区公告
暂无公告