控制台应用程序中所有窗口前面的消息框?

时间:2010-07-29 16:15:16

标签: c#

我正在尝试在所有窗口前弹出一个消息框,以便用户看到它。我有以下代码,但它似乎把消息框放在后面。

DialogResult dlgResult = MessageBox.Show(new Form() { TopMost = true }, "Do you want to continue?", "Continue?",
            MessageBoxButtons.YesNo, MessageBoxIcon.Question);
        if (dlgResult == DialogResult.Yes)
        {
            Console.WriteLine("YES");
        }
        else if (dlgResult == DialogResult.No)
        {
            Console.WriteLine("NO");
        }

上面的代码是在一个线程中运行的,这是我的问题,我将如何解决这个问题?

由于

2 个答案:

答案 0 :(得分:3)

是的,这是你的问题。你创建的表单将作为一个doornail死,你的线程不会消息循环。即使你可以使它工作,你仍然有一个重大问题。在用户的脸上按消息框无法可靠地工作。用户将敲打一个Word文档并按下空格键,就像弹出消息框一样。立即消失。用户注意到的只是一个轻微的闪光和文档中神秘遗漏的空间。

你真的应该使用NotifyIcon来弹出这样的通知。它的ShowBalloonTip方法是提供背景信息的标准方法。

您可以创建自己的Form类来显示自定义内容。重要的是它不会窃取焦点以避免上面提到的闪光问题。您需要创建专用线程以避免消息循环问题。像这样:

    public static void ShowNotification(string msg) {
        var t = new Thread(() => {
            var frm = new frmNotify(msg);
            frm.TopMost = true;
            var rc = Screen.PrimaryScreen.WorkingArea;
            frm.StartPosition = FormStartPosition.Manual;
            frm.CreateControl();
            frm.Location = new Point(rc.Right - frm.Width, rc.Bottom - frm.Height);
            Application.Run(frm);
        });
        t.SetApartmentState(ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
    }

frmNotify是通知表单,如下所示:

public partial class frmNotify : Form {
    public frmNotify(string msg) {
        InitializeComponent();
        frm.TopMost = true;
        label1.Text = msg;
        this.ShowWithoutActivation = true;
    }
}

答案 1 :(得分:3)

在这种情况下,最好的选择可能是使用P / Invoke直接调用MessageBox函数。然后,您可以包含MB_TOPMOST标志,这将强制它成为最顶层的消息框。 (这不会在托管API中公开。)

这将被声明为(来自pinvoke.net):

[DllImport("coredll.dll", SetLastError=true)]
public static extern int MessageBoxW(int hWnd, String text, String caption, uint type);

然后称为:

MessageBoxW(0, "Topmost Window", "Hello world", 0x00000040L /*MB_ICONINFORMATION*/ | 0x00040000L /*MB_TOPMOST*/);