当ShowInTaskbar = false时,将另一个进程窗口置于前台

时间:2010-04-14 10:53:54

标签: c# winforms

我们只想在任何时候运行一个应用程序实例。因此,在启动时,它会查看应用程序是否正在运行,如果是,则在主窗口上调用 SetForegroundWindow

这一切都很好...... 大部分......

当我们的应用启动时,它会显示启动画面和登录表单。这两种形式都有 ShowInTaskBar = false

因此,如果您在显示登录表单时尝试启动应用程序的另一个副本,则该登录表单不会显示在前面

特别是当用户也无法在任务栏中看到任何内容时,他们认为所有应用程序都是duff且无法启动。没有迹象表明还有另一个实例正在运行。

有没有解决这个问题的方法?

3 个答案:

答案 0 :(得分:47)

嗯,代码就在这里。即使ShowInTaskBarfalse,您也应该能够将其带到前面。

    [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);

    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    public static void bringToFront(string title) {
        // Get a handle to the Calculator application.
        IntPtr handle = FindWindow(null, title);

        // Verify that Calculator is a running process.
        if (handle == IntPtr.Zero) {
            return;
        }

        // Make Calculator the foreground application
        SetForegroundWindow(handle);
    }

注意:您应FindWindow使用表单的类而不是名称,因为启动屏幕表单有时没有标题甚至控件箱。使用Spy ++深入挖掘。

在启动时使用FindWindow。我认为这就是你想要做的事情 - 在加载主表单的同时将闪屏放在前面。

答案 1 :(得分:27)

我认为这是更好的解决方案,因为它可以从最小化状态恢复:

public static class WindowHelper
{
    public static void BringProcessToFront(Process process)
    {
        IntPtr handle = process.MainWindowHandle;
        if (IsIconic(handle))
        {
            ShowWindow(handle, SW_RESTORE);
        }

        SetForegroundWindow(handle);
    }

    const int SW_RESTORE = 9;

    [System.Runtime.InteropServices.DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr handle);
    [System.Runtime.InteropServices.DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
    [System.Runtime.InteropServices.DllImport("User32.dll")]
    private static extern bool IsIconic(IntPtr handle);
}

简单的电话:

WindowHelper.BringProcessToFront(process);

答案 2 :(得分:0)

FindWindow(null, title);

将找到与查询匹配的第一个窗口。如果另一个窗口使用相同的标题,这可能会导致意外行为。

虽然这种情况发生的可能性似乎很少或不可能(单实例应用),但这很容易发生。例如,Windows资源管理器使用所选目录的名称作为窗口标题(尽管不可见)。现在,如果窗口标题是常用术语或与应用程序目录的名称匹配,则这可能是个问题。