简体   繁体   English

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

[英]How to bring a window foreground using c#?

I am trying to bring a window foreground. 我试图带一个窗口前景。 I am using this code. 我正在使用此代码。 But its not working. 但它不起作用。 Could someone please help? 有人可以帮忙吗?

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);
 }

Code Explained 代码解释

Making a window the foreground window requires more than just calling the SetForegroundWindow API. 将窗口设置为前景窗口不仅需要调用SetForegroundWindow API。 You must first determine the foreground thread and attach it to your window, using AttachThreadInput, then call SetForegroundWindow. 您必须首先确定前台线程并使用AttachThreadInput将其附加到窗口,然后调用SetForegroundWindow。 That way they can share input states. 这样他们就可以共享输入状态。

First I call GetForegroundWindow to get the handle of the current foreground window. 首先,我调用GetForegroundWindow来获取当前前景窗口的句柄。 Then a few calls to GetWindowThreadProcessId retrieve the threads associated with the current foreground window and the window I want to bring to the foreground. 然后对GetWindowThreadProcessId的一些调用检索与当前前景窗口和我想要带到前台的窗口相关联的线程。 If these threads are the same a simple call to SetForegroundWindow is all that is necessary. 如果这些线程相同,则只需调用SetForegroundWindow就可以了。 Otherwise, the foreground thread is attached to the window that I am bringing to the front and detached from what was the current foreground window. 否则,前台线程将附加到我带到前面的窗口,并与当前前景窗口分离。 The AttachThreadInput API handles this. AttachThreadInput API处理此问题。

Content Taken from here Thanks. 内容取自此处谢谢。

I've used this method before: 我以前用过这个方法:

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

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

More information: http://pinvoke.net/default.aspx/user32.SetForegroundWindow 更多信息: http//pinvoke.net/default.aspx/user32.SetForegroundWindow

This code restores and set focus to a window: 此代码恢复并将焦点设置到窗口:

    [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;

And use it like this: 并像这样使用它:

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

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

        SetForegroundWindow(pointer);
        SendMessage(pointer, WM_SYSCOMMAND, SC_RESTORE, 0);
    }

In order for SetForegroundWindow to work consistently, you have to meet a few criteria . 为了使SetForegroundWindow始终如一地工作,您必须满足一些条件 The first is your process that would run the command must be in the foreground. 第一个是运行命令的进程必须在前台。 Only foreground process can make another process foreground. 只有前台进程可以使另一个进程前景。 In order to make your process foreground first, you have to bring the main window to the front, if it is not. 为了使您的过程成为前台,您必须将主窗口置于前面,如果不是。 You minimise it first and then SetForegroundWindow it, to make it foreground. 你首先将它最小化,然后将它最小化,然后使它成为前景。 Now find the target process and bring it to the front 现在找到目标流程并将其带到前面

The steps are 步骤是

I've got an example , though it's a slightly different use case. 我有一个例子 ,虽然这是一个稍微不同的用例。

You should use SetForegroundWindow. 你应该使用SetForegroundWindow。 Also it may be interesting for you C# Force Form Focus 对你来说, C#Force Form Focus可能也很有趣

我将简要介绍一下: Form.BringToFront()

As of Windows 7 these features dont behave quite so well. 从Windows 7开始,这些功能的表现并不是很好。 If there is an application such as Excel in front of the application you want to bring to the front then Windows 7 blocks this and flashes the window. 如果在应用程序前面有一个应用程序(如Excel),那么Windows 7会阻止它并闪烁窗口。 You can set a registry timeout setting ForegroundLockTimeout=0 in HKEY_CURRENT_USER\\Control Panel\\Desktop but these is known as stealing focus. 您可以在HKEY_CURRENT_USER \\ Control Panel \\ Desktop中设置注册表超时设置ForegroundLockTimeout = 0,但这些设置称为窃取焦点。 To set the behaviour of how XP "should" behave and will behave in Windows 7 by default you can create/set the value to 0x00030D40 (200000ms). 要设置XP“应该”的行为以及默认情况下在Windows 7中的行为,您可以创建/设置值为0x00030D40(200000ms)。 I'd like to know what is the preferred solution for trusted Windows applications. 我想知道可信Windows应用程序的首选解决方案是什么。 eg. 例如。 If I trust application B to take focus when I double click something in Application A, and some other app is obscuring the window of Application B. 当我双击应用程序A中的某些内容时,我相信应用程序B可以获得焦点,而其他一些应用程序则模糊了应用程序B的窗口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM