実行中の特定のアプリケーションの子ウィンドウにハンドラを取得する必要があります。メインウィンドウハンドラがありますが、SendMessage/PostMessageを使用するには、どの特定の子ウィンドウがアクティブであるかを知る必要があります。フォーカスのないアプリケーションのアクティブなChildWindowを取得する方法は?
私は最終的に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の一番上のウィンドウではないアプリケーションのアクティブな子ウィンドウを取得する他のアイデアを持っていますか?あなたは、プロセスのための最上位のウィンドウハンドルを持っている場合は
おかげ
にそれが動作しないことに注意してくださいアドレスバー – Noyoudont
私は、理由は、firefoxのmainWindowは1つの子供がいると思う。この子はアドレスバーの場所です。しかし、この子どもにも子供がいて、それはGoogleページの場所です。 私は、GetTopWindowは深く働かないと思うので、親ウィンドウ(子孫などではない)の子をチェックするので、常に同じハンドラを返します。 – Noyoudont
@Noyoudont:サンプルのアプローチを参照してください上記。 AttachThreadInputを使用してこの問題を回避しており、おそらくもっと信頼できる方法です。これをC#に翻訳する必要がある場合は、教えてください。 –