Boîte de dialog MessageBox parfois cachée derrière le formulaire principal

Certains de nos utilisateurs non techniques rencontrent des problèmes lorsqu’une boîte de dialog MessageBox de notre application peut parfois s’afficher derrière le formulaire principal et que l’application n’accepte aucune entrée jusqu’à ce que la boîte de message (qu’ils ne peuvent pas voir) soit supprimée.

L’application est écrite en C # et les boîtes de message sont standard, par exemple, le code peut être aussi simple que MessageBox.Show (message, légende) et les boîtes de message peuvent être créées par le fil principal de l’interface utilisateur (c’est-à-dire pas par un fil de fond). L’application ne doit pas nécessairement être exécutée en plein écran, mais 90% de nos utilisateurs l’exécutent en plein écran.

La plupart du temps ((peut-être> 99%), les boîtes de messages s’affichent correctement et je n’ai jamais réussi à comprendre comment les choses se passaient mal, mais j’ai vu une machine quand elle a mal tourné.

Une chose que j’ai remarquée est que si vous avez une application qui affiche une boîte de dialog, lorsque vous regardez votre gestionnaire de tâches, vous ne voyez normalement qu’une entrée dans la liste des applications. Chaque fois que la boîte de message est masquée, vous verrez deux entrées, une pour l’application principale et une autre pour cette boîte de message.

Il est assez facile de résoudre le problème une fois que vous savez ce qui s’est passé, mais certains de nos utilisateurs non techniques sont déconcertés et finissent par éteindre leurs ordinateurs. (Et ceux qui utilisent Remote Desktop sont encore plus confus quand cela ne résout pas le problème).

Je ne pense pas que cela soit lié au système d’exploitation, comme je l’ai vu se produire sous Vista et qu’on me dit que cela se produit également lors d’une session de terminal sur un serveur Windows 2003.

Est-ce que quelque chose sait pourquoi cela se produit et surtout si on peut faire quelque chose pour l’éviter?

Certaines surcharges de la méthode MessageBox.Show() prennent un paramètre IWin32Window comme premier argument. Si vous transmettez votre formulaire en tant que premier argument, cela devrait empêcher que cela ne se produise.

Est-ce toujours la même boîte de message (pour le même message?) Venant du même formulaire?

Idéalement, vous devriez essayer de trouver un moyen de reproduire le problème à volonté, ou du moins automatiquement. Cela facilitera votre débogage et vous pourrez alors être sûr que votre future modification aura corrigé le bogue, au lieu d’attendre quelques semaines le retour d’informations de vos utilisateurs.

S’il s’agit toujours du même message et dans la même fenêtre, résultant de la même action, et si l’appel de MessageBox est raisonnablement facile à déclencher du sharepoint vue de l’utilisateur et si votre interface utilisateur est relativement standard, vous pouvez automatiser l’interface utilisateur. avec un script AutoIT et le faire tourner en boucle jusqu’à ce que le problème se produise.

Et / ou, vous pourriez créer un “debug” -build de vos applications que vous pourriez donner à certains utilisateurs (de préférence ceux qui semblent rencontrer le problème le plus souvent) qui écriraient le contenu d’un object StackFrame dans un fichier journal ou quelque chose de similaire à chaque fois avant d’appeler un MessageBox (vous pouvez créer un wrapper autour du MessageBox pour rendre cela plus facile).

Ensuite, lorsqu’un de vos utilisateurs obtient le problème, vous pouvez consulter le fichier journal et voir d’où il provient (fichier de code source, ligne, stack d’appels, etc.). Vous pouvez également comparer cela aux journaux d’autres utilisateurs et voir si, à chaque fois, le MessageBox provient du même emplacement ou s’il varie. Cela vous montrerait d’où la MessageBox problématique est appelée et où.

Il peut y avoir des solutions plus faciles (en particulier si votre application comporte de nombreux assemblages) impliquant un débogueur .Net que vous souhaitez attacher à votre application lorsque le problème survient afin de voir la stack d’appels, etc., mais je ne l’ai fait qu’avec des applications natives. (en utilisant OllyDbg) jusqu’à présent et pas. Net. D’autres pourront peut-être approfondir cette idée …

Confirmez le problème. Pour résoudre ce problème, procédez comme suit: 1. Exécutez une nouvelle tâche et affichez la boîte de message. 2. Dans le thread principal de l’interface utilisateur pendant que la tâche est toujours en cours d’exécution, attendez la boucle créée par DoEvents. Quelque chose comme ça

MISE À JOUR 2015-12-17. Problème reproduit hier. Pour repo dans mon cas – minimiser l’application, une fenêtre contextuelle «attendre» se produit (dans notre cas cela se produit après un temps d’inactivité), puis dans la barre des tâches, cliquez sur l’icône de l’application principale. Ceci “masque” le popup, il n’est donc pas possible de l’afficher à l’écran. Le code ci-dessous a été testé et résout le problème. Mais je ne comprends toujours pas quoi / pourquoi cela se produit.

  private static DialogResult ShowMessageBox( ssortingng message, ssortingng caption, MessageBoxButtons buttons, MessageBoxIcon icon) { var showMessageBoxTask = new Task(() => { var form = new Form() {TopMost = true}; var result = MessageBox.Show( form, PrepareMessage(message), caption, buttons, icon); form.Dispose(); return result; }); showMessageBoxTask.Start(); while (!showMessageBoxTask.IsCompleted && !showMessageBoxTask.IsFaulted) { Application.DoEvents(); } return showMessageBoxTask.Result; } 

Vous dites “les boîtes de message peuvent être créées par le fil principal de l’interface utilisateur”, ce qui, je suppose, signifie qu’elles ne sont pas toujours créées par le fil principal de l’interface utilisateur. Votre problème ressemble à MessageBox.Show est parfois appelé à partir d’un autre thread.

Dans le formulaire parent, ajoutez ceci avant MessageBox.Show ():

this.TopMost = false;