2012-10-07 61 views
0

我需要从其他窗口读取文本值并将该值查询到另一个应用程序(我的问题将在第一个任务周围)...因此,我正在“窥探”其他窗口(某些第三方第三方应用程序与我们的产品相关),并等待“接受”按钮被点击以从文本框中读取值。这个其他的应用程序,对话框,有多个文本框和命令按钮。 我制作了一个鼠标钩,并在此应用程序外观中激活它。我正在读这个窗口矩形内的所有鼠标移动;文字,标题,儿童窗口ID,矩形,抓取左/右/中/轮点击。我可以抓住“接受”按钮点击;我可以看到按钮标题,我可以阅读该窗口,获取文本,并确定按钮被点击,等等。现在... 我可以阅读所有编辑类的值,获得他们的窗口句柄,矩形等,但我无法识别THEM AS类别集合中的唯一项目:我需要特别阅读我想要的文本框值。幸运的是,当我从EDIT类循环中读取文本时,我感兴趣的文本框总是首先在我的循环中。不过,我想更具体一些;确保我正在阅读带有NAME的文本框。我知道。在开发过程中,我可以读取该名称并在程序中对其进行硬编码。我怀疑是控制名称没有保存在二进制代码中。我的理解是,控制ID,窗口句柄创建窗口创建时,绝对没有控制名称的参考(说:txtOrderNumber)。如果对于按钮我可以是特定的,因为按钮标题(所以,我可以确定按下了哪个按钮)我被EDIT类项锁定,并在读取值时被抛到幸运的第一个猜测。 我的问题是: 如何从另一个窗口获取控件名称,对于我有兴趣了解的关于EDIT类实例名称的此任务。 下面是从项目的一些代码(缩短):从其他窗口控制名称

昏暗的hWnd作为IntPtr的= FindWindow函数(没什么,_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,到目前为止已经试过大部分标志没有成功...

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

+0

“GetWindowText”和“WM_GETTEXT”都不能检索属于不同进程/程序的窗口的文本。它们只有在使用该过程本身时才有效。因此,您需要通过全局挂接(间接)从该进程的上下文中使用它们。 – Jay

+0

我的回复比评论可能适合的时间长。我',发布在主页面。 –

回答

0

我做了一个全局鼠标钩,这不是问题,GetWindowText和WM_GETTEXT工作正常。事实上,该程序在这一点上运行良好且功能正常。 在检测到一个目标窗口时,我使用EnumChildWindows API保存了子窗口句柄,并仅对EDIT类窗口进行过滤(与上面发布的GetClassValues函数的修改版本一起使用)。此函数的参数是第一个EDIT类窗口句柄) 。无论如何,我如何随意访问我想要的文本框的方式是使用此类窗口的保存列表和按列表索引访问。正如我前面提到的,幸运的是,Windows CREATES THIS CHILD窗口的顺序一致。所以,在我的情况下,这个编辑类窗口,文本框“对象”,始终是列表中的第一个,尽管主窗口中有很多。 我想知道文本框“对象”的名称,如前面提到的那样说“txtAccountNumber”...