8

ウィンドウを前景にしようとしています。私はこのコードを使用しています。しかし、うまくいきません。誰か助けてくれませんか?

ShowWindowAsync(wnd.hWnd, SW_SHOW);

SetForegroundWindow(wnd.hWnd);
// Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
// Converted to Delphi by Ray Lischner
// Published in The Delphi Magazine 55, page 16
// Converted to C# by Kevin Gale
IntPtr foregroundWindow = GetForegroundWindow();
IntPtr Dummy = IntPtr.Zero;

uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy);
uint thisThreadId = GetWindowThreadProcessId(wnd.hWnd, Dummy);

 if (AttachThreadInput(thisThreadId, foregroundThreadId, true))
 {
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack
    SetForegroundWindow(wnd.hWnd);
    AttachThreadInput(thisThreadId, foregroundThreadId, false);
 }

 if (GetForegroundWindow() != wnd.hWnd)
 {
     // Code by Daniel P. Stasinski
     // Converted to C# by Kevin Gale
    IntPtr Timeout = IntPtr.Zero;
    SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0);
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE);
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack
    SetForegroundWindow(wnd.hWnd);
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE);
 }

コードの説明

ウィンドウをフォアグラウンド ウィンドウにするには、SetForegroundWindow API を呼び出すだけでは不十分です。最初にフォアグラウンド スレッドを決定し、AttachThreadInput を使用してそれをウィンドウにアタッチしてから、SetForegroundWindow を呼び出す必要があります。そうすれば、入力状態を共有できます。

まず、GetForegroundWindow を呼び出して、現在のフォアグラウンド ウィンドウのハンドルを取得します。次に、GetWindowThreadProcessId を数回呼び出して、現在のフォアグラウンド ウィンドウに関連付けられているスレッドと、フォアグラウンドに表示するウィンドウを取得します。これらのスレッドが同じ場合は、SetForegroundWindow を呼び出すだけで十分です。そうしないと、フォアグラウンド スレッドが前面に移動するウィンドウにアタッチされ、現在のフォアグラウンド ウィンドウから切り離されます。これは、AttachThreadInput API が処理します。

ここから取得したコンテンツ ありがとうございます。

4

6 に答える 6

14

私は以前にこの方法を使用しました:

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    Process[] processes = Process.GetProcessesByName("processname");
    SetForegroundWindow(processes[0].MainWindowHandle);

詳細: http: //pinvoke.net/default.aspx/user32.SetForegroundWindow

于 2011-02-01T21:12:15.200 に答える
6

このコードは、ウィンドウを復元してフォーカスを設定します。

    [DllImport("User32.dll")]
    static extern int SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam);
    static Int32 WM_SYSCOMMAND = 0x0112;
    static Int32 SC_RESTORE = 0xF120;

そして、次のように使用します。

    var proc = Process.GetProcessesByName("YourProgram").FirstOrDefault();

    if (proc != null)
    {
        var pointer = proc.MainWindowHandle;

        SetForegroundWindow(pointer);
        SendMessage(pointer, WM_SYSCOMMAND, SC_RESTORE, 0);
    }
于 2014-05-13T13:54:15.283 に答える
3

SetForegroundWindow が一貫して機能するためには、いくつかの基準を満たす必要があります。1 つ目は、コマンドを実行するプロセスがフォアグラウンドにある必要があることです。フォアグラウンド プロセスのみが別のプロセスをフォアグラウンドにできます。プロセスを最初にフォアグラウンドにするには、メイン ウィンドウが前面に表示されていない場合は前面に移動する必要があります。最初に最小化してから SetForegroundWindow を実行してフォアグラウンドにします。目的のプロセスを見つけて最前面に持ってきます

手順は次のとおりです。

使用例は少し異なりますが、例があります。

于 2014-12-19T15:57:43.460 に答える
1

簡単に説明します: Form.BringToFront()

于 2011-02-01T20:54:19.457 に答える
1

SetForegroundWindow を使用する必要があります。また、あなたにとっても興味深いかもしれませんC# Force Form Focus

于 2011-02-01T19:58:47.150 に答える
-2

Windows 7の時点では、これらの機能はそれほどうまく動作しません。前面に表示するアプリケーションの前にExcelなどのアプリケーションがある場合、Windows 7はこれをブロックし、ウィンドウをフラッシュします。HKEY_CURRENT_USER \ Control Panel \Desktopでレジストリタイムアウト設定ForegroundLockTimeout=0を設定できますが、これらはフォーカスの盗用と呼ばれます。XPが「すべき」動作を設定し、デフォルトでWindows 7で動作するようにするには、値を0x00030D40(200000ms)に作成/設定します。信頼できるWindowsアプリケーションに適したソリューションを知りたいのですが。例えば。アプリケーションAで何かをダブルクリックしたときに、アプリケーションBがフォーカスを合わせると信頼していて、他のアプリがアプリケーションBのウィンドウを覆い隠している場合。

于 2013-01-25T06:23:30.180 に答える