11

私は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 で強制終了します。必ずしも他のアプリを制御できるとは限らないため、ウィンドウにフォーカスを設定するように指示することはできません。

このメソッドは、絶対に必要でない場合は呼び出されません。この場合、敵対的なこの動作は、ユーザーだけでなく自分自身も望んでいることを知っています。

4

1 に答える 1