类模块中不能用自定义结构么?

slowgrace 2009-05-11 05:56:02
加精
类模块中不能用自定义结构么?

我在标准模块中声明了如下结构:
'用于类间消息传递,指明涉及变动的细节ID
Public Type DETAIL
lngDetailId As Long
strDetailTable As String
End Type



然后在类模块中这样用:
Public Event ValueChangedD(udtDetail As DETAIL, sngIncreased As Single, udtCT As ChangeType)  '由CDetailList发出

'由CDetailList发出
Public Sub SendMessage_ValueChangedD(udtDetail As DETAIL, sngIncreased As Single, udtCT As ChangeType)
RaiseEvent ValueChangedD(udtDetail, sngIncreased, udtCT)
End Sub


编译后出错,提示:只有在公共对象模块中定义的用户定义类型才可以与变体类型强制转换 或传递给后期绑定 late-bound 的函数。
出错在下面这句:
RaiseEvent ValueChangedD(udtDetail, sngIncreased, udtCT)

“udtDetail”这个词高亮显示。这个raiseevent是后期绑定的函数么?如果是,像现在这种情况,我有什么办法传结构出去?
...全文
4848 65 打赏 收藏 转发到动态 举报
写回复
用AI写文章
65 条回复
切换为时间正序
请发表友善的回复…
发表回复
FN2023 2012-07-24
  • 打赏
  • 举报
回复

学习一把
Tiger_Zhao 2009-08-20
  • 打赏
  • 举报
回复
没错
slowgrace 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 tiger_zhao 的回复:]
To slowgrace:
解决方法就是在工程外(tlb、dll)定义结构:
1)可以用 VC 的 idl 编译成 tlb。
2)也可以用《高级 Visual Basic 编程》附带的 EditTlb.exe 直接做成 tlb。
3)纯 VB 的方式就是在一个 ActiveX Dll 工程中定义结构。
[/Quote]

也就是我得在我的工程里引用这个定义了UDT的部件(.tlb 或 .dll),是吧?
slowgrace 2009-08-19
  • 打赏
  • 举报
回复
哎。许多事不能深想啊。
slowgrace 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 tiger_zhao 的回复:]
私有类的属性、方法始终在工程内调用,所以可以用私有 UDT。
而 RaiseEvent 走标准流程,无法保证事件接收者肯定是工程内对象,所以不能用私有 UDT。
[/Quote]

这个解释当时似乎懂了,现在再来看感觉还是懵懂。
zzyong00 2009-05-30
  • 打赏
  • 举报
回复
[Quote=引用 54 楼 slowgrace 的回复:]
引用 50 楼 zzyong00 的回复:
VB code想用事件(event)传自定义类型,恐怕很难了,学学微软,常常在定义API时,传入(出)一个指针,还有一个长度,几乎可以代替一切,当然得用copymemory了
'class1

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Public Event ValueChangedD(ByVal udtDetail As Long, ByVal nCount A…
[/Quote]
我不喜欢public
slowgrace 2009-05-30
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 m60a1 的回复:]
首先声明一下:VB6写出来的COM不是真正的COM,原因在这里不讨论.

那么来看看VB6对于COM是怎么支持的,想在VB6里面创建"COM"那么必须新建一个类模块,然后把属性,方法,事件通通写在
这个类模块中,想要对外暴露的接口,在VB6里面被申请为PUBLIC类型,Private,Friend都被视为保护类型对外不暴露

现在LZ的意思是,想在标准模块中,定义一个PUBLIC类型的结构体,然后在外部进程中对其进行使用,那么,回答是肯定的,
所有在标准模块中定义的PUBLIC类型,都被视为只能在进程内使用,不能被使用在外部进程中,这就是为什么同样是模块,
同样是定义了PUBLIC类型,一个可以在外部被使用,一个只能被进程内的类模块使用!

