2009-05-07 13 views
0

実行中の特定のアプリケーションの子ウィンドウにハンドラを取得する必要があります。メインウィンドウハンドラがありますが、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の一番上のウィンドウではないアプリケーションのアクティブな子ウィンドウを取得する他のアイデアを持っていますか?あなたは、プロセスのための最上位のウィンドウハンドルを持っている場合は

おかげ

答えて

1

は、あなたはZオーダーの一番上にウィンドウを受信するGetTopWindowを使用することができるはずです。これは、アプリケーションがアクティブ/カレントアプリに設定されている場合にアクティブになるウィンドウです。


編集:

他にどのようなプロセスのスレッドにあなたのスレッドを添付するAttachThreadInputを使用してはどうですか?

これを済ませたら、GetFocus()とPostMessage()/ SendMessage()が動作するはずです。完了したら入力を切り離してください。

The only sample I can find of thisは残念ながらDelphiでは残念ですが、翻訳は簡単です。

+0

にそれが動作しないことに注意してくださいアドレスバー – Noyoudont

+0

私は、理由は、firefoxのmainWindowは1つの子供がいると思う。この子はアドレスバーの場所です。しかし、この子どもにも子供がいて、それはGoogleページの場所です。 私は、GetTopWindowは深く働かないと思うので、親ウィンドウ(子孫などではない)の子をチェックするので、常に同じハンドラを返します。 – Noyoudont

+0

@Noyoudont:サンプルのアプローチを参照してください上記。 AttachThreadInputを使用してこの問題を回避しており、おそらくもっと信頼できる方法です。これをC#に翻訳する必要がある場合は、教えてください。 –

0

GetWindowファンクション(hWnd、GW_CHILD)を使用して子ウィンドウハンドルを取得し、このハンドルにメッセージを投稿することを検討できます。

また、フォーカスがGoogleのページの検索ボックスやと子ウィンドウと子ウィンドウ上にある場合は関係ありません、常に同じハンドラを返し、Microsoft Windows Vista and later. Message posting is subject to User Interface Privilege Isolation (UIPI). The thread of a process can post messages only to message queues of threads in processes of lesser or equal integrity level.

関連する問題