代码之家  ›  专栏  ›  技术社区  ›  Mongus Pong

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

  •  36
  • Mongus Pong  · 技术社区  · 15 年前

    我们只希望我们的应用程序在同一时间运行一个实例。所以在启动时,它会查看应用程序是否正在运行,如果正在运行,它会调用 设置基础窗口 在主窗口。

    这一切都很好… 在很大程度上…

    当我们的应用程序启动时,它将显示一个启动屏幕和一个登录表单。这两种形式都有 showintaskbar=假 .

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

    尤其是当用户在任务栏中看不到任何东西时,他们所想的是应用程序是无用的,无法启动。没有迹象表明有另一个实例正在运行。

    有办法解决这个问题吗?

    3 回复  |  直到 7 年前
        1
  •  47
  •   Nayan    15 年前

    好吧,密码在这里。即使 ShowInTaskBar false ,你应该可以把它带到前面。

        [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++深入挖掘。

    使用 查找窗口 飞溅。我想这就是你想做的-在加载主窗体时将启动屏幕放在前面。

        2
  •  25
  •   Uwe Keim    7 年前

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

    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);
    
        3
  •  0
  •   a9n    12 年前
    FindWindow(null, title);
    

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

    尽管发生这种情况的可能性看起来很小或不可能(单实例应用程序),但这种情况很容易发生。例如,windows资源管理器使用选定目录的名称作为窗口标题(尽管不可见)。现在,如果窗口标题是一个常用术语或与应用程序目录的名称匹配,这可能是一个问题。