在双显示器方案中将自动关闭消息框置于应用程序窗口的中心

Posted

技术标签:

【中文标题】在双显示器方案中将自动关闭消息框置于应用程序窗口的中心【英文标题】:centering a self-closing message box in the application window in a two-monitor scenario 【发布时间】:2020-12-27 06:52:00 【问题描述】:

我认为这里的额外皱纹使这个问题与其他中心问题不重复。

我想使用@BSharp given here 的方法来实现自动关闭消息框:

var w = new Form()  Size = new Size(0, 0) ;
Task.Delay(TimeSpan.FromSeconds(10))
    .ContinueWith((t) => w.Close(), TaskScheduler.FromCurrentSynchronizationContext());

MessageBox.Show(w, message, caption);

但是,在我的双显示器设置中,应用程序在右侧显示器上运行,而消息框在左侧显示器上显示。如何让它显示在同一位置但在正确的显示器上?

【问题讨论】:

添加var sc = Screen.FromHandle(this.Handle);确定当前屏幕,然后,例如var w = new Form() Size = new Size(0, 0), StartPosition = FormStartPosition.Manual, Location = new Point([Left], [Top]) ;,其中[Left]和[Top]是根据Screen Bounds计算的。如果您需要它,请参阅此处的注释:Using SetWindowPos with multiple monitors 关于 VirtualScreen 和其他东西(考虑 DpiAwaress 部分)。 你为什么要传入w作为一个新的表单?如果您将程序的主窗口传递给Show(...) 方法,那么消息框应该会自动显示在正确的屏幕上。 @Loathing 主要原因是你必须关闭 Owner Window 才能关闭 MessageBox。您可能不想关闭当前显示的表单。是的,当然还有其他方法,但这很简单:没有 P/Invoking,不是 UI 自动化,在线程计时器中没有风险 SendKeys 等。此外,您可以在任何其他屏幕中显示 MessageBox,无论显示主应用程序表单的位置。 不客气 :) 作为旁注,你不需要设置你从不显示的窗口的大小(无论如何也不会隐藏它):这里重要的是StartPosition = FormStartPosition.Manual ,因此您可以设置特定的Location 【参考方案1】:
private static Form CreateDummyForm(Form mainForm) 
    Form dummy = new Form(); //  Opacity = 0, ShowInTaskbar = false ;
    dummy.Location = mainForm.Location;
    IntPtr hwnd = dummy.Handle; // force handle creation
    mainForm.Load += delegate 
        IntPtr blah = dummy.Handle;
    ;
    mainForm.LocationChanged += delegate 
        dummy.Location = mainForm.Location;
    ;
    return dummy;


[STAThread]
static void Main() 
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Form mf = new Form()  Size = new Size(400, 400) ;
    Button btn = new Button  Text = "Button" ;
    Form dummy = CreateDummyForm(mf);
    btn.Click += delegate 
        Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith((t) =>  dummy.Close(); , TaskScheduler.FromCurrentSynchronizationContext());
        MessageBox.Show(dummy, "blah", "blah", MessageBoxButtons.OKCancel);
        dummy = CreateDummyForm(mf); // Close disposes the dummy form
    ;
    mf.Controls.Add(btn);
    Application.Run(mf);

【讨论】:

以上是关于在双显示器方案中将自动关闭消息框置于应用程序窗口的中心的主要内容,如果未能解决你的问题,请参考以下文章

c#里面如何显示下一个窗体而关闭当前窗体?

MFC,实现消息框自动倒计时的功能...

如何在 WPF 中将 MessageBox 窗口保留在前台

如何在 MS ACCESS 中打开定时消息框而不创建其他窗口

qq好友发过来消息时自动在右下角弹出小窗口怎么设置

在 python 中一段时间​​后关闭 tkmessagebox