C# 在双监视器场景中,将应用程序窗口中的自动关闭消息框居中

C# 在双监视器场景中,将应用程序窗口中的自动关闭消息框居中,c#,winforms,centering,C#,Winforms,Centering,我认为这里额外的皱纹使这个问题不是其他中心问题的重复 我想使用@BSharp的方法来创建一个自动关闭的消息框: var w = new Form() { Size = new Size(0, 0) }; Task.Delay(TimeSpan.FromSeconds(10)) .ContinueWith((t) => w.Close(), TaskScheduler.FromCurrentSynchronizationContext()); MessageBox.Show(w,

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

我想使用@BSharp的方法来创建一个自动关闭的消息框:

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]根据屏幕边界计算。如果您需要它,请参阅此处的注释:关于虚拟屏幕和其他内容(考虑DpiAwaress部分)。为什么要将
w
作为新表单传递?如果将程序的主窗口传递给
Show(…)
方法,则消息框应自动显示在正确的屏幕上。@令人厌恶的主要原因是您必须关闭所有者窗口才能关闭消息框。您可能不想关闭当前显示的表单。是的,当然还有其他方法,但这相当简单:没有P/调用,没有UI自动化,线程计时器中没有危险的
SendKeys
,等等。此外,您可以在任何其他屏幕上显示MessageBox,无论主应用程序的表单显示在哪里。@Jimi:谢谢您的信息!超级有用。欢迎:)作为旁注,您不需要设置从未显示的窗口的大小(无论如何也不会隐藏它):这里最重要的是
StartPosition=FormStartPosition.Manual
,因此您可以设置特定的
位置
。添加
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]根据屏幕边界计算。如果您需要它,请参阅此处的注释:关于虚拟屏幕和其他内容(考虑DpiAwaress部分)。为什么要将
w
作为新表单传递?如果将程序的主窗口传递给
Show(…)
方法,则消息框应自动显示在正确的屏幕上。@令人厌恶的主要原因是您必须关闭所有者窗口才能关闭消息框。您可能不想关闭当前显示的表单。是的,当然还有其他方法,但这相当简单:没有P/调用,没有UI自动化,线程计时器中没有危险的
SendKeys
,等等。此外,您可以在任何其他屏幕上显示MessageBox,无论主应用程序的表单显示在哪里。@Jimi:谢谢您的信息!超级有用。欢迎:)作为旁注,您不需要设置从未显示的窗口的大小(无论如何也不会隐藏):这里最重要的是
StartPosition=FormStartPosition.Manual
,因此您可以设置特定的
位置。
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);
}