至于说到C/C++,,那是个标准COM,那么在定义时,如果是公共类型那么不管是进程内还是时程外,只要将其内存地址复制出来
(也就是常说的用指针指到那个内存地址的开头位置),那么你就能用,但是在C/C++里面还有二种类型是不能被外部进程使用
的,一个是私有类型,还有一个好像叫友员吧(我记不大清楚了名字:) 报歉),其中私有类型和VB6一样只能在相同的子进程中
使用,而友员那就有点和VB6中在标准模块中PUBLIC一样,可以在进程内使用.

呵呵,,乱说的,说的不好指出一下下![/Quote]

谢谢指教。你说的很好,VC俺不懂,你说的VB部分的内容和我最近学习到的知识相符。不过的话,我感觉你并没有看到俺的症结所在啊,呵呵。

其实我的问题的根源不在自定义结构在哪里定义,而是在哪里使用。我的所有自定义结构都是在标准模块里以public声明的,所以,其实它们都是不能被外部使用的,但是可被进程内的类模块使用,所以我以前在类模块里用自定义结构都没问题。但是这回我在进程内使用了raiseevent函数,由于这个函数的接受对象可能来自外部进程,所以它不能使用私有的自定义结构,所以这里编译不能通过。具体可见Tiger_Zhao在19楼和22楼的解释。
slowgrace 2009-05-28
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 zzyong00 的回复:]
VB code想用事件(event)传自定义类型,恐怕很难了,学学微软,常常在定义API时,传入(出)一个指针,还有一个长度,几乎可以代替一切,当然得用copymemory了
'class1

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Public Event ValueChangedD(ByVal udtDetail As Long, ByVal nCount As Long, ByVal sngIncreased As Sin…
[/Quote]

先问句溜边儿滴:你干嘛声明两次copymemory啊?在标准模块里声明一个public的CopyMemory不好么?
slowgrace 2009-05-28
  • 打赏
  • 举报
回复
[Quote=引用 57 楼 myjian 的回复:]
我给你那个工具只是一个语法转换器,实际还是调用的这个MKTYPLIB.EXE来生成的.

因为ODL语言掌握的人不多.........
[/Quote]

谢谢。
嗷嗷叫的老马 2009-05-28
  • 打赏
  • 举报
回复
我给你那个工具只是一个语法转换器,实际还是调用的这个MKTYPLIB.EXE来生成的.

因为ODL语言掌握的人不多.........
slowgrace 2009-05-28
  • 打赏
  • 举报
回复
正好想请教myjian问题呢。

刚才看到MSDN里提到MkTypLib这个工具,是用来做type library的。你用过么?貌似这个和你及TZ推荐的那个功能相似?不过的话,这个MkTypLib是正儿八经VB程序员指南里推荐的。
嗷嗷叫的老马 2009-05-28
  • 打赏
  • 举报
回复
路过..............
zhizhiming 2009-05-18
  • 打赏
  • 举报
回复
模块里的似乎类型不能导出,,,写在公共类里试试,,我没试过
嗷嗷叫的老马 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 slowgrace 的回复:]
TO MYJIAN:我在VBA里试的。不知是不是这个差别导致的结果不同?在类模块中用标准模块里定义的结构,这种用法,我用了很久了。直到昨天用了raiseevent才出错。

另外,弱弱的问一哈,那个VB6ApiTypeLibMaker.exe怎么用啊?我把下面的结构声明拷到API声明里:


VB code'用于类间消息传递,指明涉及变动的细节ID
Public Type DETAIL
lngDetailId As Long
strDetailTable As String
End Type




然后点“转…
[/Quote]
VB6ApiTypeLibMaker貌似只能转API声明.

要做类型库,推荐使用EditTLB.EXE:

一,新建个ActiveX DLL工程,在那里面声明你要的自定义结构.

为了方便,添加个模块,再声明在里面吧.

二,编译出DLL,然后用EditTLB.exe打开,把类删除,只留你要的那个结构,再另存为TLB文件;

三,打开这个TLB文件,改一下CLSID(不能与DLL冲突了,或者你反注册那DLL也行),可以使用了......
神马都能聊 2009-05-13
  • 打赏
  • 举报
回复
友元是个特例,似乎VB没有与之匹配的东西,要说有大概只能说是friend了,区别较大.
m60a1 2009-05-13
  • 打赏
  • 举报
