标准、窗体、类这三个模块的实现方式或者原理是啥?

神马都能聊 2011-02-11 11:53:09
大侠们新年好,我的问题是这样的,标准、窗体、类这三个模块的实现方式或者原理是啥?貌似讨论这些还离不开VB6的IDE,我郁闷,编译前和编译后貌似还有区别。。。TNND。

细说一些问题的话,就比如说:

1.为啥窗体就有个全局实例,这家伙为啥能用AddressOf;
2.为啥标准模块的公共变量、公共函数就可全局访问,这家伙咋也能用AddressOf;
3.为啥类模块就不让用AddressOf,是因为COM的那些接口?搞不懂COM,有没有讲述这些东西的书?

好久没问技术问题了,如果可以的话,请您回复的清晰点儿,毕竟那也是您的劳动成果,我的理解能力不太好!


最初写简历就写精通,这几年写熟悉,现在越来越觉得不熟悉了,更别谈精通了。该死的黑盒子啊,该死的微软帝国啊。


只要答案给力,分不是问题,即使倾家荡产我也要问。
...全文
403 76 打赏 收藏 转发到动态 举报
写回复
用AI写文章
76 条回复
切换为时间正序
请发表友善的回复…
发表回复
lyserver 2011-08-15
  • 打赏
  • 举报
回复
1、窗体是一种特殊的类模块,它们均有一个类指针,即VB中的Me关键字(外部调用时则为该实例的变量名称),该指针指向窗体实例和类实例,窗体和类模块中的所有函数和方法都必须通过类指针来访问。而标准模块没有类指针,因此不需要类指针来访问。
2、与类模块不同的是,窗体的实例化由VB隐式进行,VB会在由窗体启动时或使用Load、Show方法时,自动判断窗体是否已被实例化,如果没有则进行隐性的实例化当然我们也可以显式实例化,甚至还可以实例化多个实例,比如:
"vb"
Sub main()
Dim frm1 As Form1, frm2 As Form1

Set frm1 = New Form1
frm1.Move 0, 0
Set frm2 = New Form1
frm2.Move 500, 500

frm1.Show
frm2.Show
End Sub

3、实例是运行时生成的,因此类指针指向的函数和方法的内存地址也是运行时动态生成的,标准模块没有实例,因此它的方法和函数的内存地址是在编译时就确定了的。由于AddressOf运算符只能指向一个编译时确定的内存地址,因此它只能适用于标准模块,而不能直接适用于窗体和类模块。
4、所谓的类,如同PctGL所说,实质上就是一个结构体,只不过ActiveX中,窗体类不能直接通过ODL(IDL在VB中的本地化)暴露给调用者,而类模块可以。
暂时能想到的就这么多,不知道说得是否清楚。
msdtx 2011-08-15
  • 打赏
  • 举报
回复
其实你看过VB 的反汇编代码就知道了,模块中的函数才是直接的函数。窗体或类中的函数都有一个默认的me 参数,访问他们的前提是取得类或窗体的对象实例,通过对象实例来访问其方法。所以AddressOf 只允许对模块中的函数获取地址。
worldy 2011-08-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 aisac 的回复:]
大侠们新年好,我的问题是这样的,标准、窗体、类这三个模块的实现方式或者原理是啥?貌似讨论这些还离不开VB6的IDE,我郁闷,编译前和编译后貌似还有区别。。。TNND。

细说一些问题的话,就比如说:

1.为啥窗体就有个全局实例,这家伙为啥能用AddressOf;
2.为啥标准模块的公共变量、公共函数就可全局访问,这家伙咋也能用AddressOf;
3.为啥类模块就不让用Address……
[/Quote]

使用类,可以将数据,以及数据的处理组成一个整体,避免无关的处理影响到数据,但是,类只是定义一组数据组成和对该组处理方式,并没有内存实体,只有使用了 set a=new aClass的时候,才创建类的实例(也称为对象),数据才能真正存在!

窗口,事实上是一种特殊的类,该类用于处理窗口及窗口显示用户交互方面的操作,VB为方便用户,在内部定义了一个和窗口类名相同的的窗口对象,事实上,该窗口对象并不一定要使用,比如,你设计了一个窗口Form1,你可以直接使用Form1来操作,也可以使用dim f as new Form1,然后用f来操作,这在创建同一个窗口的多个实例的时候,经常会使用。

类模块(包括窗口模块)中,定义的public的数据、过程、属性和方法(称之为类成员),是和特定的对象相关的,所以,访问类中的Public的成员时,必须明确的指明是哪个对象在调用,对应Bas模块的Public的成员,因为是属于整个程序所有,所以,不需要指明。但是,如果有两个Bas模块定义了相同的名称,那么就需要使用模块名称对该名称进行限定,比如,A模块有函数 AFun,B模块也有一个命名为AFun的函数,则调用的时候就需要使用A.Afun\B.Afun进行限定。

使用类另一个好处是,一个类创建的多个对象之间不会互相干涉,比如你希望创建一个多文本编辑器,如果不使用类技术,而是使用直接内存定义,就要考虑变量之间的互相影响,那么编程将会变成非常的复杂麻烦。

addressof函数用于提取一个函数或过程的地址(函数指针),事实上,它可以在任意的场合(Bas模块,类模块,窗口模块)下使用,只是addressof的参数,只能是定义在Bas模块中的过程或函数。

Com是一种软件技术,它最大的意义是能够在二进制的层次代码重用。所谓二进制层次的代码重用,就是,一个Com部件编译成二进制之后,开发者可以直接使用该部件,不需要对该部件重新进行编译;同时,使用该部件的用户程序,在Com部件升级或者排除Bug时,也不需要重新修改和编译,(相对而C++,C++的代码重用是代码层次的重用,即不论修改了类的定义、实现方法,还是修改了使用类得程序,都必须重新编译)
gooore 2011-07-21
  • 打赏
  • 举报
回复
学习了。。

不过还是不知道空白回复怎么弄的
worldy 2011-06-11
  • 打赏
  • 举报
回复
我想,是否可以这样理解:

frm模块,一个独立组件,为用户提供的可视的窗口界面,它包含了所有控制窗口的和用户交互的代码
ctl模块,一个独立的组件,提供给窗口,并且可以和用户交互的单元
cls模块,一个独立的组件,提供一种合适的数据管理单元
bas模块,提供全局支持的相关功能

至于创建缺省窗口,只是编译器的约定,为什么要这么约定,VB开发者为了你方便吧,其实其后台会自动创建创建窗口的代码
杀神者 2011-04-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dbcontrols 的回复:]
只要出分给力,顶不是问题,即使整宿不睡我也要顶。
[/Quote]
++++
warmice5255 2011-04-21
  • 打赏
  • 举报
回复
<br />
Kill_Sky 2011-02-18
  • 打赏
  • 举报
回复

</br></br>
神马都能聊 2011-02-18
  • 打赏
  • 举报
回复
我顶啊
神马都能聊 2011-02-16
  • 打赏
  • 举报
回复
[Quote=引用 57 楼 tiger_zhao 的回复:]
其实 VB 一直是微软主推的 OLE/ActiveX/COM 技术的主力,但是大量的 standard dll 又是客观存在的,为了能调用它们,VB 又特地加了好多特性,比如这个 AddressOf,目的并不是给 VB 自己用的,而是为了 API 调用。

至于不能对类成员用 AddressOf,按照 COM 标准,应该通过 VTable 取函数指针。
[/Quote]
AddressOf是给API用的啊,之前没想过这个问题,现在想想,好像确实是这样,子类化都是用API实现的。

不能对类成员用AddressOf的原因果然是与COM有关,我刚刚买了本COM的书,《COM原理与应用》,没敢买《COM本质论》,怕看不懂。

[Quote=引用 61 楼 ybh37 的回复:]
引用楼主 aisac 的回复:
最初写简历就写精通,这几年写熟悉,现在越来越觉得不熟悉了,更别谈精通了。该死的黑盒子啊,该死的微软帝国……

怎么?换槽子还是跳槽子
[/Quote]
不换不跳,只是想深入了解一下VB6。
神马都能聊 2011-02-16
  • 打赏
  • 举报
