What would be an ideal way to list existing objects to read and alter their properties?

∥☆過路亽.° 提交于 2020-01-10 05:22:05

问题


I'm trying to develop an application in Delphi XE2 that will be able to read and alter object properties between different applications.

Currently, our only target applications are one developed in Delphi XE, to which I have the source code, and one done in VB6, which we have no source or information.

Main objects we are looking for are Labels and Edits, but ideally I'd need to almost design an object viewer, listing every object as well as their properties, being able to read and alter those at will, and call methods.

I am at a loss on how to do so, best I got was being able to read some label captions, based on reading the buffer on the VB application and working directly with memory allocations, but even that had it's limitations, since it only worked in WinXP, not Windows 7 like intended.

What would be the best way to accomplish what I want? I am willing to code in a different language if it would be best.

Edit: After doing some more research, I discovered TestComplete, and within it, it has an object viewer that basically does the listing/modifying of objects and their properties.
Being so that the goal is not to use a third software party to do this, it is clear that this is doable, but I am lost as to how. MSAA/IAutomation worked to an extent, but neither could really list me all objects.

Here are a couple of screens to show briefly how it works (With the 3rd Party VB application, redacted parts for security):


回答1:


Additionally to WinAPI, you can use Microsoft Active Accessibility to get information from other window. Here is small example: http://blogs.msdn.com/b/oldnewthing/archive/2004/04/23/118893.aspx and delphi code: http://www.transl-gunsmoker.ru/2009/08/blog-post.html




回答2:


What would be the ideal way to list the existing objects and read/modify their properties ?

There is nothing like ideal way. Either you know the application and have some interface to it (or know it from inside) or you have to conform to what is available. If your target is the Windows application with the common Windows controls, then Windows API is what you are looking for.

However, not all of the controls you can see on the screen are accessible through the Windows API and unfortunately labels are one of them. Generally speaking, only window controls, those having handle are accessible through the Windows API.

How to create an object viewer listing every object (of the foreign application) and its properties, be able to read and modify these properties and call the object's methods.

The object listing (from the Windows API point of view) is pretty easy, you need to get the handle of the window from the target application you want to inspect and enumerate its child windows (or better to call them components for this time), with code like this one.
But the only two related things you can get from such enumeration - the component handle and its class name. Each component instance has its own, at one time unique, system wide identifier and a class type identified by the class name.

One can say, that's cool, I can get the system wide component identifier and the class type, so I can rule every component in the whole wide Windows by sending component's specific windows messages, but ...
who in the world would expect that class names may differ for components that processes and reacts to the same messages the same way ?

Well, your nightmare is called subclassing and it allows developers to extend the existing components with the new functionality under the new class name. As one illustrious example might be used the basic Windows edit box class EDIT and our Delphi subclassed type TEdit. Both can be controlled by the same set of messages and both behaves the same, but from your point of view it's just another hitch, because you will have to remember that if you find the component with the TEdit class type you have to control it the same way like the EDIT class component.

So now you know what type is the component with a certain handle, what remains is to choose the right set of functions (messages) that can be used with that component type. All what you need you will find
on the MSDN reference pages. There are all available common control functions, including those for getting or setting certain component properties and the best is to browse there.

About calling foreign application object methods. Fortunately, this is not possible, and I don't even want to imagine what might be caused by a malware or badly written application calling each others functions from one process to another without any restriction.




回答3:


It's quite easy, with RTTI and, say, Indy TidTCPServer, to add a text-based, 'telnet-like' object browser/editor to any Delphi app. I have done this on several apps, organising the form and component structure so that containers appears as 'folders' and the components like 'files'. It can be useful.. and fun. It is a little unsettling for users when their app suddenly changes color in front of them, or gradually gets taller and taller and thinner and thinner. The bug reports I then get are entertaining, (no, you're right, I shouldn't do it, even to marketing managers).

I don't see why a form-based browser could not be constructed with a treeView. Clicking on a component node could bring up a form that lists the properties and allows them be edited. IIRC, I could only call published methods like this.

OTOH, I've no idea how to effectively get at a VB app. VB is not something I like to approach without adequate protection and those hazmat suits are uncomfortable.



来源:https://stackoverflow.com/questions/10096071/what-would-be-an-ideal-way-to-list-existing-objects-to-read-and-alter-their-prop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!