【问题标题】:Get handle of child window to postmessage in C#在 C# 中获取子窗口的句柄以发布消息
【发布时间】:2020-03-22 08:21:15
【问题描述】:

我正在寻找如何获取子窗口的句柄并在那里发布消息。

我的代码:

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        //This send postmessage to window "192.168.0.94 - Remote Desktop Connection"//
        IntPtr hwnd10 = FindWindow(null, "192.168.0.94 - Remote Desktop Connection");
        Point location = new Point(636, 324);
        PostMessage(hwnd10, WM_MOUSEMOVE, 0, MAKELPARAM(location.X, location.Y));
        PostMessage(hwnd10, WM_LBUTTONDOWN, 0x1, MAKELPARAM(location.X, location.Y));
        PostMessage(hwnd10, WM_LBUTTONUP, 0, MAKELPARAM(location.X, location.Y));

        // But now how can i do the same to child window "Input Capture Window"?

我做了一些研究,发现了 [pageenumchildwindows][1],但不知道如何在我的示例中使用它。

截屏看看我在寻找什么窗口:

【问题讨论】:

  • 你可以试试 FindWindowEx。它遍历父窗口的子窗口。您已经获得了父窗口,因此将其传递给此窗口并将名称设置为“输入捕获窗口”:docs.microsoft.com/tr-tr/windows/win32/api/winuser/…
  • 你能把它写在 answear 中吗,它应该是什么样子?使用 dllimport 等。
  • 我会的。我只是想拥有一个有效的 POC

标签: c# rdp postmessage childwindow


【解决方案1】:

好的,感谢 Oguz Ozgul,我找到了解决方案。 我是通过 FindWindowEx 做到的,例如:

 IntPtr child = FindWindowEx(hwnd10, IntPtr.Zero, "TscShellAxHostClass", null);
        //check if window is caught
        if(child!=IntPtr.Zero)
        {
            Console.WriteLine("Findow TscShellAxHostClass found!!!");

            child = FindWindowEx(child, IntPtr.Zero, "ATL:00007FFC92EAF400", null);
            if (child != IntPtr.Zero)
            {
                Console.WriteLine("Findow ATL:00007FFC92EAF400 found!!!");

                child = FindWindowEx(child, IntPtr.Zero, "UIMainClass", null);
                if (child != IntPtr.Zero)
                {

                    Console.WriteLine("Findow UIMainClass found!!!");
                    child = FindWindowEx(child, IntPtr.Zero, "UIContainerClass", null);
                    if (child != IntPtr.Zero)
                    {

                        Console.WriteLine("Findow UIContainerClass found!!!");
                        child = FindWindowEx(child, IntPtr.Zero, "IHWindowClass", null);
                        if (child != IntPtr.Zero)
                        {
                            Console.WriteLine("Findow IHWindowClass found!!!");
                        }
                    }
                }
            }
        }

【讨论】:

  • 很高兴听到这个消息。 :)
【解决方案2】:

这是另一个实现,使用EnumWindowsEnumChildWindows

这个答案并不意味着被标记,而是展示了解决同一问题的不同方法。

搜索深度为3,可以在代码中增加,甚至可以作为构造函数或方法参数获取。

有效。

public class RecursiveWindowSearcher
{
    public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
    [DllImport("user32")]
    public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    private IntPtr windowParent;
    private string windowName;
    private IntPtr windowPointer;

    public RecursiveWindowSearcher(string windowName, IntPtr windowParent)
    {
        this.windowName = windowName;
        this.windowParent = windowParent;
    }

    public bool WinApiCallback(IntPtr hwnd, IntPtr lParam)
    {
        Console.WriteLine("Window: {0}", hwnd);

        StringBuilder windowNameFar = new StringBuilder(256);
        GetWindowText(hwnd, windowNameFar, 256);

        if (windowNameFar.ToString() == windowName)
        {
            windowPointer = hwnd;
            return false;
        }   

        Console.WriteLine("Name: {0}", windowNameFar);

        if(indent == 6)
        {
            return false;
        }
        indent += 2;
        EnumChildWindows(hwnd, WinApiCallback, IntPtr.Zero);
        indent -= 2;

        return true;
    }

    public IntPtr Find()
    {
        this.windowPointer = IntPtr.Zero;
        if (windowParent == IntPtr.Zero)
        {
            EnumWindows(WinApiCallback, 0);
        }
        else
        {
            EnumChildWindows(windowParent, WinApiCallback, IntPtr.Zero);
        }
        return windowPointer;
    }
}

而且用法也很简单:

第二个构造函数参数是一个指向现有窗口的指针。如果您有此句柄,则可以传递它以将搜索范围缩小到特定窗口及其子窗口。

static void Main()
{
    IntPtr windowFound = new RecursiveWindowSearcher("Skype for Business ", IntPtr.Zero).Find();
    Console.ReadLine();
}

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多