9

私はメッセージングツールに取り組んでいます。メッセージング ウィンドウは、アプリケーション全体の一部です。メッセージが来たら、ウィンドウを前面に出す必要があります。私はこのコードを使用しています:

    if( m_hwnd == NULL || !::IsWindow(m_hwnd) )
        return E_UNEXPECTED;

    if(::IsIconic(m_hwnd))
    {
        ::ShowWindowAsync( m_hwnd, SW_RESTORE );
    }
    ::SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    ::SetForegroundWindow(m_hwnd);
    if( pvbProcessed != NULL )
        *pvbProcessed = VARIANT_TRUE;

    return S_OK;

TOPMOST を実行しようとしましたが、それでもうまくいかない場合があります。::BringToFront() も試しました。

なぜそれが機能しないのか、誰でも助けたり説明したりできますか? これはマイクロソフトの既知の制限ですか。

4

2 に答える 2

11

システムは、フォアグラウンド ウィンドウを設定できるプロセスを制限します。プロセスは、次の条件のいずれかに該当する場合にのみ、フォアグラウンド ウィンドウを設定できます。

  • プロセスはフォアグラウンド プロセスです。
  • プロセスはフォアグラウンド プロセスによって開始されました。
  • プロセスは最後の入力イベントを受け取りました。
  • フォアグラウンド プロセスはありません。
  • フォアグラウンド プロセスはデバッグ中です。
  • 前景はロックされていません (LockSetForegroundWindow を参照)。
  • フォアグラウンド ロックのタイムアウトが期限切れになりました (SystemParametersInfo の SPI_GETFOREGROUNDLOCKTIMEOUT を参照)。
  • アクティブなメニューはありません。

詳細については、SetForegroundWindow()ドキュメントを参照してください。

于 2013-10-02T12:04:33.640 に答える
8

Win32 API の公式ドキュメントには、次のようなコメントがあります。

備考 システムは、フォアグラウンド ウィンドウを設定できるプロセスを制限します。プロセスは、次の条件のいずれかに該当する場合にのみ、フォアグラウンド ウィンドウを設定できます。

  • プロセスはフォアグラウンド プロセスです。
  • プロセスはフォアグラウンド プロセスによって開始されました。
  • プロセスは最後の入力イベントを受け取りました。
  • フォアグラウンド プロセスはありません。
  • プロセスはデバッグ中です。
  • フォアグラウンド プロセスは、モダン アプリケーションまたはスタート画面ではありません。
  • 前景はロックされていません (LockSetForegroundWindow を参照)。
  • フォアグラウンド ロックのタイムアウトが期限切れになりました (SystemParametersInfo の SPI_GETFOREGROUNDLOCKTIMEOUT を参照)。
  • アクティブなメニューはありません。

ただし、ウィンドウを強制的に前面に表示するトリックがあります。

トリックは、(AttachThreadInput API を使用して) スレッドをアタッチし、別の API である BringWindowToTop を使用して、プロセスとターゲット ウィンドウ (hwnd) が関連しているとウィンドウに「思わせる」ようにすることです。

void CommonHelpers::forceForegroundWindow(HWND hwnd) {
    DWORD windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(),LPDWORD(0));
    DWORD currentThreadId = GetCurrentThreadId();
    DWORD CONST_SW_SHOW = 5;
    AttachThreadInput(windowThreadProcessId, currentThreadId, true);
    BringWindowToTop(hwnd);
    ShowWindow(hwnd, CONST_SW_SHOW);
    AttachThreadInput(windowThreadProcessId,currentThreadId, false);
}

元の答えはここにあります

PS:また、メッセージが表示された場合にメッセージアプリをトップに表示する必要はないと思いますが、それでも...これは Windows 10 の Qt アプリで機能するソリューションです

于 2020-01-09T07:55:30.723 に答える