Имя элемента управления из другого окна

Мне нужно прочитать текстовое значение из другого окна и запросить это значение в другом приложении (мой вопрос будет касаться 1-го задания)… поэтому я "шпионю" за другим окном (какое-то стороннее приложение, которое мы используем в связи с нашим продуктом) и ожидание нажатия кнопки "принять" для считывания значения из текстового поля. Это другое приложение, диалоговое окно, имеет несколько текстовых полей и командных кнопок. Я сделал крючок мыши и активирую его при появлении этого приложения. Я читаю все движения мыши внутри этого прямоугольника окна; тексты, подписи, идентификаторы дочерних окон, прямоугольники, щелчки левой / правой / средней / колесики. Я могу получить кнопку "принять"; Я МОГУ ВИДЕТЬ заголовок кнопки и могу прочитать это окно, получить текст и определить, какая кнопка нажата и т. Д. Теперь... Я могу читать ВСЕ значения класса РЕДАКТИРОВАТЬ, получать их дескрипторы окон, прямоугольники и т. Д., НО НЕ МОГУ ОПРЕДЕЛИТЬ ИХ КАК УНИКАЛЬНЫЕ предметы в коллекции классов: мне нужно специально прочитать желаемое значение текстового поля. К счастью, текстовое поле, которое меня интересует, ВСЕГДА НАХОДИТСЯ ПЕРВОЙ В МОЕЙ ПЕТЛЕ, когда я читаю тексты из цикла EDIT. Однако я хотел бы быть более конкретным; убедившись, что я читаю текстовое поле с именем. Я знаю. Во время разработки я мог прочитать это ИМЯ и жестко запрограммировать его в программе. Я подозреваю, что имя элемента управления не сохраняется в двоичном коде. Насколько я понимаю, идентификатор элемента управления, дескриптор окна создаются при создании окна и не имеют абсолютно никакой ссылки на имя элемента управления (скажем, txtOrderNumber). Если для кнопок я могу быть конкретным из-за заголовков кнопок (так, я могу определить, какая кнопка нажата), я заблокирован с элементами класса EDIT и брошен в 1-е предположение при чтении значения. Мой вопрос: как я могу получить имя элемента управления из другого окна, для этой задачи мне интересно узнать об именах экземпляров класса EDIT. Вот некоторые коды (сокращенные) из проекта:

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

Я посмотрел на API GetWindowLong и GetDlgCtrlID и попробовал большинство флагов, но пока безуспешно...

Любой совет, подсказка, направление приветствуется. Спасибо

1 ответ

Я сделал глобальный хук мыши, это не проблема, и GetWindowText и WM_GETTEXT работают нормально. На самом деле программа работает нормально и функционально на данный момент. После обнаружения целевого окна я сохраняю дескрипторы дочерних окон в коллекции списков, используя API EnumChildWindows и фильтруя только окна класса EDIT (используется в связи с опубликованной выше измененной версией функции GetClassValues. Аргументом для этой функции является первый дескриптор окна класса EDIT). В любом случае, способ произвольного доступа к желаемому текстовому полю - использовать сохраненный список для окон этого класса и доступ по индексу списка. Как я упоминал ранее, к счастью, окна СОЗДАЮТ ЭТОГО РЕБЕНКА в последовательном порядке. Итак, в моем случае это окно класса EDIT, текстовое поле "объект", всегда является первым в списке, хотя в главном окне их много. Я хотел бы получить это имя текстового поля "объект", скажем "txtAccountNumber", как я упоминал ранее...

Другие вопросы по тегам