Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取未聚焦的应用程序的活动子窗口?_C#_Winapi_Focus_Keypress_Childwindow - Fatal编程技术网

C# 如何获取未聚焦的应用程序的活动子窗口?

C# 如何获取未聚焦的应用程序的活动子窗口?,c#,winapi,focus,keypress,childwindow,C#,Winapi,Focus,Keypress,Childwindow,我需要将处理程序转到正在运行的特定应用程序的子窗口。我有主窗口处理程序,但我需要知道哪个特定的子窗口处于活动状态,以便使用SendMessage/PostMessage 我最终通过使用firefox使用以下代码实现了这一点: [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); [DllImport("user32.dll

我需要将处理程序转到正在运行的特定应用程序的子窗口。我有主窗口处理程序,但我需要知道哪个特定的子窗口处于活动状态,以便使用SendMessage/PostMessage

我最终通过使用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);

    }
这个效果很好!但是,如果应用程序未处于活动状态,例如,如果记事本覆盖firefox,则GuitThreadInfo的每个成员都为null。只有当firefox是windows中最活跃的应用程序时,结构才会被填充

我知道把firefox放到前台可以解决这个问题,但我需要避免这样做。是否有人有任何其他想法来获取不是Windows中最顶层窗口的应用程序的活动子窗口


谢谢

如果您拥有流程的最顶部窗口句柄,您应该能够使用接收Z顺序顶部的窗口。如果应用程序设置为活动/当前应用程序,则此窗口应为活动窗口


编辑:

使用将线程附加到另一个进程线程怎么样

完成后,GetFocus()和PostMessage()/SendMessage()应该可以工作。只需确保完成后分离输入即可


在Delphi中很不幸,但很容易翻译。

< p>可以考虑使用函数(HWND,GWSKEY)获取子窗口句柄,并在该句柄上发布消息。


还要注意的是,在

上,它不起作用,总是返回相同的处理程序,不管焦点是位于google页面搜索框中的子窗口还是位于地址中的子窗口,我认为原因是firefox的主窗口只有一个子窗口。这个孩子就是地址栏所在的地方。但是这个孩子也有一个孩子,这就是谷歌页面所在的位置。因此,我认为GetTopWindow不能深入工作,只检查父窗口的子窗口(而不是孙子窗口等),因此它总是返回相同的处理程序…@Noyoudont:参见上面示例中的方法。它使用AttachThreadInput来解决这个问题,这可能是一种更可靠的方法。如果您需要我将其转换为C#,请让我知道。我在该解决方案方面没有取得任何进展,因为不幸的是,它仍然要求应用程序处于活动状态。。。如果我最小化应用程序,或者将另一个应用程序放在前面,GetFocus会返回一个空处理程序=(还有其他想法吗?不是真的-除了可能跟踪当前活动的应用程序,将firefox切换为活动(这样GetFocus就可以工作了),然后再切换回来。我的印象是这样做是可行的,因为将你的线程输入连接到该应用程序基本上会使它处于活动状态,即使它在后台。。。