如何从多个文本框中获取文本控制另一个程序。C#WM#u GETTEXT
我试图从另一个应用程序中的多个或特定文本框/控件中获取文本 我这里的代码可以工作,它将文本框文本显示为label2.text 但它不是从我需要的文本框中读取值。所有文本框类名都是“WindowsForms10.EDIT.app.0.141b42a_r12_ad1”。那么我如何阅读特定的方框呢 另外请注意,每次重新打开应用程序时,句柄都会更改。但类名不是 如果有任何解决方案,请提供一个示例 谢谢如何从多个文本框中获取文本控制另一个程序。C#WM#u GETTEXT,c#,C#,我试图从另一个应用程序中的多个或特定文本框/控件中获取文本 我这里的代码可以工作,它将文本框文本显示为label2.text 但它不是从我需要的文本框中读取值。所有文本框类名都是“WindowsForms10.EDIT.app.0.141b42a_r12_ad1”。那么我如何阅读特定的方框呢 另外请注意,每次重新打开应用程序时,句柄都会更改。但类名不是 如果有任何解决方案,请提供一个示例 谢谢 IntPtr Hwnd = FindWindow(null, "Software - Name");
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;
在大多数程序中,控件总是以相同的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++;
}
要使用的是控件id。您可以使用Spy++来实现这一点 在程序执行后,转到Visual Studio。在“工具”菜单中是“Spy++”。如果您的系统是64位系统,则需要使用64位版本的Spy++或32位版本的Spy++。转到“搜索”|“查找窗口…”。这将打开一个“查找窗口”对话框。首先,确保程序是可见的;至少是它的相关按钮部分。然后单击“Finder Tool”(查找工具)图标(正方形中有一个圆圈,看起来像一个目标)。按住鼠标按钮,从Finder工具图标拖动到“=”按钮并释放鼠标。“查找窗口”对话框将填充按钮的句柄和其他数据。点击“确定”。然后,您将获得一个“窗口属性”窗口,其中包含一个带有5个选项卡的选项卡控件。这五个选项卡是“常规”、“样式”、“窗口”、“类”和“进程”。在第一个(常规)选项卡底部附近查找“控件ID”。它是一个十六进制值。无论值是什么,每次执行该程序时都可能是该值。在Windows API级别,控件通常由控件id标识。我们可以在程序中使用窗口属性窗口中显示的控件id 您将需要以下内容:
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);
假设“handle”是主窗口句柄,“TextBoxId”是textbox的id,您可以使用以下方法获取textbox的句柄:
IntPtr TextBoxhWnd = GetDlgItem(handle, TextBoxId);
另请参见my。这些窗口类名是自动生成的,每次程序运行时都会更改。所以你不能用它们来识别你想要点击的文本框。长方体相对于其父对象的位置通常是次优方法。但不要这样做,而是使用System.Windows.Automation。每次程序运行时控件id都在更改,这很不幸。通常不会,但这是可能发生的。