Domanda

Devo portare il gestore nella finestra figlio di una determinata applicazione in esecuzione. Ho il gestore della finestra principale, ma devo sapere quale finestra figlio specifica è attiva, al fine di utilizzare SendMessage / PostMessage.

Finalmente sono riuscito a farlo usando il seguente codice, usando 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);

    }

Funziona molto bene! Tuttavia, se l'applicazione non è attiva, ad esempio, se il blocco note copre firefox, GUIThreadInfo viene fornito con ogni membro null. Solo se Firefox è l'applicazione più attiva (attiva) di Windows, la struttura verrà riempita.

So che questo potrebbe essere risolto portando Firefox in primo piano, ma ho dovuto evitare di farlo. Qualcuno ha un'altra idea per ottenere la finestra figlio attiva di un'applicazione che non è la finestra più in alto in Windows?

Grazie

È stato utile?

Soluzione

Se hai l'handle di finestra più in alto per il processo, dovresti essere in grado di usare GetTopWindow per ricevere la finestra nella parte superiore dell'ordine Z. Questa dovrebbe essere la finestra che sarebbe attiva se l'applicazione fosse impostata come l'app attiva / corrente.


Modifica:

Che dire dell'utilizzo di AttachThreadInput per allegare il tuo thread nell'altro thread di processo?

Una volta fatto, GetFocus () e PostMessage () / SendMessage () dovrebbero funzionare. Assicurati di staccare l'input quando hai finito.

L'unico esempio che posso trovare su questo è purtroppo in Delfi, ma sarebbe facile da tradurre.

Altri suggerimenti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top