C# 如何在同一应用程序的所有窗口上显示窗口

C# 如何在同一应用程序的所有窗口上显示窗口,c#,winforms,C#,Winforms,我有一个SplashScreen,应该显示在应用程序中所有其他窗口的前面 由于它是一个飞溅屏幕,因此不能使用模式对话框。相反,这应该通过其他线程来显示 我通过以下方式创建初始屏幕: SplashScreenForm = new SplashScreen(mainForm); // SplashScreenForm.TopMost = true; 为了说明这一点,我使用了这个调用,从另一个线程调用: Application.Run(SplashSc

我有一个SplashScreen,应该显示在应用程序中所有其他窗口的前面

由于它是一个
飞溅屏幕
,因此不能使用模式对话框。相反,这应该通过其他线程来显示

我通过以下方式创建初始屏幕:

            SplashScreenForm = new SplashScreen(mainForm);
            // SplashScreenForm.TopMost = true;
为了说明这一点,我使用了这个调用,从另一个线程调用:

Application.Run(SplashScreenForm);
如果我取消对SplashScreenForm.TopMost=true的注释,则splash将显示在其他窗口的顶部,甚至是属于不同应用程序的窗口的顶部

如果您想知道线程是如何创建的:

    public void ShowSplashScreen()
    {
        SplashScreenThread = new Thread(new ThreadStart(ShowForm));
        SplashScreenThread.IsBackground = true;
        SplashScreenThread.Name = "SplashScreenThread";
        SplashScreenThread.Start();
    }

    private static void ShowForm()
    {
        Application.Run(SplashScreenForm);
    }

如何执行此操作?

您可以尝试从
WinAPI
调用函数
setforegroundindow(HWND)

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

// somewhere in the code :
SetForegroundWindow(SplashScreenForm.Handle);
比如:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    Thread splashThread = new Thread(new ThreadStart(
        delegate
        {
            splashForm = new SplashForm();
            Application.Run(splashForm);
        }
        ));

    splashThread.SetApartmentState(ApartmentState.STA);
    splashThread.Start();

    // Load main form and do lengthy operations
    MainForm mainForm = new MainForm();
    mainForm.Load += new EventHandler(mainForm_Load);
    Application.Run(mainForm);
}
然后,在耗时的操作结束后:

static void mainForm_Load(object sender, EventArgs e)
{
    if (splashForm == null)
        return;
    splashForm.Invoke(new Action(splashForm.Close));
    splashForm.Dispose();
    splashForm = null;
}

这将在主窗体之前启动启动启动屏幕,仅当在
mainForm\u Load

中完成冗长的操作时才会关闭启动屏幕。为什么需要从另一个线程显示此对话框?@RomanoZumbé,因为它应该在主线程加载应用程序时显示(正在加载设备驱动程序、数据库中的一些列表等)。加载应用程序时,启动屏幕应显示加载状态。在gui线程中执行繁重的工作并将实际的gui元素放入另一个线程中,我觉得有点奇怪。为什么不转移Resources的加载(以及您需要做的任何事情)到工作线程并从主线程显示您的闪屏?这种方式不可行。首先,启动操作不能从其他线程进行。其中一些线程,为了使其线程安全,我需要实现一些同步机制。它更复杂。第二,请参阅。在介绍中,它说明了哪些要求闪屏ould meet.我按照文档所说的做了。当你的应用程序完成加载并准备好显示主窗口时,关闭splashscreen不是一种常见的做法吗?我不知道你为什么要关注这个问题-对我来说,你要么打开splashscreen,要么打开应用程序-不是同时打开两者。但是,我已经尝试过了,启动屏幕一开始是显示的,但几乎马上就被隐藏了。我想这是应该的,因为主线程仍然在加载一些东西。这是一个很好的解决方案。这正是我所寻找的。@jstuardo很高兴能提供帮助。您可能想对答案进行投票,以便其他人也能找到它。