繁体   English   中英

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

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

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

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

内容取自此处谢谢。

我以前用过这个方法:

    [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

此代码恢复并将焦点设置到窗口:

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

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

步骤是

我有一个例子 ,虽然这是一个稍微不同的用例。

你应该使用SetForegroundWindow。 对你来说, C#Force Form Focus可能也很有趣

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

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

暂无
暂无

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

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