私はAttachThreadInputを完全に理解するのに少し問題がありました。
2つのスレッドのメッセージキューを「接続」していることはわかっています。これにより、たとえば、ウィンドウ(winforms)をフォアグラウンドに強制できます。
この方法でできること:
private void SetForegroundWindowEx(IntPtr hWnd)
{
uint SW_SHOW = 5;
uint appThread = GetCurrentThreadId();
uint foregroundThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
if (foregroundThread != appThread)
{
AttachThreadInput(foregroundThread, appThread, true);
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
AttachThreadInput(foregroundThread, appThread, false);
}
else
{
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
}
}
ただし、スレッドが切り離されるとすぐに、両方のウィンドウのフォーカスが失われます。
メッセージ キューが空になるのを待って (Application.DoEvents())、ウィンドウをアクティブにすると (フォアグラウンドにあるがフォーカスされていない)、フォーカスを取り戻して保持します。
メッセージキューが空になる前にそれを行うと、再びフォーカスが失われます。
したがって、デタッチの何かがウィンドウからフォーカスを奪うと思いますが、それが何であるか、またはそれを防ぐ方法がわかりません。
これは私がよく理解していない最初のことです。
2番目に得られないのは、ウィンドウをフォアグラウンドに設定しない場合です:
AttachThreadInput(foregroundThread, appThread, true);
AttachThreadInput(foregroundThread, appThread, false);
Application.DoEvents();
this.Activate();
メッセージ キューが空になるのを待って、ウィンドウをアクティブにします (今回はフォアグラウンドではなく、他のウィンドウにまだフォーカスがあります)。スレッドが接続されていなくても、実際にはアクティブになります。
おそらく、AttachThreadInput をよりよく理解している人が、これら 2 つの質問に答えることができます。
情報:
この場合、アプリが API 経由で呼び出されるため、フォーカスを奪う必要があります。私を呼び出す他のアプリは、私のアプリからのフィードバックを待ち、ほとんどの場合、情報を取得するまでフリーズします。
他のアプリがフルスクリーンの場合、多くのユーザーはタスクバーの点滅に気付かず、他のアプリがクラッシュしたと思い、Taskmamanger で強制終了します。必ずしも他のアプリを制御できるとは限らないため、ウィンドウにフォーカスを設定するように指示することはできません。
このメソッドは、絶対に必要でない場合は呼び出されません。この場合、敵対的なこの動作は、ユーザーだけでなく自分自身も望んでいることを知っています。