Reputation: 4931
I am trying to get a message box to pop up in front of all windows so the user will see it. I have the following code but it seems to put the message box to the very back.
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");
}
The above code is run in a thread is this my problem and how would I fix this?
Thanks
Upvotes: 0
Views: 9372
Reputation: 564323
The best option, in a situation like this, is probably to use P/Invoke to call the MessageBox function directly. You can then include the MB_TOPMOST
flag, which will force this to be a topmost message box. (This is not exposed in the managed API.)
This would be declared as (from pinvoke.net):
[DllImport("coredll.dll", SetLastError=true)]
public static extern int MessageBoxW(int hWnd, String text, String caption, uint type);
Then called as:
MessageBoxW(0, "Topmost Window", "Hello world", 0x00000040L /*MB_ICONINFORMATION*/ | 0x00040000L /*MB_TOPMOST*/);
Upvotes: 3
Reputation: 941218
Yes that's your problem. The form you create will be dead as a doornail, your thread isn't pumping a message loop. Even if you could make it work, you'd still have a significant problem. Pushing a message box in the user's face cannot work reliably. The user will be banging away at, say, a Word document and pressed the space bar just as the message box pops up. To immediately disappear. All that the user notices is a slight flash and a space that's mysteriously missing from the document.
You really ought to use a NotifyIcon to pop up notifications like this. Its ShowBalloonTip method is the standard way to deliver background info.
You could create your own Form class to show something custom. It's important that it doesn't steal the focus to avoid the flash-and-gone problem mentioned above. You'd need to create a dedicated thread to avoid the message loop problem. Something like this:
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();
}
Where frmNotify is the notification form, something like this:
public partial class frmNotify : Form {
public frmNotify(string msg) {
InitializeComponent();
frm.TopMost = true;
label1.Text = msg;
this.ShowWithoutActivation = true;
}
}
Upvotes: 3