2017-02-18 54 views
0

我想從另一個應用程序中的多個或特定文本框/控件中獲取文本。如何從多個文本框中獲取文本控制另一個程序。 C#WM_GETTEXT

我在這裏的代碼有效,它將文本框文本顯示到label2.text中。

但它沒有讀取我需要的文本框中的值。所有的文本框類名都是「WindowsForms10.EDIT.app.0.141b42a_r12_ad1」。那麼如何閱讀特定的框?

另請注意,每次應用程序重新打開時,句柄都會更改。但是班級名稱不。

如果有任何解決方案,樣本會很好。

感謝

IntPtr Hwnd = FindWindow(null, "Software - Name"); 

IntPtr Handle = Marshal.AllocHGlobal(100); 

int NumText = (int)SendMessage(Hwnd, WM_GETTEXT, (IntPtr)50, Handle); 


string Text = Marshal.PtrToStringUni(Handle); 
label1.Text = Text; 

IntPtr ChildHandle = FindWindowEx(Hwnd, IntPtr.Zero, "WindowsForms10.EDIT.app.0.141b42a_r12_ad1", ""); 

IntPtr Hndl = Marshal.AllocHGlobal(200); 


       NumText = (int)SendMessage(ChildHandle, WM_GETTEXT, (IntPtr)200, Hndl); 

      Text = Marshal.PtrToStringUni(Hndl); 

        label2.Text = Text; 
+0

這些窗口類名是自動生成的,每次程序運行時都會更改。所以你不能用它們來識別你想要打的文本框。盒子相對於其父母的位置通常是次佳方法。但不要這樣做,請使用System.Windows。自動化代替。 –

回答

0

在大多數程序中的控件相同Z順序總是佈置。因此,您可以列出所有文本框,按照它們的z順序對它們進行編號,然後再用它來查找它。

此代碼片段將把所有文本框的內容放入label2中。

IntPtr Hwnd = FindWindow(null, "Software - Name"); 

IntPtr Handle = Marshal.AllocHGlobal(100); 

int NumText = (int)SendMessage(Hwnd, WM_GETTEXT, (IntPtr)50, Handle); 

string Text = Marshal.PtrToStringUni(Handle); 
label1.Text = Text; 

IntPtr ChildHandle = IntPtr.Zero; 

label2.Text = ""; 

// Loop through all the textboxes that are children of Hwnd. 
int childNo = 0; 
while ((ChildHandle = FindWindowEx(Hwnd, ChildHandle, "WindowsForms10.EDIT.app.0.141b42a_r12_ad1", "")) != IntPtr.Zero) { 
    IntPtr Hndl = Marshal.AllocHGlobal(200); 

    NumText = (int)SendMessage(ChildHandle, WM_GETTEXT, (IntPtr)200, Hndl); 
    Text = Marshal.PtrToStringUni(Hndl); 
    label2.Text += "(Child Number " + childNo + ") " + Text + Environment.NewLine; 
    Marshal.FreeHGlobal(Hndl); 

    childNo++; 
} 

一旦你想通了你想要的文本具有號碼,您可以更改代碼,使得它僅讀取該文本框中的文本。說,號碼是5,你可以改變while循環是這樣的:

while ((ChildHandle = FindWindowEx(Hwnd, ChildHandle, "WindowsForms10.EDIT.app.0.141b42a_r12_ad1", "")) != IntPtr.Zero) { 
    if (childNo == 5) { 
     IntPtr Hndl = Marshal.AllocHGlobal(200); 

     NumText = (int)SendMessage(ChildHandle, WM_GETTEXT, (IntPtr)200, Hndl); 
     Text = Marshal.PtrToStringUni(Hndl); 
     label2.Text = Text; 
     Marshal.FreeHGlobal(Hndl); 
     break; 
    } 

    childNo++; 
} 
0

使用的東西是控制ID。你可以使用Spy ++來獲取它。

隨着程序執行,轉到Visual Studio。在「工具」菜單中是「Spy ++」。如果您的系統是64位系統,那麼您需要使用64位版本的Spy ++或32位版本使用32位版本。轉到「搜索」| 「查找窗口...」。這將打開一個「查找窗口」對話框。首先,確保程序可見;至少它的相關按鈕部分。然後點擊「Finder Tool」圖標(帶圓圈的正方形看起來像一個目標)。使用鼠標按鈕,從Finder Tool圖標拖動到「=」按鈕並釋放鼠標。查找窗口對話框將填充按鈕的句柄和其他數據。點擊「確定」。然後您將得到一個帶有5個選項卡的選項卡控件的「窗口屬性」窗口。這五個選項卡是常規,樣式,Windows,類和過程。在第一個(常規)選項卡底部附近尋找「控制ID」。它是一個十六進制值。無論價值是什麼,每次執行該程序時可能就是這個價值。在Windows API級別,控件通常由控件ID標識。我們可以使用程序中窗口屬性窗口中顯示的控件ID。

你將需要:

[DllImport("user32.dll")] 
static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem); 

假設「處理」是主窗口句柄和「TextBoxId」是文本框的ID,您可以使用以下方法來獲取文本框的手柄:

IntPtr TextBoxhWnd = GetDlgItem(handle, TextBoxId); 

另請參閱我的Clicking a Button in Another Application

+0

每次程序運行時控件ID都在變化 – yappy

+0

這很不幸。通常它不會但可能發生。 – user34660

相關問題