How do I get the active ChildWindow of an application that is not focused?

I need to get a handler for a child window of a specific application that is running. I have a main window handler, but I need to know which specific child window is active in order to use SendMessage / PostMessage.

I was able to do it using the following code using firefox:

    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

    [DllImport("user32.dll", EntryPoint = "GetGUIThreadInfo")]
    internal static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO threadInfo);


    private void button1_Click(object sender, EventArgs e)
    {
        //start firefox
        firefox = new Process();
        firefox.StartInfo.FileName = @"C:\Program Files\Mozilla Firefox\firefox.exe";
        firefox.Start();
        Thread.Sleep(10000);

        // get thread of the main window handle of the process
        var threadId = GetWindowThreadProcessId(firefox.MainWindowHandle, IntPtr.Zero);

        // get gui info
        var info = new GUITHREADINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        if (!GetGUIThreadInfo(threadId, out info))
            throw new Win32Exception();


        // send the letter W to the active window
        PostMessage(info.hwndActive, WM_KEYDOWN, (IntPtr)Keys.W, IntPtr.Zero);

    }

      

It works really well! However, if the app is inactive, for example if notepad covers firefox, the GUIThreadInfo contains each element null. Only if firefox is the topmost (active) windows app will the outline be filled.

I know this could be fixed by putting firefox in the foreground, but I needed to avoid that. Does anyone have any other idea to get an active child window of an application that is not the topmost window on Windows?

thanks

0


a source to share


2 answers


Once you have the topmost window handle for the process, you can use GetTopWindow to get the window at the top of the Z order. This should be the window that will be active if the application was set as active / current application.


Edit:



How about using AttachThreadInput to attach a thread to another process?

Once you've done that, GetFocus () and PostMessage () / SendMessage () should work. Just make sure you disconnect the input when you're done.

The only sample I can find from this is unfortunately in Delphi, but easy to translate.

+1


a source


You might consider creating a handle to the child window using the GetWindow (hWnd, GW_CHILD) function and send a message to that handle.



Also keep in mind that on Microsoft Windows Vista and later. The post is hosted under a user interface license (UIPI). A process thread can only send messages to thread message queues in processes with less or equal integrity.

0


a source







All Articles