简体   繁体   English

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

[英]How do I get the active ChildWindow of an application?

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. 我想将一个pressKey事件发送到某个应用程序,该应用程序不是Windows中的活动应用程序,因此我必须使用sendMessage / postMessage api调用。

However, I need to know the exact child window that is active IN the application and send the pressKey message to it... 但是,我需要知道在应用程序中处于活动状态的确切子窗口并向其发送pressKey消息...

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. 我正在使用GetTopWindow和GetWindow(GW_CHILD)api调用来获取主窗口的顶级子窗口,并使用获取的子窗口再次执行以获取顶级孙子窗口,并继续执行它直到我找到没有更多子窗口的子窗口。 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. 我发现这样做的唯一方法(获取实际活动窗口的处理程序)是使用GuiThreadInfo api调用,但它仅在目标应用程序是活动的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. 我可以使用setForegroundWindow api调用将应用程序带到顶部,但我不想这样做。 I also tried the AttachThreadInput and GetFocus api calls, but again, they only work if the target application is the active application IN windows. 我还尝试了AttachThreadInput和GetFocus api调用,但同样,它们仅在目标应用程序是活动应用程序IN窗口时才有效。

Any ideas? 有任何想法吗? Thanks 谢谢

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). 一个例外是,我认为如果你在你的应用程序中使用工具窗口它将不会找到它,因为我认为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;
    }

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. 如果您知道Window标题和Window类名,请查看FindWindow()和FindWindowEx(),看看它们是否符合您的需求。

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

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

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