特別な場合の問題の種類:
System.Diagnostics.Process.Start(..)
でプロセスを開始しますこの時点で、プロセスのUI(またはUIハンドル)を取得する必要があります。プロセスの動作を変更して、これを簡単に(または賢く)することはできないと仮定します。
私はオンラインで見回しましたが、1時間以上探していなかったことを認めます。やや些細なことのようです:-(
Windows APIを使用してもかまわない場合は、 EnumWindowsProc
を使用して、使用して表示される各ハンドルを確認できます。 GetWindowThreadProcessId
(プロセス内にあることを確認するため)、そしておそらくIsWindowVisible
、GetWindowCaption
GetWindowTextLength
を使用して、プロセス内のどのhWnd
が必要かを判断します。
ただし、その前にこれらの関数を使用したことがない場合、そのアプローチは非常に苦痛になります。したがって、もっと簡単な方法があることを願っています。
@ageektrappedは正しい方向に進んでいますが、FindWindow
は子ウィンドウを検索しません。
そのためには、 FindWindowEx
を使用する必要があります
ご回答ありがとうございます。ここでのおかげで、プロセスのメインウィンドウが前面にあるかどうかを知る方法がわかりました。
注:もちろん、これにはSystem.DiagnosticとSystem.Runtime.Interropが必要です。
public bool IsWindowActive(Int32 PID)
{
return IsWindowActive(Process.GetProcessById(PID));
}
[DllImport("user32.dll")]
private static extern
IntPtr GetForegroundWindow();
public bool IsWindowActive(Process proc)
{
proc.Refresh();
return proc.MainWindowHandle.Equals(GetForegroundWindow());
}
.Refresh()を呼び出すと、新しいトップレベルウィンドウが表示される場合があります。
Process.GetProcessById(proc.Id);を使用します。ここで、procはスプラッシュ画面でした。私のために働きます。
では、どのようにしてSystem.Windows.Formsのメインウィンドウのプロパティにアクセスして、win32を使用せずにフォーカスを与えるのでしょうか。結局のところ、.netはワンストップソリューションであるはずです-そうではありませんか?
ウィンドウのタイトルがわかっている場合は、P/Invokeを介してWin32呼び出しのFindWindowを使用できます。
署名はpinvoke.netで見つけることができます ここ
私が理解していることから、開始しているプロセスのMainWindowHandle
プロパティは無効です。その場合は、必要なウィンドウハンドルを返す FindWindow
関数(Win32 SDKから)を使用できます。必要なのは、ターゲットアプリケーションのメインウィンドウのクラス名だけです。 Spy ++または Winspector を使用して取得できます。また、 GetWindowThreadProcessId
を使用してウィンドウのプロセスIDを確認し、正しいウィンドウがあることを確認する必要があります。
最後に、私はWin32の専門家ではないので、あなたのケースにはもっと良い解決策があるかもしれません。
MainWindowHandleプロパティは、最初にアクセスされた後にキャッシュされるため、ハンドルが無効になっても変更されません。 GregUzelacの情報は正しいです。 Proces.Refreshを呼び出すと、次のProcess.MainWindowHandleの呼び出しでロジックが再実行され、新しいメインウィンドウハンドルが検索されます。新しいプロセスにはキャッシュされたバージョンのMainWindowHandleがないため、Michaelのロジックも機能します。
コードのどこかに、「実際の」メインウィンドウが作成されます。その時点でウィンドウハンドルを保存するだけで、スプラッシュ画面が閉じた後、Application.MainWindowを実際のウィンドウに設定できます。