Как получить активное ChildWindow приложения? - PullRequest
4 голосов
/ 09 мая 2009

Я хочу отправить событие pressKey определенному приложению, которое не является активным приложением в Windows, поэтому я должен использовать API-вызовы sendMessage / postMessage.

Однако мне нужно знать точное дочернее окно, которое активно в приложении, и отправить ему сообщение pressKey ...

Я использовал API-вызовы GetTopWindow и GetWindow (GW_CHILD), чтобы получить верхнее дочернее окно главного окна, и делал это снова с полученным дочерним окном, чтобы получить верхнее grandchildWindow, и продолжал делать это, пока не нашел дочернее окно с нет больше детских окон. Это прекрасно работает для некоторых приложений, но в некоторых случаях это не так. Иногда родительское окно является активным окном, а не одним из его дочерних окон, поэтому получение верхнего дочернего окна родителя не будет работать, потому что я отправлю сообщение не в то окно.

Единственный способ сделать это (получить обработчик действительного активного окна) - использовать вызов API GuiThreadInfo, но он работает, только если целевое приложение является активным в Windows. Как я уже упоминал в начале, обработчик не равен нулю.

Я могу вывести приложение наверх с помощью API-вызова setForegroundWindow, но я НЕ хочу этого делать. Я также попробовал API-вызовы AttachThreadInput и GetFocus, но опять-таки они работают только в том случае, если целевое приложение является активным приложением в окнах.

Есть идеи? Спасибо

Ответы [ 2 ]

1 голос
/ 16 мая 2009

Я предполагаю, что из того, что вы пробовали, вы знаете, как получить указатель на свое главное окно, но если вы не просто оставите комментарий, и я опубликую фрагмент для этого.

Я соединил несколько вещей, которые я нашел в сети, чтобы понять это, но главное - это один . У меня нет отличного приложения, чтобы проверить это, но оно работает в простом случае. Единственным исключением является то, что я думаю, что если вы используете окна инструментов в своем приложении, оно не обнаружит это, поскольку оно закодировано, потому что я думаю, что метод 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;
    }
0 голосов
/ 16 мая 2009

Если вы знаете заголовок 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

...