views:

582

answers:

2

I've got a shell tray icon with an attached context menu. The problem I'm having is that calling ShowDialog() from a context menu Clicked handler does not result in a modal dialog.

It's easy to reproduce this with a default C# project. Simply add the following code to the Form1.cs file:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    ToolStripMenuItem contextMenuShowMsg = new System.Windows.Forms.ToolStripMenuItem();
    contextMenuShowMsg.Name = "contextMenuShowMsg";
    contextMenuShowMsg.Text = "Show MessageBox...";
    contextMenuShowMsg.Click += new System.EventHandler(this.contextMenuShowMsg_Click);

    ContextMenuStrip contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
    contextMenuStrip.Items.Add(contextMenuShowMsg);

    NotifyIcon notifyIcon = new NotifyIcon();
    notifyIcon.Text = "DlgTest";
    notifyIcon.Icon = SystemIcons.Application;
    notifyIcon.Visible = true;
    notifyIcon.ContextMenuStrip = contextMenuStrip;
}

private void contextMenuShowMsg_Click(object sender, EventArgs e)
{
    MessageBox.Show(this, "Test MessageBox");
}

If you build and run this, you will be able to get two message boxes on the screen by simply choosing the context menu item twice. Shouldn't this be modal? Replacing this with a call to ShowDialog() for another form results in the same non-modal behavior.

My best guess is that the NotifyIcon isn't specifically tied to the Form, as it would be in a typical Windows application. But I don't see any way of doing that.

Any ideas? Thanks in advance for any help!

A: 

I would suggest doing two things before you attempt to display a modal message box:

  1. Make your icon's owner-window visible.
  2. Give it focus.

Once you've done that, the this in the MessageBox.Show becomes a legal "modality parent".

Heck, it even makes more sense that the message box will be displayed on top of whatever program generated it, right? That way, the user has some context for what the message box is about!

scraimer
There are all sorts of reasons why you might want a system tray icon backed by a hidden window - I bet you have more than one in your system tray.The problem is, this is typically handled by Windows for you, since you associate a window (form) with the shell icon in the Shell_NotifyIcon API call. Modality is then enforced. In .NET, I don't see any way to associate a form with the NotifyIcon.
A modal dialog box, is simply a dialog box that prevents the focus from being moved from it to another window in the application. If your window is hidden, that has no meaning. Are you trying to make a "system-wide modal" dialog box? Something that prevents the user from doing *anything* else until he deal with the dialog box?
scraimer
A: 

You will need to keep track of activations of your system tray menu, and disable it when a dialog is open.

Martlark