向所有API高人求教:为什么我能够捕捉到VB6"本地"窗体的句柄,但是却取不到其中那个树状控件的句柄?原因何在?

nmd002 2008-05-16 03:36:36
如题。本人已用VB6+API制作了一段有效的代码,可以捕捉到VB6的“本地”窗体的句柄,经验证已取得句柄正确。
但是本人却无法将“本地”窗体中的那个树状控件的句柄捕捉到。试验证明SPY++也查不到这个控件的句柄。

本人至今未能查到这个控件是什么类名(classname),属于哪个类型,也不知道如何才能取得其中的各个键值对。好像在VB6中也没有一种对应的控件是这个类型的。

本人写这段程序的目的是,为了捕捉其他外部VB程序中调试时的“本地”窗体中的数据(变量名,值,类型),并希望能用层级结构制作数据的清单。

如果有高人能够做到:
1:能用VB+API,取得其他程序VB6的“本地”窗体中已展开树的所有键值对,就算没有层级关系也行。
2:告知此树状控件是什么类型或类名,其运作的原理是什么。
3:通过该窗体句柄从进程中取得其内存数据,并转化为可用的VB对象。

只要三个问题中可以回答出任何一个,并且经本人试用确实有效,就可得分。
如嫌少,可另外再给。
请各位高人指教,洗耳恭听。
...全文
296 点赞 收藏 37
写回复
37 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
sonic_andy 2008-12-16
调试的时候addin都灰掉了,我发现用钩子的时候,好像有一些权限..比如可以通过键盘钩子调出对话框.

你可以通过另一种思路啊,比如在立即窗口里createobject
通过typelib information(tlbinf32.dll)动态分析对象的属性,属性值,动态调用成员函数...
回复
nmd002 2008-05-20
感谢大家的热烈响应。
现将本人的目标再重新声明一下:
本人想通过一段程序,实现指定VB开发环境下,某个运行中的VB程序的各项数据(包括变量、对象及其值)。而且现在主要是想把“本地窗口”内的那个树状结构中所显示出的数据,做为输出的主要来源。也就是说,执行某VB程序之后,在运行中中断,通过本地窗口所监控到的数据(名称、值、类型),都想当作内容做一个输出(甚至是按层级的定位或查询,当然那是在树状结构可控的前提下才行),以供使用者方便地查找和监控变量的值。

本人首先使用的方法是捕获该窗口句柄的方法,结果是可以捕获该窗体,可以捕获窗体中除树状控件以外的其他控件的句柄和值。老鸟的解释是:有些控件是直接进行绘制的,因此此类控件是没有句柄可供捕获的。所以本人基本放弃了这种获得数据的思路。

接下来,根据老鸟和诸位高人的提议,本人研究了ADDIN的使用。本指望通过微软封装的类,取得本地窗体,并将其内所含控件取得后,再加利用。谁知微软不地道,他们没有留下操作窗体内任何控件的途径和方法。

所以本人当时考虑,如果还是不能取得控件中的各名称和值的话,只好自己写一个类似本地窗体的ADDIN。用本地窗口的表现形式做一个仿品,功能仿照本地窗口中的树状结构来显示各对象,点击节点,伸缩树枝。然后在其上扩展自己的输出功能,把已经展开的节点中的全部属性名和值都做为输出的内容。

但是最后的这种想法,会涉及到几个问题,尚待解决:
1:ADDIN方式建立的窗口,在运行中断的情况下,是否能取得运行中某个控件的各属性及其值。看过前面(lsftest)给出的那篇文章,多少对取得某控件的全部属性有了信心。但是对在运行中断时的控件对象的取得,因为没有测试过,仍不敢确定。
2:ADDIN窗口在运行中断的情况下,是否能正常显示,还没有经过测试。如果ADDIN无法在中断情况下显示,那最后的这个想法也只能放弃了。
3:还有一个功能控件的问题。本地窗口的树状控件,看来很简单,但是却包含了许多一般控件没有的功能。比如随时可以在其中添加新的对象或变量,并对其从属的属性进行同样的树状伸缩。也就是说这个控件不是一般的树,只有一个根,他可以有多个根,每个单独的根都可以伸缩,也是个极其难以模仿的控件。

另外,“(yinweihong)请结贴,谢谢!”在回复中提到的“直接扫描VB6的栈...再去分析,难度更大”,我也很感兴趣。能否介绍一下思路或者方法,使本人可以在此基础上,拓展一下思路。也许这个问题看着难,解决起来其实很容易。关键是本人的技术水平仍然很有限,思维还不够活跃,才无法脱离已知的条条框框的束缚。

