简体   繁体   English

如何获取未聚焦的应用程序的活动ChildWindow?

[英]How to get the active ChildWindow of an application that is not focused?

I need to get the Handler to the child Window of a certain application that is running. 我需要将Handler移至正在运行的某个应用程序的子窗口中。 I have the main window handler, but I need to know which specific child window is active, in order to use the SendMessage/PostMessage. 我有主窗口处理程序,但是我需要知道哪个特定的子窗口处于活动状态,以便使用SendMessage / PostMessage。

I finally managed to do this using the following code, using firefox: 我终于使用以下代码通过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);

    }

This works very well! 效果很好! However, if the application is not active, for example, if notepad is covering firefox, the GUIThreadInfo comes with every member null. 但是,如果应用程序处于非活动状态,例如,如果记事本覆盖了Firefox,则GUIThreadInfo的每个成员都为null。 Only if firefox is the top-most (active) application of windows, will the structure be filled. 仅当firefox是Windows最顶层(活动的)应用程序时,结构才会被填充。

I know this could be fixed by bringing firefox to the foreground but I needed to avoid doing this. 我知道可以通过将Firefox放在前台来解决此问题,但我需要避免这样做。 Does anyone have any other idea to get the active child window of an application that is not the top-most window in Windows? 没有人有其他想法来获取不是Windows中最顶层窗口的应用程序的活动子窗口吗?

Thanks 谢谢

If you have the topmost window handle for the process, you should be able to use GetTopWindow to receive the window at the top of the Z order. 如果您拥有该过程的最高窗口句柄,则应该能够使用GetTopWindow来接收Z顺序顶部的窗口。 This should be the window that would be active if the application were set to be the active/current app. 如果将应用程序设置为活动/当前应用程序,则该窗口应为活动窗口。


Edit: 编辑:

What about using AttachThreadInput to attach your thread to the other process thread? 使用AttachThreadInput将线程附加到另一个进程线程该怎么办?

Once you've done that, GetFocus() and PostMessage()/SendMessage() should work. 完成此操作后,GetFocus()和PostMessage()/ SendMessage()应该可以工作。 Just make sure you detach the input when you're done. 只需确保完成后分离输入即可。

The only sample I can find of this is unfortunately in Delphi, but would be easy to translate. 不幸的是, 我能找到的唯一样本是在Delphi中,但翻译起来很容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM