2009-05-07 4 views
0

Ich muss den Handler zum Kind Fenster einer bestimmten Anwendung, die ausgeführt wird. Ich habe den Hauptfenster-Handler, aber ich muss wissen, welches bestimmte untergeordnete Fenster aktiv ist, um SendMessage/PostMessage zu verwenden.Wie bekomme ich das aktive ChildWindow einer Anwendung, die nicht fokussiert ist?

ich es endlich geschafft, dies zu tun, mit dem folgenden Code, mit 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); 

    } 

Das funktioniert sehr gut! Wenn die Anwendung jedoch nicht aktiv ist, z. B. wenn Notepad firefox abdeckt, wird die GUIThreadInfo mit jedem Member als null angezeigt. Nur wenn Firefox die oberste (aktive) Anwendung von Windows ist, wird die Struktur gefüllt.

Ich weiß, das könnte behoben werden, indem firefox in den Vordergrund gebracht, aber ich musste dies vermeiden. Hat jemand eine andere Idee, das aktive untergeordnete Fenster einer Anwendung, die nicht das oberste Fenster in Windows ist, zu erhalten?

Dank

Antwort

1

Wenn Sie das oberste Fenster-Handle für den Prozess haben, sollten Sie in der Lage sein GetTopWindow zu verwenden, um das Fenster am oberen Rand der Z-Reihenfolge zu erhalten. Dies sollte das Fenster sein, das aktiv wäre, wenn die Anwendung als aktive/aktuelle App eingestellt wäre.


Edit:

Was AttachThreadInput mit Ihrem Thread zu dem anderen Prozess Thread zu befestigen?

Sobald Sie das getan haben, sollten GetFocus() und PostMessage()/SendMessage() funktionieren. Stellen Sie nur sicher, dass Sie die Eingabe trennen, wenn Sie fertig sind.

The only sample I can find of this ist leider in Delphi, wäre aber leicht zu übersetzen.

+0

Es ist nicht immer den gleichen Handler liefert nicht funktioniert, egal, ob der Fokus auf dem Kind-Fenster mit dem Suchfeld der Google-Seite oder das Kind Fenster ist mit die Adressleiste – Noyoudont

+0

Ich denke der Grund ist, dass das Hauptfenster von Firefox ein Kind hat. In diesem Kind befindet sich die Adressleiste. Aber dieses Kind hat auch ein Kind, und das ist, wo die Google-Seite ist. Also ich denke, dass das GetTopWindow nicht gründlich arbeitet, überprüft nur die Childs des übergeordneten Fensters (nicht die Enkel, usw.), so dass es immer den gleichen Handler zurückgibt ... – Noyoudont

+0

@Noyoudont: Siehe den Ansatz in der Probe über. Es verwendet AttachThreadInput, um dieses Problem zu umgehen, und ist wahrscheinlich ein viel zuverlässigerer Ansatz. Wenn Sie mich brauchen, um dies in C# zu übersetzen, lassen Sie es mich wissen. –

Verwandte Themen