C#PInvoke从已知窗口中查找子窗口的窗口句柄

本文关键字:窗口 窗口句柄 查找 C#PInvoke | 更新日期: 2023-09-27 17:59:23

我目前正试图通过C#pinvoke使用SendMessage从子窗口获取一些文本。然而,由于应用程序启动时值发生了变化,我之前尝试对窗口句柄进行硬处理时失败了。有没有办法可靠地获取此子窗口的窗口句柄?Winspector spy显示此窗口的类名为RichEdit20W。我当前的代码如下:

IntPtr hWnd= (IntPtr) 0xA0E88; // Hardcode window handle

        int txtlen = SendMessage(hWnd, WM_GETTEXTLENGTH, 20, null);
        StringBuilder text = new StringBuilder(txtlen);
        int RetVal = SendMessage(hWnd, WM_GETTEXT, text.Capacity, text);

C#PInvoke从已知窗口中查找子窗口的窗口句柄

如果可以获得顶级窗口(带有标题栏的窗口),则可以使用FindWindowEx在子窗口中递归。这允许您指定窗口的文本(使用null,因为您不知道)和/或类(您知道)。

http://www.pinvoke.net/default.aspx/user32.findwindowex

我最终使用托管Windows API来枚举该窗口的所有子代窗口。

            var descendantwindows = childWindows[0].AllDescendantWindows; // Get all descendant windows of CMainWindow
        for (int i = 0; i<descendantwindows.Length; i++)
        {
            if (descendantwindows[i].ClassName == "RichEdit20W")
                childHandle = descendantwindows[i].HWnd;
        }

您可以PInvoke API [FindWindow][1]以获得顶级窗口,或者如果您知道进程名称,可以使用:

Process[] processes = Process.GetProcessesByName("yourprocessname");
foreach (Process p in processes)
{
    IntPtr pFoundWindow = p.MainWindowHandle;
    // Do something with the handle...
    //
}

请注意,有更多的条目,因为可能有更多的流程实例同时运行。然后,您需要一些策略来查找顶级子项,以准确地指向您要查找的窗口。