如何获取应用程序的活动子窗口?

发布于 2024-07-18 11:25:30 字数 653 浏览 10 评论 0 原文

我想将 pressKey 事件发送到某个应用程序,该应用程序不是 Windows 中的活动应用程序,因此我必须使用 sendMessage/postMessage api 调用。

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

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

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

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

有任何想法吗? 谢谢

I want to send a pressKey event to a certain application which is not the active application IN Windows so I have to use the sendMessage/postMessage api calls.

However, I need to know the exact child window that is active IN the application and send the pressKey message to it...

I was using GetTopWindow and GetWindow(GW_CHILD) api calls to get the top child window of the main window, and do it again with the obtained child window to get the top grandchildWindow, and keep doing it until I found a childwindow with no more childwindows. This works great for some applications but in some cases it doesn't. Sometimes the parent window is the active window, not one of its childwindows, so getting the parent's top child window will not work cause I will be sending a message to the wrong window.

The only way I found of doing this (getting the handler of the actual active window) was using the GuiThreadInfo api call but it only works if the target application is the active one IN Windows. As I mentioned in the beginning, it isn't so the handler comes null.

I can bring the application to the top using setForegroundWindow api call but I DON'T want to do this. I also tried the AttachThreadInput and GetFocus api calls, but again, they only work if the target application is the active application IN windows.

Any ideas? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

握住我的手 2024-07-25 11:25:30

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

我结合了在网上找到的一些东西来解决这个问题,但主要的是这个 一个。 我没有一个很好的应用程序来测试它,但它可以在一个简单的情况下工作。 一个例外是,我认为如果您在应用程序中使用工具窗口,它不会发现它是编码的,因为我认为 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;
    }

I assume from the things that you have tried that you know how to get a handle to your main window, but if you don't just leave a comment and I will post a snippet for that.

I combined a few things that I found on the net to figure this out, but the main one is this one. I don't have a great app to test this with, but it works in a simple case. One exception is that I think if you use tool windows in your application it will not find that as it is coded because I think the GetLastActivePopup method doesn't include them (not sure about that, and didn't test that case).

[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;
    }
欢烬 2024-07-25 11:25:30

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

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

If you know the Window title and the Window class name, take a look at FindWindow() and FindWindowEx() and see if those meet your needs.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文