2010-07-29 4 views
0

J'essaie d'obtenir une boîte de message devant toutes les fenêtres afin que l'utilisateur puisse le voir. J'ai le code suivant, mais il semble mettre la boîte de message à l'arrière.Boîte de message devant toutes les fenêtres de l'application console?

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"); 
     } 

Le code ci-dessus est exécuté dans un thread est-ce mon problème et comment puis-je résoudre ce problème?

Merci

+1

[soupir] Ne pas. Aussi important que puisse être votre boîte à message, il n'est pas plus important que ce que l'utilisateur a décidé est l'application la plus importante en ce moment. De plus, si l'utilisateur tape un email par exemple et que votre boîte de message apparaît et vole le focus du clavier, il y a 50% de chances que l'utilisateur fasse quelque chose qu'il regrette plus tard. –

+0

Ceci est le point. L'utilisateur attendra le message contextuel comme ils l'ont invoqué à partir d'une autre application. Merci pour le conseil de toute façon. – arbme

+0

Utilisez FlashWindowEx (http://msdn.microsoft.com/en-us/library/ms679347(VS.85).aspx) au lieu de pousser votre boîte de message vers le haut et de voler le focus du clavier. –

Répondre

3

La meilleure option, dans une telle situation, est probablement d'utiliser P/Invoke pour appeler le MessageBox fonctionner directement. Vous pouvez ensuite inclure l'indicateur MB_TOPMOST, ce qui forcera à être la boîte de message la plus élevée. (. Ce n'est pas exposé dans l'API géré)

Ce serait déclaré (de pinvoke.net):

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

alors appelé comme:

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

Oui c'est votre problème. Le formulaire que vous créez sera mort comme un doornail, votre thread ne pompe pas une boucle de message. Même si vous pouviez le faire fonctionner, vous auriez toujours un problème important. Pousser une boîte de message dans le visage de l'utilisateur ne peut pas fonctionner de manière fiable. L'utilisateur va frapper, par exemple, un document Word et appuyer sur la barre d'espace juste au moment où la boîte de message apparaît. Pour disparaître immédiatement. Tout ce que l'utilisateur remarque est un léger flash et un espace mystérieusement absent du document.

Vous devriez vraiment utiliser un NotifyIcon pour faire apparaître des notifications comme celle-ci. Sa méthode ShowBalloonTip est la manière standard de fournir des informations d'arrière-plan.

Vous pouvez créer votre propre classe Form pour afficher quelque chose de personnalisé. Il est important qu'il ne vole pas le focus pour éviter le problème flash-and-gone mentionné ci-dessus. Vous devez créer un thread dédié pour éviter le problème de boucle de message. Quelque chose comme ceci:

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(); 
    } 

Où frmNotify est la forme de notification, quelque chose comme ceci:

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