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 始终如一地工作,您必须满足一些条件。首先是运行命令的进程必须在前台。只有前台进程才能使另一个进程成为前台。为了使您的进程首先处于前台,如果不是,您必须将主窗口置于最前面。你首先最小化它然后 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 应用程序的首选解决方案是什么。例如。如果我相信应用程序 B 会在我双击应用程序 A 中的某些内容时获得焦点,而其他一些应用程序正在遮挡应用程序 B 的窗口。

于 2013-01-25T06:23:30.180 回答