4

我想向某个不是 Windows 中的活动应用程序的应用程序发送一个 pressKey 事件,所以我必须使用 sendMessage/postMessage api 调用。

但是,我需要知道在应用程序中处于活动状态的确切子窗口并向其发送 pressKey 消息...

我正在使用 GetTopWindow 和 GetWindow(GW_CHILD) api调用来获取主窗口的顶部子窗口,并使用获得的子窗口再次执行以获取顶部的孙子窗口,并继续这样做直到我找到一个没有更多子窗口的子窗口. 这对某些应用程序非常有用,但在某些情况下则不然。有时父窗口是活动窗口,而不是其子窗口之一,因此获取父窗口的顶部子窗口将不起作用,因为我将向错误的窗口发送消息。

我发现这样做的唯一方法(获取实际活动窗口的处理程序)是使用 GuiThreadInfo api 调用,但它仅在目标应用程序是 Windows 中的活动应用程序时才有效。正如我在开头提到的那样,处理程序并非如此。

我可以使用 setForegroundWindow api 调用将应用程序置于顶部,但我不想这样做。我还尝试了 AttachThreadInput 和 GetFocus api 调用,但同样,它们仅在目标应用程序是 Windows 中的活动应用程序时才有效。

有任何想法吗?谢谢

4

2 回答 2

1

我从您尝试过的事情中假设您知道如何获取主窗口的句柄,但如果您不只是发表评论,我会为此发布一个片段。

我结合了我在网上找到的一些东西来解决这个问题,但主要的是这个。我没有一个很好的应用程序来测试它,但它适用于一个简单的案例。一个例外是,我认为如果您在应用程序中使用工具窗口,它不会在编码时发现它,因为我认为 GetLastActivePopup 方法不包括它们(不确定,也没有测试这种情况)。

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll")]
static extern IntPtr GetLastActivePopup(IntPtr hWnd);

[DllImport("user32.dll", ExactSpelling = true)]
static extern IntPtr GetAncestor(IntPtr hwnd, uint gaFlags);

const uint GA_PARENT = 1;
const uint GA_ROOT = 2;
const uint GA_ROOTOWNER = 3;

    public static IntPtr GetAppActiveWindow(IntPtr hwnd)
    {
        IntPtr activeAppWindow = IntPtr.Zero;

        if (hwnd != IntPtr.Zero)
        {
            //Get the root owner window (make sure we are at the app window
            //if you already have a handle to the main window shouldn't have 
            //to do this but I put it in just in case
            hwnd = GetAncestor(hwnd, GA_ROOTOWNER);

            while ((activeAppWindow = 
                      GetLastActivePopup(hwnd)) != activeAppWindow)
            {
                if (IsWindowVisible(activeAppWindow))
                    break;
                hwnd = activeAppWindow;
            }
        }

        return activeAppWindow;
    }
于 2009-05-16T00:22:54.727 回答
0

如果您知道 Window 标题和 Window 类名,请查看 FindWindow() 和 FindWindowEx() 看看它们是否满足您的需求。

FindWindow(): http: //msdn.microsoft.com/en-us/library/ms633499.aspx
FindWindowEx(): http://msdn.microsoft.com/en-us/library/ms633500(VS.85 )。 aspx

于 2009-05-16T01:57:20.490 回答