Link to home
Start Free TrialLog in
Avatar of Dovberman
DovbermanFlag for United States of America

asked on

How to read text boxes and list box rows from another open application.

I would like to read text boxes and list box rows from another open application.  The other application is not my own. Any suggestions?
Avatar of edwardiii
edwardiii

Hi, Dovberman.

If the application is Internet Explorer based, you can use methods as I've detailed here:

     https://www.experts-exchange.com/questions/21387130/Web-pages-that-use-input-from-user-Part-2.html


Otherwise, you need to start with the window handle of the application, enumerate all its components, and then act on the ones (e.g. text boxes and list boxes) you want.  You'll need something like Spy++ to know what the class names are of the components you want to manipulate.  An example is here:

     https://www.experts-exchange.com/questions/21387870/Findwindow-Classes.html

Sometimes its all but impossible to grab what you need from another application, for example because it tears down the component when its not in use.  It all depends on how the other application was constructed.


Avatar of Dovberman

ASKER

I will try the enum methods on Monday.  This is an application that I distribute. Will distributed spyware adversly affect customer computers ?

Thanks,

Dovberman
Yes, this helped.  I then combined it with

http://vbnet.mvps.org/index.html?code/enums/enumwindowsdemo.htm

This finds open applications and enumerates both the main and child windows.  

Thanks,

Dovberman
How do I read label captions? The label controls are not enumerated.

Glad you're making progress:)  You need to use Spy++ or something similar and drag it's "target" square right into your target application's label caption.  Work up from there to determine the chain of components that label is a child of, and alter the coding of your Enumeration accordingling.  Bear in mind, if you are dealing with a static application, then you can forego hunting for textboxes based on the related label captions.  Determine which textbox you want (e.g. the 2nd one in the app) set up a counter "x" in your Enum loop and save the window handle value when x = 2.

Not sure what you mean by :"Will distributed spyware adversly affect customer computers ?" in the context of enumerating an app's components?
I have developed an app that is used by poker players while playing online.  Competitive apps read the open card values from the game window.  My app requires users to click on a card deck in my app.  I downloaded competitive apps and found that spyware was installed on  my computer.  I do not wish to install spyware on customer computers.
I'm still not following you, sorry:(  But using enumeration/and SendMessage/PostMessage APIs to control textbox contents will not install spyware, or add spyware to an app.
No problem.  I will use Spy++ in development  mode to identify handles.

Then I will use enum in the application.

I understand now that spyware will not be installed with my product.
Good deal.  Please bear in mind, if the items you're looking for aren't directly under the main parent class (e.g. they may be several class layers down), you'll have to also employ the FindWindowEx API.  Below is an example I've used:

    Dim first, second, third, fourth, fifth, sixth, seventh As Long

    first = FindWindow("arframe", vbNullString)
    second = FindWindowEx(first, 0&, "MDIClient", vbNullString)
    third = FindWindowEx(second, 0&, vbNullString, "VZ - East - NRB (New)")
    fourth = FindWindowEx(third, 0&, "AfxMDIFrame42", vbNullString)
    fifth = FindWindowEx(fourth, 0&, "AfxFrameOrView42", "FormView")
    sixth = FindWindowEx(fifth, 0&, "SysTabControl32", vbNullString)
   
    EnumChildWindows sixth, AddressOf EnumChildWindow, ByVal 0&
    seventh = EnumFoundHandle
    Call SendMessageByString(seventh, WM_SETTEXT, 0&, txtAll)               ' "txtAll" is a text box containing the text to send.
Thanks,

I will try this.  One issue that I have is detecting a mouse click on a specific image or command button in the application window.

I have set messages and can get output from mouse clicks.  I am still learning Spy++.
Okay.  Detecting a mouse click would be the basis for another question, but I can assist with finding the textbox in question.  Regarding Spy++, be aware you should have your outside application running when you fire up Spy++.  Otherwise, when you click the "Find" (binoculars) icon, you'll drag it to the textbox in the app, and when you hit "Ok" in the Window Search dialog box, you'll get a "Can't find window which matches search criteria error".  So, if you open your outside app after you start Spy++, be sure to do a Window/Refresh from the Spy++ top menu.

Let's consider an example with finding the field in the Windows Calculator where one enters calculations.  In Win2k Pro, the application class is "static" and the Caption will be "0" (if you haven't input any numerals in the Calculator).  If you do a Find and drag the "Finder Tool" into the edit box of the calculator, then press OK, the main Spy++ screen will highlight the field/class in question.  For example, I got this:

     - 01080726 "Calculator" SciCalc
           01790736 "Hyp" Button
           00EE06FE "Inv" Button
           00BE070C ""     Button
           011B070A ""     Button
           010407B6 "0. " Static
           and so on....

In this case, the component I want to manipulate is one level down from the application/parent class "SciCalc", so if I just use FindWindow and enumerate all the components of SciCalc using its window handle "01080726", I'll get several buttons and about 4 Static fields.  If the Static field I wanted had no caption, then I would have to loop until I had gone through x instances of Static to grab the one I want.

Now, what if you wanted a Text field that was buried inside another class?  Spy ++ would show you the complete hierarchy:

     -00000000 "Outside App" OutApp
           -00000001 "" TabbedPane
                 00000022 "" Edit      '<--You're looking for this.

You would edit your FindWindow...coding as follows:

     Dim first, second, third, fourth, fifth, sixth, seventh As Long

     first = FindWindow("OutApp", vbNullString)   'or, as your app has a caption you could use "Outside App" vs vbNullString
     second = FindWindowEx(first, 0&, "TabbedPane", vbNullString)

     EnumChildWindows second, AddressOf EnumChildWindow, ByVal 0&
     third = EnumFoundHandle
     Call SendMessageByString(third, WM_SETTEXT, 0&, txtAll)        

By the way, I named component "TabbedPane" for ease of understanding--a real Tab element would have a different
class name. However, you can see it's a matter of knowing the hierarchy from parent class to target class, and enumerating the immediate parent of your target class.  If, in the above example, you had three "TabbedPane" elements and they all had no caption, you would have to run two EnumChildwindows routines

The first to cycle through all elements of "OutApp" looking for "TabbedPane" (and use the For loop in EnumChildWindows to grab the handle of the correct TabbedPane instance, for example the second one).  The second to take the handle of the correct TabbedPane returned by the first enumeration and then enumerate its contents (all the while scanning for the correct instance of "Edit"--e.g. whatever your textbox element class is called--and using the For loop to grab the handle of the correct instance).

Hope that helps:)
Thanks,

Calc.exe is a good example to use for testing.

Once I drill down to get the needed sub window, I will be ready to detect a mouse click.

Detecting a mouse click on the target class is a different subject.

Can you tell me if SetWindowsHookEx can be set to work with a windows application like Calc.exe?

Thanks,

Dovberman
Why is FindWindow("OutApp", vbNullString)  instead of FindWindow(vbNullString,"OutApp")  ?

Where is the code for EnumFoundHandle?
ASKER CERTIFIED SOLUTION
Avatar of edwardiii
edwardiii

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial