如题。本人已用VB6+API制作了一段有效的代码,可以捕捉到VB6的“本地”窗体的句柄,经验证已取得句柄正确。
但是本人却无法将“本地”窗体中的那个树状控件的句柄捕捉到。试验证明SPY++也查不到这个控件的句柄。本人至今未能查到这个控件是什么类名(classname),属于哪个类型,也不知道如何才能取得其中的各个键值对。好像在VB6中也没有一种对应的控件是这个类型的。本人写这段程序的目的是,为了捕捉其他外部VB程序中调试时的“本地”窗体中的数据(变量名,值,类型),并希望能用层级结构制作数据的清单。如果有高人能够做到:
1:能用VB+API,取得其他程序VB6的“本地”窗体中已展开树的所有键值对,就算没有层级关系也行。
2:告知此树状控件是什么类型或类名,其运作的原理是什么。
3:通过该窗体句柄从进程中取得其内存数据,并转化为可用的VB对象。只要三个问题中可以回答出任何一个,并且经本人试用确实有效,就可得分。
如嫌少,可另外再给。
请各位高人指教,洗耳恭听。

解决方案 »

  1.   

    敝 人就让你 本 人瞧瞧TreeView与ListView的类名吧, 其余的要等 敝 人有空时再给你 本 人解答.....
      

  2.   

    不知道你所谓的“本地”窗体是哪个?
    所有的无窗口控件的内容都是在容器窗口上直接绘出来的,所以不可能按句柄方式进行访问。
    典型代表:组件中添加 Microsoft Forms 2.0 Object Library,里面的任何一个控件放在窗体上,都找不到句柄的。
      

  3.   

    感谢2楼高人的回应。盼星星盼月亮,终于盼来了解放军啊。高人就是高人!出手就不一样。但是……有几个地方还请再考虑一下:
    1:VB6里面的那个树状结构的控件倒底是不是TreeView或者ListView,仍然无法确定,需要再探讨。
    2:另外,这个控件有些麻烦。它与TREE有区别,它可以有多个根节点,用追加新对象的操作,就可以加入新的根。就算是TREE好像也只能找到一个根节点吧?
      

  4.   

    谢谢(Tiger_Zhao)VB老鸟的莅临指导!我所说的VB6“本地”窗体,就是在VB6运行调试时,通过断点暂停程序,再点击视图菜单,和“立即窗体”靠的很近的那个“本地窗体”,在窗体的标题里写着“本地”两个字,里面是一个树状的结构,展开后可得到当前程序某个窗体的各属性的名称、值、类型。其中的部分值,是可以点击后进行修改的。另外,您所说的Microsoft Forms 2.0 Object Library,在引用之后,可以找到与那个树状结构一致的控件吗?请赐教。
      

  5.   

    有没有会用实时临控软件查看VB窗体运行时内存状况的高人在啊?能给讲解一下这个控件的运作原理也是好的。如果这个帖子在这个版块里解决不了,我要不要到VC的论坛里也发一个问问呢?
      

  6.   

    被执行的程序是访问不到运行环境的,你可以仿照 VB-Addin 的例子,到 VBE 对象下的 Windows 集合中看看能不能访问到“本地”窗口的属性。
      

  7.   

    请恕在下鲁钝,再请教(Tiger_Zhao) VB老鸟:
    您所提的"VB-Addin",和"VBE对象下的WINDOWS集合"都是怎么用的?能不能再多给一点提示。
      

  8.   

    请教:
    Microsoft Forms 2.0 Object Library
    在我的VB引用中为什么没看到呢?
      

  9.   

    MSDN的样例中有一个叫 TabOrder,作为 Vb-Addin 就可以访问 VB-IDE 的环境对象 VBE。
    MSDN中查找“VBE 对象”
      

  10.   

    感谢老鸟的提示,由于手上没有MSDN,所以暂时无法知道是否适用,请容我调查之后,再行回复。
      

  11.   

    //
    这个控件的句柄的确没找到.如果它真是一个控件,那应该也是轻量控件...像LABEL一样绘上去的~~而不是用createwindow根据某个类生成的.....
    如果是样,你的方向可能要改改,如赵老虎所说,写个ADDIN吧~~~
      

  12.   

    来凑个热闹。 ^_^Mark.
      

  13.   

    local window的类型叫做vbext_wt_Locals  你去查一下,这一类型的窗口是不是有什么共通方法或者属性成员~
      

  14.   

    Spy++能捕捉到么?
    如果不能,恐怕你的程序也不能。
      

  15.   


    你确信Microsoft Forms 2.0 Object Library引用成功了吗? 
    引用后,工具箱中增加很多像常规控件一样的控件,比如:listbox,commandbutton,combox等.
      

  16.   

    感谢大家的帮助。向大家汇报一下目前的进展。1:我已经找到了 VB老鸟 提到的TabOrder的例程,并且已经运行看到了效果。目前正在研究代码。是否能够加以利用,目前未知。2:前面已经提到过的“Microsoft Forms 2.0 Object Library”即“FM20.DLL”这个文件,我只在日文的XP下看到过,在中文XP下的系统中并没有找到。所以我复制了日文系统下的这个文件到指定目录加以引用。但是总是引用之后毫无反应。也没有像 (chenjl1031)东方之珠说的那种效果,显示出什么新控件。想请教各位这个“FM20.DLL”文件,在中文系统下要安装什么程序才能出现?3:“(yinweihong)请结贴,谢谢!”的回复中提到vbext_wt_Locals这个类型名,我在MSDN中只查到两个常量的定义,目前暂时还没有进行深入的研究,不知道是否能用上。
      

  17.   

    Microsoft Forms 2.0 Object Library 只要安装 Office(可能是 2000 以上)就有了。
      

  18.   

    真奇怪。我已经安装了中文OFFICE2003,但是这个DLL的引用还是没效果。
    我点击了“引用”,在“浏览”中指定C:\WINDOWS\SYSTEM32\FM20.DLL,然后在选单中该项打挑。但是什么也没出现。
    我再重新点击“引用”,结果里面我已经打过挑的那项“Microsoft Forms 2.0 Object Library ”前面的挑不见了。
    请问“老鸟”这是什么原因啊。
      

  19.   

    我用myspy看本地窗口的类名是VbaWindow。
      

  20.   

    感谢(lsftest )的帮助,窗口早已捕获到了,类名也知道了。现在的目标是想要获得窗口内的树状控件,并将其中的值取得出来。
      

  21.   

    “Microsoft Forms 2.0 Object Library ”一直也没引用成功,不知道问题在哪里。
      

  22.   

    请问老鸟,如果“Microsoft Forms 2.0 Object Library ”加载成功的话,我可以找到与本地窗口中那个树状控件一样的控件吗?
      

  23.   

    “Microsoft Forms 2.0 Object Library ”的加载已经成功,只要不按引用添加而按照部件来添加就可以了。为了保证程序的可用性,我把OFFICE2003换成了OFFICE2000,所以现在的控件列表里,可能不全是最新的控件。没有我需要捕获的那个树状控件,这是肯定的。而且这其中的大部分控件和常规的控件区别好像不是太大,只是属性内容上有区别,外观差异比较小。另外,我把VBIDE的ADDIN的那个例子看了一下,基本上可以理解他的内容和原理。但是似乎想要达到我的使用效果还是有困难。现将原因解释在下面:
    1:ADDIN的主要功能,怎么看都是针对VB编辑环境中的代码视窗和设计视窗为主来制作的。其他视窗都只做为点缀,可用的功能主要是设焦点和关闭窗口。
    2:虽然我写的代码暂时还没有运行成功,没有看到运行效果。但是,取不到本地窗体中的任何控件已经是肯定的了。因为在阅读过MSDN后,发现VBE对象(就是整个VB代码编辑的窗体对象)下的各个小视窗,就是本地窗口、立即窗口之类的小窗体,全都是通过一个集合对象(VBIDE.WINDOWS类)来管理的,而其中的每个项目(VBIDE.WINDOW类),就只有那么少的可怜的操作方法和属性。根本就没办法得到这个窗口内的任何控件。估计是微软早就考虑到有人会想直接从他们的窗口里取值,所以就根本没有打算开放这些窗体内控件,使之作为可操作内容。
    3:我想要获得的是本地窗体的数据信息,而本地视窗的数据,都是在运行中断,也就是调试时才出现数据的。从例子中的代码看,他是把运行时(包括运行中断时)的窗体都隐藏了。能否在调试状态下显示这个窗体,目前由于未修改其代码进行测试,所以目前说不上是否能够在调试状态下显示和有效运行。
      

  24.   

    请教大家,是不是还有别的思路可以借鉴,以达到使我取得本地窗口内树状控件数据的目的。目前看使用VBIDE来取得值的可能性,还不如直接使用API的可能性高。用API取得窗体句柄后,最不济也还能取得窗口中其他的几个控件:两个滚条,一个EDIT(当前窗体的名称那个),一个按钮(...那个)。如果用了VBIDE来获得窗体,就只能得到窗体本身,而且除了设焦点和关闭窗口,再就只能取个宽高顶底的位置了。烦请各位高人,本着研究技术不达目的不罢休的精神,继续跟帖。希望大家能有新的想法可以提出来。谢谢各位。
      

  25.   

    楼主想要干什么呢?要应用到什么地方?是对本地窗口本身有兴趣还是对里面的数据有兴趣???如果是后者可以参考我在另一帖子的回复:
    http://topic.csdn.net/u/20080518/21/88464e5e-3768-490a-80c0-7bd51cfa3c6e.html
      

  26.   


    不知道楼主到底想做什么...但是很明显,你现在从拿到窗口句柄,然后去拿那些值的路已经走死拿值的另外一个思路:楼主可以注意到当前locals窗口显示的正是Locals里面Edit所指示过程/函数 里面所有的变量的名字和值
    里面的变量的顺序正是从该过程开始的变量的压栈顺序,变量的名字好拿到,是值可能比较难拿....
    或者  直接扫描VB6的栈...再去分析,难度更大
    楼主可以说明一下到底想做什么,大家帮你看看,也不至于走如此...
      

  27.   

    里面的变量的顺序正是从该过程开始的变量的压栈顺序,变量的名字好拿到,是值可能比较难拿.... 
    呵呵,一定要做的话,呵呵,拿到变量的名字后到立即窗口里面debug.print 拿值~...
      

  28.   

    感谢大家的热烈响应。
    现将本人的目标再重新声明一下:
    本人想通过一段程序,实现指定VB开发环境下,某个运行中的VB程序的各项数据(包括变量、对象及其值)。而且现在主要是想把“本地窗口”内的那个树状结构中所显示出的数据,做为输出的主要来源。也就是说,执行某VB程序之后,在运行中中断,通过本地窗口所监控到的数据(名称、值、类型),都想当作内容做一个输出(甚至是按层级的定位或查询,当然那是在树状结构可控的前提下才行),以供使用者方便地查找和监控变量的值。本人首先使用的方法是捕获该窗口句柄的方法,结果是可以捕获该窗体,可以捕获窗体中除树状控件以外的其他控件的句柄和值。老鸟的解释是:有些控件是直接进行绘制的,因此此类控件是没有句柄可供捕获的。所以本人基本放弃了这种获得数据的思路。接下来,根据老鸟和诸位高人的提议,本人研究了ADDIN的使用。本指望通过微软封装的类,取得本地窗体,并将其内所含控件取得后,再加利用。谁知微软不地道,他们没有留下操作窗体内任何控件的途径和方法。所以本人当时考虑,如果还是不能取得控件中的各名称和值的话,只好自己写一个类似本地窗体的ADDIN。用本地窗口的表现形式做一个仿品,功能仿照本地窗口中的树状结构来显示各对象,点击节点,伸缩树枝。然后在其上扩展自己的输出功能,把已经展开的节点中的全部属性名和值都做为输出的内容。但是最后的这种想法,会涉及到几个问题,尚待解决:
    1:ADDIN方式建立的窗口,在运行中断的情况下,是否能取得运行中某个控件的各属性及其值。看过前面(lsftest)给出的那篇文章,多少对取得某控件的全部属性有了信心。但是对在运行中断时的控件对象的取得,因为没有测试过,仍不敢确定。
    2:ADDIN窗口在运行中断的情况下,是否能正常显示,还没有经过测试。如果ADDIN无法在中断情况下显示,那最后的这个想法也只能放弃了。
    3:还有一个功能控件的问题。本地窗口的树状控件,看来很简单,但是却包含了许多一般控件没有的功能。比如随时可以在其中添加新的对象或变量,并对其从属的属性进行同样的树状伸缩。也就是说这个控件不是一般的树,只有一个根,他可以有多个根,每个单独的根都可以伸缩,也是个极其难以模仿的控件。另外,“(yinweihong)请结贴,谢谢!”在回复中提到的“直接扫描VB6的栈...再去分析,难度更大”,我也很感兴趣。能否介绍一下思路或者方法,使本人可以在此基础上,拓展一下思路。也许这个问题看着难,解决起来其实很容易。关键是本人的技术水平仍然很有限,思维还不够活跃,才无法脱离已知的条条框框的束缚。希望各位有识之士,能够提出更有创意的思路和方法来。本人感激涕零,热烈盼望各位不吝赐教。
      

  29.   

    不知道有没有哪位高人,能够通过VB开发环境所在的进程,取得其中某个窗口所使用的线程,并将其操作的内存(数据部分)转化成可用的对象,再进行遍.以我个人看法,取得进程再取得线程应该是可以办得到的.但是怎么样才能将所操作的内存区域判断出来是比较困难的,再想把其中的数据转化成可用的对象或数组,就更困难了.但我总觉得这是一条可行的路子,因为寻找内存比寻找对象要直接.我个人有些C语言的功底,也见过一些C语言中管理内存的操作.通常都是向指定的管理函数传入一个内存的起始地址,之后要么是给定长度和读取类型,要么就是按照一个顺序和指定长度不断循环至出现'\0'.总之读取内存的方法想来应该更快捷.但是本人目前没有找到转化内存中对象的方法,更没有办法判断内存的区域和内存中的对象属于哪一类型.所以只能提出来,看看是不是有高人能做到.万望赐教.
      

  30.   

    已经测试过了,默认的ADDIN开发出来之后,其窗体只能显示在编码状态下。在运行中断(调试)状态下,整个外接程序根本就是被关闭的。连外接程序的主菜单都禁用了,更不用说其下的其他窗体了。
    现在我认为ADDIN在VB6里的主要作用,只能是作为编码的辅助用窗口,连参与调试的可能性都没有。不能满足我的开发需求。但愿我的判断是错误的,可以有哪位高人出来指正一下。请问现在还有哪位高人,有办法能帮我获得VB本地窗体中的数据吗?求大家帮忙顶帖。我还是不死心!
      

  31.   

    调试的时候addin都灰掉了,我发现用钩子的时候,好像有一些权限..比如可以通过键盘钩子调出对话框.你可以通过另一种思路啊,比如在立即窗口里createobject
    通过typelib information(tlbinf32.dll)动态分析对象的属性,属性值,动态调用成员函数...