如何使用c#引入窗口前景?

时间:2011-02-01 19:44:52

标签: c# winapi window foreground

我正试图带一个窗口前景。我正在使用此代码。但它不起作用。有人可以帮忙吗?

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处理此问题。

取自here的内容 感谢。

6 个答案:

答案 0 :(得分:12)

我之前使用过这种方法:

    [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

答案 1 :(得分: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);
    }

答案 2 :(得分:2)

为了使SetForegroundWindow始终如一地工作,您必须meet a few criteria。第一个是运行命令的进程必须在前台。只有前台进程可以使另一个进程前景。为了使您的过程成为前台,您必须将主窗口置于前面,如果不是。你首先将它最小化,然后将它最小化,然后使它成为前景。现在找到目标流程并将其带到前面

步骤

I've got an example,虽然用例略有不同。

答案 3 :(得分:1)

您应该使用SetForegroundWindow。你也可能感兴趣C# Force Form Focus

答案 4 :(得分:1)

我会简短: Form.BringToFront()

答案 5 :(得分:0)

从Windows 7开始,这些功能的表现并不理想。如果在应用程序前面有一个应用程序(如Excel),那么Windows 7会阻止它并闪烁窗口。您可以在HKEY_CURRENT_USER \ Control Panel \ Desktop中设置注册表超时设置ForegroundLockTimeout = 0,但这些设置称为窃取焦点。要设置XP“应该”的行为以及默认情况下在Windows 7中的行为,您可以创建/设置值为0x00030D40(200000ms)。 我想知道可信Windows应用程序的首选解决方案是什么。例如。如果我在应用程序A中双击某些内容时相信应用程序B需要关注,而其他一些应用程序则模糊了应用程序B的窗口。