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

时间:2009-05-07 00:01:24

标签: c# winapi focus keypress childwindow

我需要将Handler放到正在运行的某个应用程序的子窗口中。我有主窗口处理程序,但我需要知道哪个特定的子窗口是活动的,以便使用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);

    }

这非常有效!但是,如果应用程序未处于活动状态,例如,如果notepad覆盖了firefox,则GUIThreadInfo会将每个成员都带为null。只有当firefox是windows的最顶层(活动)应用程序时,才会填充结构。

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

由于

2 个答案:

答案 0 :(得分:1)

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


编辑:

使用AttachThreadInput将线程附加到其他进程线程怎么样?

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

The only sample I can find of this很遗憾在Delphi中,但很容易翻译。

答案 1 :(得分:0)