如何从多个文本框中获取文本控制另一个程序。 C#WM_GETTEXT

时间:2017-02-18 13:49:38

标签: c#

我正在尝试从其他应用程序中的多个或特定文本框/控件中获取文本。

我在这里使用的代码工作,它将文本框文本显示为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;

2 个答案:

答案 0 :(得分: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++;
}

答案 1 :(得分:0)

使用的是控件 id 。你可以使用Spy ++来实现它。

执行程序后,转到Visual Studio。在"工具"菜单是" Spy ++"。如果您的系统是64位系统,那么您需要使用64位版本的Spy ++或32位版本使用32位版本。转到"搜索" | "查找窗口..."。这将打开一个"查找窗口"对话。首先,确保程序可见;至少它的相关按钮部分。然后点击" Finder工具"图标(在其中看起来像目标的圆圈的方形)。按下鼠标按钮,从Finder工具图标拖动到" ="按钮并释放鼠标。将使用按钮的句柄和其他数据填充“查找窗口”对话框。点击"确定"。然后,您将获得一个"窗口属性"带有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