Получить дескриптор дочернего окна для почтового сообщения в C# - PullRequest
0 голосов
/ 22 марта 2020

Я смотрю, как получить дескриптор дочернего окна и почтового сообщения там.

Мой код:

    [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] но не знаю точно, как я могу использовать его в моем примере.

Снимок экрана, чтобы увидеть, какое именно окно я ищу:

Ответы [ 2 ]

1 голос
/ 22 марта 2020

Вот еще одна реализация, использующая EnumWindows и EnumChildWindows.

. Этот ответ не предназначен для пометки, но показывает другой подход к той же проблеме.

Поиск для глубины 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;
    }
}

И использование достаточно просто:

Второй параметр конструктора - это указатель на существующее окно для поиска, начиная с. Если у вас есть этот дескриптор, вы можете передать его, чтобы сузить область поиска до указанного c окна и его дочерних элементов.

static void Main()
{
    IntPtr windowFound = new RecursiveWindowSearcher("Skype for Business ", IntPtr.Zero).Find();
    Console.ReadLine();
}
0 голосов
/ 22 марта 2020

ОК, я нашел решение благодаря Огузу Озгулу. Я сделал это 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!!!");
                        }
                    }
                }
            }
        }
...