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

Мне нужно получить обработчик для дочернего окна определенного запущенного приложения. У меня есть обработчик главного окна, но мне нужно знать, какое конкретное дочернее окно активно, чтобы использовать 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);

    }

Это работает очень хорошо! Однако, если приложение не активно, например, если блокнот закрывает firefox, GUIThreadInfo поставляется с каждым элементом null. Только если firefox является самым (активным) приложением окон, структура будет заполнена.

Я знаю, что это можно исправить, выведя firefox на передний план, но мне нужно было избегать этого. У кого-нибудь есть идея получить активное дочернее окно приложения, которое не является самым верхним окном в Windows?

Спасибо

Ответы [ 2 ]

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

Если у вас есть верхний дескриптор окна для процесса, вы сможете использовать GetTopWindow , чтобы получить окно в верхней части Z-порядка. Это должно быть окно, которое будет активным, если приложение было установлено как активное / текущее приложение.


Edit:

Как насчет использования AttachThreadInput для присоединения вашего потока к другому потоку процесса?

Как только вы это сделаете, GetFocus () и PostMessage () / SendMessage () должны работать. Просто убедитесь, что вы отключили вход, когда закончите.

Единственный образец, который я могу найти для этого , к сожалению, в Delphi, но его было бы легко перевести.

0 голосов
/ 07 мая 2009
...