Control name from other window

1.5k views Asked by At

I need to read a text value from other window and query that value to another application (my question will be around the 1st task)…so, I’m “spying” other window (some 3rd party application we use in connection with our product) and waiting for “accept” button to be clicked to read a value from a text box. This other application, the dialog box, has multiple text boxes and command buttons. I made a mouse hook and I’m activating it upon this application appearance. I‘m reading all mouse moves inside this window rectangle; texts, captions, child windows IDs, rectangles, grab left/right/middle/wheel clicks. I can grab the “accept” button click; I CAN SEE the button caption and I can read that window, get the text and determine what button is clicked, etc. Now… I can read ALL EDIT class values, get their window handles, rectangles, etc., BUT I CANNOT IDENTIFY THEM AS UNIQUE items within the class collection: I need specifically read my desired text box value. Fortunately the text box I’m interested in is ALWAYS COMES FIRST IN MY LOOP when I’m reading texts from EDIT class loop. However I would like to be more specific; making sure that I’m reading the text box with the NAME. I know. During the development I could read that NAME and hard code it in the program. My a suspicion is that control name is not saved in the binary code. My understanding is that control ID, windows handle are created upon windows creation and have absolutely no reference to control name (say: txtOrderNumber). If for buttons I can be specific because of button captions (so, I can determine what button is clicked) I’m locked with EDIT class items and thrown to lucky 1st guess when reading the value. My question is: How I can get a control name from another window, for this task I’m interested to know about EDIT class instance names. Here are some codes (shortened) from the project:

Dim hWnd As IntPtr = FindWindow(Nothing, _windowText)

'API: FindWindowEx 'API: SendMessage 'API: GetClassName 'API: GetWindowTextLength 'API: GetWindowText 'API: WM_GETTEXT

Public Shared Function GetClassValues(_controlClass As String, _hWindow As IntPtr) As List(Of String)

    Dim cl As New List(Of String)

    'First control handle in that class
    Dim hc As IntPtr = FindWindowEx(_hWindow, IntPtr.Zero, _controlClass, vbNullString)
    Do
        Dim sv As String = GetWindowValue(hc)
        cl.Add(sv)

        'Next control (after hc) handle
        hc = FindWindowEx(_hWindow, hc, _controlClass, vbNullString)
    Loop Until hc = 0
    Return cl
End Function
Public Shared Function GetWindowValue(_hWindow As IntPtr) As String
    If _hWindow = IntPtr.Zero Then Return String.Empty
    Dim sz As Integer = 256
    Dim bf As IntPtr = Marshal.AllocHGlobal(sz)
    Dim pt As IntPtr = SendMessage(_hWindow, WM_GETTEXT, sz, bf)
    Dim rs As String = Marshal.PtrToStringUni(bf)
    Marshal.Release(bf)
    Return rs.Trim
End Function
Public Shared Function GetWindowClassName(_hWindow As IntPtr) As String
    Dim ln As Integer = 256
    Dim sb As New System.Text.StringBuilder("", ln)
    GetClassName(_hWindow, sb, ln)
    Return sb.ToString()
End Function
Public Shared Function GetWindowText(_hWindow As IntPtr) As String
    Dim ln As Integer
    If _hWindow.ToInt32 <= 0 Then Return String.Empty
    ln = GetWindowTextLength(_hWindow)
    If ln = 0 Then Return String.Empty
    Dim sb As New System.Text.StringBuilder("", ln + 1)
    GetWindowText(_hWindow, sb, sb.Capacity)
    Return sb.ToString()
End Function

I've looked at GetWindowLong and GetDlgCtrlID API and have tried most of the flags with no success so far...

Any tip, clue, direction is appreciated. Thank you

1

There are 1 answers

0
Sam Saarian On

I made a global mouse hook, this is not a problem and, GetWindowText and WM_GETTEXT works fine. As a matter of fact the program works fine and functional at this point. Upon detecting a target window I save child window handles in a list collection using EnumChildWindows API and filtering EDIT class windows only (used in connection with modified version of GetClassValues function posted above. The argument for this function is the first EDIT class window handle). Anyway, the way how I arbitrary access my desired text box is to use the saved list for this class windows and access by list index. As I mentioned earlier, fortunately, windows CREATES THIS CHILD windows in consistent order. So, in my case this EDIT class window, the text box “object”, is always the 1st in the list though there are many in the main window. I would like to get that the text box “object” name, say “txtAccountNumber” as I mentioned earlier…