Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 751
  • Last Modified:

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?
0
Dovberman
Asked:
Dovberman
  • 8
  • 6
1 Solution
 
edwardiiiCommented:
Hi, Dovberman.

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

     http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21387130.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:

     http://www.experts-exchange.com/Q_21387870.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.


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

Thanks,

Dovberman
0
 
DovbermanAuthor Commented:
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
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
DovbermanAuthor Commented:
How do I read label captions? The label controls are not enumerated.

0
 
edwardiiiCommented:
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?
0
 
DovbermanAuthor Commented:
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.
0
 
edwardiiiCommented:
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.
0
 
DovbermanAuthor Commented:
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.
0
 
edwardiiiCommented:
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.
0
 
DovbermanAuthor Commented:
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++.
0
 
edwardiiiCommented:
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:)
0
 
DovbermanAuthor Commented:
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
0
 
DovbermanAuthor Commented:
Why is FindWindow("OutApp", vbNullString)  instead of FindWindow(vbNullString,"OutApp")  ?

Where is the code for EnumFoundHandle?
0
 
edwardiiiCommented:
To answer your questions:

1)  SetWindowsHookEx can be set to work with a windows application like Calc.exe?

     Am not sure, I've not experimented with that API.  Per the Internet Explorer-based link above, I am familiar with
    taking action based on a Document.Element...click event.  Can only recommend you search this forum, AllApi.net,
    or Google for "SetWindowsHookEx".

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

    FindWindow("OutApp", vbNullString) will operate on your target application/window, based on its class name
    as shown in Spy++ (e.g. "SciCalc").

    FindWindow(vbNullString,"OutApp") will operate on the target app based on its window caption (e.g. "Calculator").

3) Where is the code for EnumFoundHandle?
 
    You need to drop the code into a module per my post here:
    http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_21387870.html:

    Function EnumChildWindow(ByVal hChild As Long, ByVal lParam As Long) As Long

         Dim wClass As String
         Dim j As Integer
   
         wClass = Space(64)
         j = GetClassName(hChild, wClass, 63)
         wClass = Left(wClass, j)
         
         wText = Space(256)
         j = SendMessageByString(hChild, WM_GETTEXT, 255, wText)
         wText = Left(wText, j) '
   
         Debug.Print "Enum " & hChild; ", "; wClass;
         If Len(wText) Then Debug.Print ", """; wText; """";
         Debug.Print
   
         If wClass = "ThunderRT6TextBox" Then
              x = x + 1
              If x = 2 Then      'NOTE: you can change x = 1 to get your Text2.text
                  mystr = wText
              End If
         End If
   
         EnumChildWindow = 1  ' Continue enumeration
         End Function

0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now