回复
首先声明一下:VB6写出来的COM不是真正的COM,原因在这里不讨论.

那么来看看VB6对于COM是怎么支持的,想在VB6里面创建"COM"那么必须新建一个类模块,然后把属性,方法,事件通通写在
这个类模块中,想要对外暴露的接口,在VB6里面被申请为PUBLIC类型,Private,Friend都被视为保护类型对外不暴露

现在LZ的意思是,想在标准模块中,定义一个PUBLIC类型的结构体,然后在外部进程中对其进行使用,那么,回答是肯定的,
所有在标准模块中定义的PUBLIC类型,都被视为只能在进程内使用,不能被使用在外部进程中,这就是为什么同样是模块,
同样是定义了PUBLIC类型,一个可以在外部被使用,一个只能被进程内的类模块使用!

至于说到C/C++,,那是个标准COM,那么在定义时,如果是公共类型那么不管是进程内还是时程外,只要将其内存地址复制出来
(也就是常说的用指针指到那个内存地址的开头位置),那么你就能用,但是在C/C++里面还有二种类型是不能被外部进程使用
的,一个是私有类型,还有一个好像叫友员吧(我记不大清楚了名字:) 报歉),其中私有类型和VB6一样只能在相同的子进程中
使用,而友员那就有点和VB6中在标准模块中PUBLIC一样,可以在进程内使用.

呵呵,,乱说的,说的不好指出一下下!
东方之珠 2009-05-13
  • 打赏
  • 举报
回复
讨论这么激烈,参观一下!
kjduanhaowei 2009-05-13
  • 打赏
  • 举报
回复
语法感觉有点怪怪的……
mofamans 2009-05-13
  • 打赏
  • 举报
回复
学习!
Tiger_Zhao 2009-05-13
  • 打赏
  • 举报
回复
To slowgrace:
解决方法就是在工程外(tlb、dll)定义结构:
1)可以用 VC 的 idl 编译成 tlb。
2)也可以用《高级 Visual Basic 编程》附带的 EditTlb.exe 直接做成 tlb。
3)纯 VB 的方式就是在一个 ActiveX Dll 工程中定义结构。
加载更多回复(44)
1 安装方法: 此系统为测试版本,只是一个大体的框架,直接解压缩到c: ewsoft目录下即可,注意只能为此目录,且不能改变其目录结构,在正式版将提供自动目录搜寻功能。 “newsoft”目录下为源文件。 “my”子目录为系统的exe文件,双击即可运行。 “lib”子目录为系统存放文件目录。 2 功能介绍: 对办公用品的购买,领取进行管理。 本系统可以设置用户权限,根据权限可以实现不同级别的操作; 系统初始密码为:超级用户:用户名、口令都为vip 一般用户:用户名、口令都为user 别添加:添加所购物品分,如钢笔、笔记本等; 部门添加:添加公司部门,还没有加上,有兴趣的朋友可以自己加上,方法与别添加一样,表名为bm; 物品入库:采购来的物品应及时入库,若两次采购相同的物品,系统会自动计算其平均价格,并更新购买日期。注:此版本现只能计算平均成本和更新最后采购日期,但当有多个采购员是不能看出到底是谁进的货,有兴趣的朋友可以修改。 领用登记:领用办公用品后,应及时入库登记,系统会自动分摊费用,可以按月、季、年结帐分摊费用。注:设想改为到一定时期(如一个月),自动备份数据,打印报表,交财务分摊费用。 报表打印:可以按年、季、月或自定义一段时期打印报表。 更多功能正在完善,可以来信与我交流。 3 系统说明 由于时间仓促,系统的详细说明教程还没有写,需要的朋友可以来信索取,等完成后我会发到您的信箱。 4 意见反馈 由于近期要为公司开发一套办公管理软件(网络版),这是其一个模块,希望您试用以后能给我一点意见。

742

社区成员

发帖
与我相关
我的任务
社区描述
VB 版八卦、闲侃,联络感情地盘,禁广告帖、作业帖
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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