キーボード入力を別のプロセスのウィンドウに送りたいが、そのウィンドウをフォアグラウンドにする必要はない。私はPostMessage
を使ってWM_KEYDOWN
とWM_KEYUP
を偽造することができます。私が知る必要があるのは、どのウィンドウハンドルがキーボード入力を受け取るべきか、つまりGetFocusのようなものですが、別の非アクティブなアプリケーションのためです。P/Invoke経由でGetGUIThreadInfoを呼び出す
GetGUIThreadInfo APIは有望です - 別のアプリ用にhwndFocus
を返します。しかし、私は64ビットOS上でC#を動かすことはできませんでした。私はpinvoke.netからの宣言をコピーしてから調整しましたが、私が返すのはジェネリックエラーコードです(詳細は下記参照)。
私はGetGUIThreadInfoを呼び出す前にcbSizeを設定していますので、最も明らかな潜在的な問題は避けています。
私は64ビットVistaを使用しているため、問題がAPIを正しく使用していないか、または64ビットで動作が異なるかどうかわかりません。具体的にWin64でうまく動作することを示すコードサンプル。
ここにサンプルコードがあります。私はGetWindowThreadProcessId as recommendedを使用していますので、私はこの問題は、スレッドとスレッドIDをハンドル混合に関係しているとは思わない:
[StructLayout(LayoutKind.Sequential)] internal struct Rect { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] internal class GuiThreadInfo { public int cbSize; public uint flags; public IntPtr hwndActive; public IntPtr hwndFocus; public IntPtr hwndCapture; public IntPtr hwndMenuOwner; public IntPtr hwndMoveSize; public IntPtr hwndCaret; public Rect rcCaret; } [DllImport("user32.dll")] internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); [DllImport("user32.dll", SetLastError = true)] internal static extern bool GetGUIThreadInfo(uint idThread, ref GuiThreadInfo lpgui); IntPtr GetFocusedHandleFromProcessWithWindow(IntPtr window) { var threadId = GetWindowThreadProcessId(window, IntPtr.Zero); var info = new GuiThreadInfo(); info.cbSize = Marshal.SizeOf(info); if (!GetGUIThreadInfo(threadId, ref info)) throw new Win32Exception(); return info.hwndFocus; }
window
は、有効なウィンドウハンドルです。 GetWindowThreadProcessId
は、非ゼロのスレッドハンドルを返します。しかし、GetGUIThreadInfo
の呼び出しは常にfalse
を返し、例外メッセージは常に「パラメータが正しくありません」です。
は、念のために問題がGetGUIThreadInfo
は何とか64ビットバージョンを持っていないことを、私は4バイトint
sのGuiThreadInfo
宣言で全て8バイトIntPtr
Sを変える試みたが、私はまだ同じですエラー。
Win64で動作するC#サンプルがGetGUIThreadInfo
の人はいますか?または、そのアプリをアクティブにせずに、別のアプリでフォーカスされた子ウィンドウハンドルを見つける方法がありますか?
あなたは正しい - 私はそれを逃したとは思わない。 礼儀のポイント:これは直近の問題を解決しましたが、別の問題が発生しました。私の最終目標である「他のプロセスに焦点を当てる」はまだ開かれています。この質問を編集するか、この回答を受け入れて新しい質問を書くべきですか? –
この場合、質問は実際にはGetGUIThreadInfoをpInvokingすることです。だから、おそらくそれを参考に投票して回答としてマークするべきです。また、タイトルを編集して、この質問を詳しく説明することもできます。そして、より一般的な問題について新しい質問を追加してください。 –
...あなたの根底にある要件は、これまでに試したことです。一般的には、質問を編集して情報を追加するか、尋ねられている内容を変更しないようにする必要があります。 –