0

我需要从其他窗口读取文本值并将该值查询到另一个应用程序(我的问题将围绕第一个任务)......所以,我正在“监视”其他窗口(我们使用的一些与我们的产品相关的第 3 方应用程序) 并等待单击“接受”按钮以从文本框中读取值。这个另一个应用程序,对话框,有多个文本框和命令按钮。我制作了一个鼠标钩,并在此应用程序出现时激活它。我正在读取此窗口矩形内的所有鼠标移动;文本、标题、子窗口 ID、矩形、左/右/中/滚轮点击。我可以抓住“接受”按钮点击;我可以看到按钮标题,我可以读取该窗口,获取文本并确定单击了哪个按钮等。现在……我可以读取所有 EDIT 类值,获取它们的窗口句柄、矩形等,但我无法将它们识别为类集合中的唯一项目:我需要专门阅读我想要的文本框值。幸运的是,当我从 EDIT 类循环中读取文本时,我感兴趣的文本框总是首先出现在我的循环中。但是我想更具体一点;确保我正在阅读带有 NAME 的文本框。我知道。在开发过程中,我可以读取该名称并将其硬编码到程序中。我的怀疑是控件名称未保存在二进制代码中。我的理解是控件 ID、窗口句柄是在创建窗口时创建的,并且绝对不引用控件名称(例如:txtOrderNumber)。如果对于按钮,我可以因为按钮标题而具体化(因此,我可以确定单击了哪个按钮)我被 EDIT 类项目锁定,并且在读取值时被抛出幸运的第一个猜测。我的问题是:如何从另一个窗口获取控件名称,对于这个任务,我有兴趣了解 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

我查看了 GetWindowLong 和 GetDlgCtrlID API,并尝试了大多数标志,但到目前为止都没有成功......

任何提示,线索,方向表示赞赏。谢谢

4

1 回答 1

0

我做了一个全局鼠标钩子,这不是问题,GetWindowText 和 WM_GETTEXT 工作正常。事实上,该程序在这一点上运行良好且功能正常。在检测到目标窗口后,我使用 EnumChildWindows API 将子窗口句柄保存在列表集合中并仅过滤 EDIT 类窗口(与上面发布的 GetClassValues 函数的修改版本一起使用。此函数的参数是第一个 EDIT 类窗口句柄)。无论如何,我任意访问所需文本框的方式是使用此类窗口的保存列表并通过列表索引访问。正如我之前提到的,幸运的是,windows 以一致的顺序创建 THIS CHILD 窗口。所以,在我的例子中,这个 EDIT 类窗口,文本框“object”,总是在列表中的第一个,尽管主窗口中有很多。

于 2012-10-11T03:31:36.507 回答