1

im looking how to get handle of child window and postmessage there.

My code:

    [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"?

I do some research and i found [pageenumchildwindows][1] but don't know exacly how can i use it in my example.

Screenshoot to see what window exacly am i looking for :

Adam Zbudniewek
  • 107
  • 2
  • 12
  • You can try FindWindowEx. It iterates over the child windows of the parent window. You already get the parent window so pass it to this one and set the name to "Input Capture Window": https://learn.microsoft.com/tr-tr/windows/win32/api/winuser/nf-winuser-findwindowexa – Oguz Ozgul Mar 22 '20 at 10:28
  • Could you write it in answear , how it should looks? With dllimport etc. – Adam Zbudniewek Mar 22 '20 at 10:52
  • I will. I am just trying to have a working POC – Oguz Ozgul Mar 22 '20 at 12:09

2 Answers2

1

OK i found solution thanks to Oguz Ozgul. I did it by FindWindowEx like :

 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!!!");
                        }
                    }
                }
            }
        }
Adam Zbudniewek
  • 107
  • 2
  • 12
1

Here is another implementation, using EnumWindows and EnumChildWindows.

This answer is not meant to be marked, but shows a different approach to the same problem.

It searches for a depth of 3, which can be increased in the code or even can be got as a constructor or method parameter.

It works.

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;
    }
}

And the usage is simple enough:

The second constructor parameter is a pointer to an existing window to search starting from. If you have this handle, you can pass it to narrow the search scope to a specific window and its children.

static void Main()
{
    IntPtr windowFound = new RecursiveWindowSearcher("Skype for Business ", IntPtr.Zero).Find();
    Console.ReadLine();
}
Oguz Ozgul
  • 6,809
  • 1
  • 14
  • 26