希望各位有识之士,能够提出更有创意的思路和方法来。本人感激涕零,热烈盼望各位不吝赐教。
回复
nmd002 2008-05-20
已经测试过了,默认的ADDIN开发出来之后,其窗体只能显示在编码状态下。在运行中断(调试)状态下,整个外接程序根本就是被关闭的。连外接程序的主菜单都禁用了,更不用说其下的其他窗体了。
现在我认为ADDIN在VB6里的主要作用,只能是作为编码的辅助用窗口,连参与调试的可能性都没有。不能满足我的开发需求。但愿我的判断是错误的,可以有哪位高人出来指正一下。

请问现在还有哪位高人,有办法能帮我获得VB本地窗体中的数据吗?

求大家帮忙顶帖。我还是不死心!
回复
nmd002 2008-05-20
不知道有没有哪位高人,能够通过VB开发环境所在的进程,取得其中某个窗口所使用的线程,并将其操作的内存(数据部分)转化成可用的对象,再进行遍.

以我个人看法,取得进程再取得线程应该是可以办得到的.但是怎么样才能将所操作的内存区域判断出来是比较困难的,再想把其中的数据转化成可用的对象或数组,就更困难了.但我总觉得这是一条可行的路子,因为寻找内存比寻找对象要直接.我个人有些C语言的功底,也见过一些C语言中管理内存的操作.通常都是向指定的管理函数传入一个内存的起始地址,之后要么是给定长度和读取类型,要么就是按照一个顺序和指定长度不断循环至出现'\0'.总之读取内存的方法想来应该更快捷.

但是本人目前没有找到转化内存中对象的方法,更没有办法判断内存的区域和内存中的对象属于哪一类型.所以只能提出来,看看是不是有高人能做到.万望赐教.
回复
nmd002 2008-05-19
真奇怪。我已经安装了中文OFFICE2003,但是这个DLL的引用还是没效果。
我点击了“引用”,在“浏览”中指定C:\WINDOWS\SYSTEM32\FM20.DLL,然后在选单中该项打挑。但是什么也没出现。
我再重新点击“引用”,结果里面我已经打过挑的那项“Microsoft Forms 2.0 Object Library ”前面的挑不见了。
请问“老鸟”这是什么原因啊。
回复
nmd002 2008-05-19
谢谢老鸟,我刚从网上找到这个问题的解决方法。正在安装
回复
Tiger_Zhao 2008-05-19
Microsoft Forms 2.0 Object Library 只要安装 Office(可能是 2000 以上)就有了。
回复
nmd002 2008-05-19
感谢大家的帮助。向大家汇报一下目前的进展。

1:我已经找到了 VB老鸟 提到的TabOrder的例程,并且已经运行看到了效果。目前正在研究代码。是否能够加以利用,目前未知。

2:前面已经提到过的“Microsoft Forms 2.0 Object Library”即“FM20.DLL”这个文件,我只在日文的XP下看到过,在中文XP下的系统中并没有找到。所以我复制了日文系统下的这个文件到指定目录加以引用。但是总是引用之后毫无反应。也没有像 (chenjl1031)东方之珠说的那种效果,显示出什么新控件。想请教各位这个“FM20.DLL”文件,在中文系统下要安装什么程序才能出现?

3:“(yinweihong)请结贴,谢谢!”的回复中提到vbext_wt_Locals这个类型名,我在MSDN中只查到两个常量的定义,目前暂时还没有进行深入的研究,不知道是否能用上。
回复
yinweihong 2008-05-19
里面的变量的顺序正是从该过程开始的变量的压栈顺序,变量的名字好拿到,是值可能比较难拿....


呵呵,一定要做的话,

呵呵,拿到变量的名字后到立即窗口里面debug.print 拿值~...
回复
yinweihong 2008-05-19
[Quote=引用 30 楼 nmd002 的回复:]
请教大家,是不是还有别的思路可以借鉴,以达到使我取得本地窗口内树状控件数据的目的。

目前看使用VBIDE来取得值的可能性,还不如直接使用API的可能性高。用API取得窗体句柄后,最不济也还能取得窗口中其他的几个控件:两个滚条,一个EDIT(当前窗体的名称那个),一个按钮(...那个)。如果用了VBIDE来获得窗体,就只能得到窗体本身,而且除了设焦点和关闭窗口,再就只能取个宽高顶底的位置了。

烦请各位高人,本着研究…
[/Quote]

不知道楼主到底想做什么...但是很明显,你现在从拿到窗口句柄,然后去拿那些值的路已经走死

拿值的另外一个思路:

楼主可以注意到当前locals窗口显示的正是Locals里面Edit所指示过程/函数 里面所有的变量的名字和值
里面的变量的顺序正是从该过程开始的变量的压栈顺序,变量的名字好拿到,是值可能比较难拿....


或者 直接扫描VB6的栈...再去分析,难度更大


