0

他のウィンドウからテキスト値を読み取り、その値を別のアプリケーションに照会する必要があります (私の質問は最初のタスクに関するものです)...つまり、他のウィンドウを「スパイ」しています (私たちの製品に関連して使用するサードパーティのアプリケーション) )、「受け入れる」ボタンがクリックされるのを待って、テキストボックスから値を読み取ります。この別のアプリケーションであるダイアログ ボックスには、複数のテキスト ボックスとコマンド ボタンがあります。マウス フックを作成し、このアプリケーションの表示時にアクティブにしています。このウィンドウの四角形内のすべてのマウスの動きを読み取っています。テキスト、キャプション、子ウィンドウ ID、四角形、左/右/中央/ホイール クリックをつかみます。「受け入れる」ボタンのクリックをつかむことができます。ボタンのキャプションを見ることができ、そのウィンドウを読み取ったり、テキストを取得したり、クリックされたボタンを特定したりできます。これで、すべての EDIT クラスの値を読み取り、それらのウィンドウ ハンドルや四角形などを取得できます。しかし、それらをクラス コレクション内の一意のアイテムとして識別できません。目的のテキスト ボックスの値を具体的に読み取る必要があります。幸いなことに、私が興味を持っているテキスト ボックスは、EDIT クラス ループからテキストを読み込んでいるときに、ALWAYS COMES FIRST IN MY LOOP です。ただし、より具体的にしたいと思います。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 は一貫した順序でこの子ウィンドウを作成します。したがって、私の場合、この EDIT クラス ウィンドウ、テキスト ボックス「オブジェクト」は、メイン ウィンドウに多数ありますが、常にリストの最初に表示されます。

于 2012-10-11T03:31:36.507 に答える