Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others


0 votes
in Technique[技术] by (71.8m points)

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

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):

TestComplete Object Browser TestComplete Object Browser 2

See Question&Answers more detail:os

Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share