私はこの問題を持っている:私は、特定のアプリケーションのメインウィンドウへのハンドラを持っている、と私は、そのアプリケーション上のキーの押下をシミュレートしたい...アプリケーションのアクティブChildWindowを取得するにはどうすればよいですか?
私はのsendMessage /のpostMessage APIを使用していますが、これを行うために呼び出します。私が.Net SendKeys関数またはwin32 APIのkeybd_eventを使用しない理由は、それらがグローバルレベルでのキー押しをシミュレートしているからです。私の場合、ターゲットアプリケーションはトップアクティブではありません(他のアプリケーションはより高いzレベルで動作している可能性があり、ターゲットアプリケーションをカバーしている可能性があります)。
sendMessageとpostMessageの問題は、キーを押したい正確な子ウィンドウのハンドラを渡す必要があることです。たとえば、メモ帳でmainWindowのハンドラにキーを送信しても、何も起こりません。子ウィンドウのハンドラにキーを送信する必要があります。子ウィンドウは、基本的に書き込み可能な白いキャンバスから構成されています。
アクティブな子ウィンドウへのハンドラの取得が問題です。最初は、GetTopWindowまたはGetWindow(GW_CHILD)API呼び出しを使用していました。最もアクティブな子ウィンドウが返されるためです。私がやっていたことは、childWindowがなくなるまで、GetWindow(GW_CHILD)を呼び出すことでした。これは、メモ帳やペイントのようなアプリケーションでうまくいきます。しかし、場合によっては(例えばfirefoxのように)、動作しません。その理由は、親ウィンドウにはFirefox全体の領域があり、子ウィンドウには開かれたWebページ(Googleなど)があるからです。したがって、私がmainWindowの中で最もアクティブな子ウィンドウを要求すると、それはWebページ領域に対応する子ウィンドウのみを返します。これは、アクティブなウィンドウがそのウィンドウである場合にのみ機能します(ユーザーが特定のページのテキストボックスに何かを書いている場合など)。しかし、アクティブなウィンドウがアクティブなウィンドウではなく、実際には親ウィンドウであるため、アクティブなウィンドウがアドレスバーで動作しない場合、この情報はプログラムでは取得できません。
私は実際に次のコードを使用して、GetGUIThreadInfo API呼び出しを使用して、これを行う方法を見つけた:
// 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);
をそして、それは非常によく動作します:アドレスバーがアクティブな場合、それは「W」を送信しますアドレスバーへの手紙。 googleの検索テキストボックスがアクティブな場合、それは "W"という文字を送信します...完璧!しかし、この方法は簡単な理由で私には使用できません。 ターゲットアプリケーションがオペレーティングシステムのアクティブなウィンドウでない場合、ThreadInfo構造体は空になります。たとえば、firefoxを対象としている場合、firefoxがアクティブな場合(最上位のアプリケーション、フォーカス/アクティブなもの)は動作しますが、メモ帳がFirefoxの上にある場合、動作しません。アクティブなウィンドウハンドラを取得できません。
私はこれを解決するには、setForegroundWindow API呼び出しを使用してターゲットアプリケーションをアクティブにし、アクティブな子ウィンドウのハンドラを取得することができますが、ターゲットアプリケーションをフォアグラウンドに持ってこないようにしたいと思います。
私はまた、AttachThreadInput()やGetFocus()API呼び出しなどの他のテクニックも試しました。これも動作しますが、同じ問題があります。ターゲットアプリケーションがアクティブなWindowsアプリケーションでない場合、動作しません。
基本的に、そのアプリケーションがアクティブな子ウィンドウでない場合でも、ハンドラをアクティブな子ウィンドウにする方法を見つける必要があります。
アイデア? ありがとう