回复
[Quote=引用 56 楼 tiger_zhao 的回复:]
如果你是从最早的过程式语言一路过来的,就会知道最早的OO(面向对象)语言是没有类和实例的概念的,一个对象(Form)就是一个个体,象变量一样能直接被使用。
现在应该还能找到 DOS 版的 FoxPro,就是这种模式。

再向高级语言发展,对象需要创建实例才能使用了,那么为了兼容,VB 就给类 Form1 隐式定义了一个同名的 As New 变量。
所以这是历史原因造成的。
[/Quote]
哦,原来窗体全局实例是历史原因造成的。
咸清 2011-02-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 aisac 的回复:]
最初写简历就写精通,这几年写熟悉,现在越来越觉得不熟悉了,更别谈精通了。该死的黑盒子啊,该死的微软帝国……
[/Quote]
怎么?换槽子还是跳槽子
flfq 2011-02-15
  • 打赏
  • 举报
回复
<br></br>
flfq 2011-02-15
  • 打赏
  • 举报
回复
<br></br>
咸清 2011-02-15
  • 打赏
  • 举报
回复
Tiger_Zhao 2011-02-15
  • 打赏
  • 举报
回复
其实 VB 一直是微软主推的 OLE/ActiveX/COM 技术的主力,但是大量的 standard dll 又是客观存在的,为了能调用它们,VB 又特地加了好多特性,比如这个 AddressOf,目的并不是给 VB 自己用的,而是为了 API 调用。

至于不能对类成员用 AddressOf,按照 COM 标准,应该通过 VTable 取函数指针。
Tiger_Zhao 2011-02-15
  • 打赏
  • 举报
回复
如果你是从最早的过程式语言一路过来的,就会知道最早的OO(面向对象)语言是没有类和实例的概念的,一个对象(Form)就是一个个体,象变量一样能直接被使用。
现在应该还能找到 DOS 版的 FoxPro,就是这种模式。

再向高级语言发展,对象需要创建实例才能使用了,那么为了兼容,VB 就给类 Form1 隐式定义了一个同名的 As New 变量。
所以这是历史原因造成的。
贝隆 2011-02-15
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 jhone99 的回复:]
1.为啥窗体就有个全局实例,这家伙为啥能用AddressOf;
2.为啥标准模块的公共变量、公共函数就可全局访问,这家伙咋也能用AddressOf;
3.为啥类模块就不让用AddressOf,是因为COM的那些接口?搞不懂COM,有没有讲述这些东西的书?
*********************

没有具体研究过,在这里猜测一下。

窗体是具体对象,公共变量是具体变量,这些有地址
……
[/Quote]
高见,学习!
king06 2011-02-15
  • 打赏
  • 举报
回复
我发现我这号被设置了,我发空白就不行, 打个up顶下自己的贴还被删, 没天理
现在还是人类 2011-02-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 aisac 的回复:]
1.为啥窗体就有个全局实例,这家伙为啥能用AddressOf;
2.为啥标准模块的公共变量、公共函数就可全局访问,这家伙咋也能用AddressOf;
3.为啥类模块就不让用AddressOf,是因为COM的那些接口?搞不懂COM,有没有讲述这些东西的书?
[/Quote]
其实很简单呀,就是个函数入口的问题。
在VB中的公共模块中的函数,就有点像VC里的静态函数。而类里的函数,他不会把接口像静态函数一样把入口放出来,这样就不能找到他的函数入口,所以类里的函数就不能像模块中的函数那样通过AddressOf得到他的函数指针地址。这不是VB才有的现象,VC同样也有这种问题,只是VC可以在类定义函数时加一个static来解决这种问题,不过这时这个函数的性质也被改变了。
至于为什么要用AddressOf,是因为VB没有指针的概念,要得到一个函数的地址指针,当然需要一个东西转换一下,所以他就提供了AddressOf来把函数转换成函数指针地址,以这种方式来弥补他没有函数指针概念的缺陷。
加载更多回复(51)

863

社区成员

发帖
与我相关
我的任务
社区描述
VB COM/DCOM/COM+
c++ 技术论坛(原bbs)
社区管理员
  • COM/DCOM/COM+社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