Ich habe dieses Problem: Ich habe einen Handler zum Hauptfenster von einer bestimmten Anwendung haben, und ich möchte eine keypress auf diese Anwendung simulieren ...Wie bekomme ich das aktive ChildWindow einer Anwendung?
Ich verwende nachrichts/postmessage api, dies zu tun nennt. Der Grund, warum ich die .Net SendKeys-Funktion oder das keybd_event der Win32-API nicht verwende, ist, dass sie den Tastendruck auf globaler Ebene simulieren. In meinem Fall ist die Zielanwendung nicht die oberste aktive Anwendung (eine andere Anwendung läuft möglicherweise auf einer höheren z-Ebene und deckt somit die Zielanwendung ab).
Das Problem mit sendMessage und postMessage besteht darin, dass Sie den Handler des exakten untergeordneten Fensters übergeben müssen, an dem die Taste gedrückt werden soll. Zum Beispiel in Notepad, wenn ich den Schlüssel an den Handler des Hauptfensters senden, geschieht nichts, ich muss den Schlüssel an den Handler des untergeordneten Fensters, das im Grunde besteht aus der weißen Leinwand, wo Sie schreiben können, senden.
Das Behandeln des aktiven unterordneten Fensters ist das Problem. Am Anfang habe ich die API-Aufrufe GetTopWindow oder GetWindow (GW_CHILD) verwendet, da es das aktivste untergeordnete Fenster zurückgibt. Was ich tat, war, das GetWindow (GW_CHILD) aufzurufen, bis ich ein Childwindow bekam, das keine Childwindows mehr hatte. Dies funktioniert für einige Anwendungen wie Notizblock oder Farbe. In einigen Fällen (wie Firefox zum Beispiel) funktioniert es jedoch nicht. Der Grund dafür ist, dass das übergeordnete Fenster den gesamten Firefox-Bereich hat und sein untergeordnetes Fenster die geöffnete Web-Seite hat (wie Google). Wenn ich nach dem aktivsten untergeordneten Fenster von mainWindow frage, wird das einzige untergeordnete Fenster zurückgegeben, das dem Webpage-Bereich entspricht. Es funktioniert nur, wenn das aktive Fenster dieses ist (wie wenn der Benutzer etwas in ein Textfeld einer bestimmten Seite schreibt). Aber was ist aktiv ist, sagen wir, die Adressleiste, es funktioniert nicht, weil das aktive Fenster nicht das Kind-Fenster ist, sondern das Elternteil ... und ich kann diese Informationen nicht programmatisch bekommen.
Ich fand einen Weg, dies zu tun, den API-Aufruf GetGUIThreadInfo verwenden, mit dem folgenden Code:
// 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);
Und es funktioniert sehr gut: Wenn die Adressleiste aktiv ist, ist es ein „W“ sendet Brief an die Adressleiste. Wenn die Suche TextBox von Google aktiv ist, sendet es den "W" Brief an sie ... Perfekt! Diese Methode kann jedoch nicht von mir aus einem einfachen Grund verwendet werden: Wenn die Zielanwendung nicht das aktive Fenster des Betriebssystems ist, wird die ThreadInfo-Struktur leer. Zum Beispiel, wenn ich Firefox anvisiere, funktioniert es, wenn Firefox aktiv ist (die oberste Anwendung, die fokussierte/aktive), aber wenn, sagen wir, Notepad oben auf Firefox ist, funktioniert es nicht, es kann den aktiven Fensterhandler nicht abrufen.
Ich weiß, dass ich das lösen kann, indem ich den setForegroundWindow-API-Aufruf verwende, um die Zielanwendung zu aktivieren und dann den Handler des aktiven Kindfensters zu erfassen, aber ich wollte die Zielanwendung nicht in den Vordergrund bringen.
Ich habe auch andere Techniken wie AttachThreadInput() und GetFocus() API-Aufrufe versucht, die auch funktioniert, aber das gleiche Problem: Wenn die Zielanwendung nicht die aktive Windows-Anwendung ist, funktioniert es nicht.
Also im Grunde muss ich eine Möglichkeit finden, den Handler zum aktiven untergeordneten Fenster einer Anwendung zu bekommen, auch wenn diese Anwendung nicht die oberste aktive ist.
Irgendwelche Ideen? Dank