楼主可以说明一下到底想做什么,大家帮你看看,也不至于走如此...
回复
lsftest 2008-05-19
楼主想要干什么呢?要应用到什么地方?是对本地窗口本身有兴趣还是对里面的数据有兴趣???如果是后者可以参考我在另一帖子的回复:
http://topic.csdn.net/u/20080518/21/88464e5e-3768-490a-80c0-7bd51cfa3c6e.html
回复
nmd002 2008-05-19
请教大家,是不是还有别的思路可以借鉴,以达到使我取得本地窗口内树状控件数据的目的。

目前看使用VBIDE来取得值的可能性,还不如直接使用API的可能性高。用API取得窗体句柄后,最不济也还能取得窗口中其他的几个控件:两个滚条,一个EDIT(当前窗体的名称那个),一个按钮(...那个)。如果用了VBIDE来获得窗体,就只能得到窗体本身,而且除了设焦点和关闭窗口,再就只能取个宽高顶底的位置了。

烦请各位高人,本着研究技术不达目的不罢休的精神,继续跟帖。希望大家能有新的想法可以提出来。谢谢各位。
回复
nmd002 2008-05-19
“Microsoft Forms 2.0 Object Library ”的加载已经成功,只要不按引用添加而按照部件来添加就可以了。为了保证程序的可用性,我把OFFICE2003换成了OFFICE2000,所以现在的控件列表里,可能不全是最新的控件。没有我需要捕获的那个树状控件,这是肯定的。而且这其中的大部分控件和常规的控件区别好像不是太大,只是属性内容上有区别,外观差异比较小。

另外,我把VBIDE的ADDIN的那个例子看了一下,基本上可以理解他的内容和原理。但是似乎想要达到我的使用效果还是有困难。现将原因解释在下面:
1:ADDIN的主要功能,怎么看都是针对VB编辑环境中的代码视窗和设计视窗为主来制作的。其他视窗都只做为点缀,可用的功能主要是设焦点和关闭窗口。
2:虽然我写的代码暂时还没有运行成功,没有看到运行效果。但是,取不到本地窗体中的任何控件已经是肯定的了。因为在阅读过MSDN后,发现VBE对象(就是整个VB代码编辑的窗体对象)下的各个小视窗,就是本地窗口、立即窗口之类的小窗体,全都是通过一个集合对象(VBIDE.WINDOWS类)来管理的,而其中的每个项目(VBIDE.WINDOW类),就只有那么少的可怜的操作方法和属性。根本就没办法得到这个窗口内的任何控件。估计是微软早就考虑到有人会想直接从他们的窗口里取值,所以就根本没有打算开放这些窗体内控件,使之作为可操作内容。
3:我想要获得的是本地窗体的数据信息,而本地视窗的数据,都是在运行中断,也就是调试时才出现数据的。从例子中的代码看,他是把运行时(包括运行中断时)的窗体都隐藏了。能否在调试状态下显示这个窗体,目前由于未修改其代码进行测试,所以目前说不上是否能够在调试状态下显示和有效运行。
回复
Tiger_Zhao 2008-05-19
不是在引用而是在组件中添加的。
回复
nmd002 2008-05-19
请问老鸟,如果“Microsoft Forms 2.0 Object Library ”加载成功的话,我可以找到与本地窗口中那个树状控件一样的控件吗?
回复
nmd002 2008-05-19
“Microsoft Forms 2.0 Object Library ”一直也没引用成功,不知道问题在哪里。
回复
WuYunpeng 2008-05-19
通过枚举正在运行的程序可得到这个本地窗口的句柄
回复
nmd002 2008-05-19
感谢(lsftest )的帮助,窗口早已捕获到了,类名也知道了。现在的目标是想要获得窗口内的树状控件,并将其中的值取得出来。
回复
lsftest 2008-05-19
[Quote=引用 19 楼 nmd002 的回复:]
感谢大家的帮助。向大家汇报一下目前的进展。

1:我已经找到了 VB老鸟 提到的TabOrder的例程,并且已经运行看到了效果。目前正在研究代码。是否能够加以利用,目前未知。

2:前面已经提到过的“Microsoft Forms 2.0 Object Library”即“FM20.DLL”这个文件,我只在日文的XP下看到过,在中文XP下的系统中并没有找到。所以我复制了日文系统下的这个文件到指定目录加以引用。但是总是引用之后毫无反应。也没有像 (chenjl1…
[/Quote]
我用myspy看本地窗口的类名是VbaWindow。
回复
东方之珠 2008-05-18
[Quote=引用 9 楼 nmd002 的回复:]
请教:
Microsoft Forms 2.0 Object Library
在我的VB引用中为什么没看到呢?
[/Quote]

你确信Microsoft Forms 2.0 Object Library引用成功了吗?
引用后,工具箱中增加很多像常规控件一样的控件,比如:listbox,commandbutton,combox等.
回复
发帖
API
创建于2007-09-28

1461

社区成员

VB API
申请成为版主
帖子事件
创建了帖子
2008-05-16 03:36
社区公告
暂无公告