2009-08-11 10 views
1

Si je montre un MessageBox comme modal d'une fenêtre sur un autre processus, cela fonctionne très bien tant que mon programme continue de répondre. Si elle est fermée ou terminée alors que le MessageBox affiche les fenêtres qui ont reçu le MessageBox sera verrouillé (mais répond toujours) et il devra être finalisé via le Gestionnaire des tâches.Modal MessageBox sur un autre processus 'Handle peut verrouiller la cible Processus

Voici un exemple de code pour démontrer que:

using System; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.Threading; 

namespace TestMessageBox 
{ 
    class Program 
    { 
     private WindowWrapper notepad; 

     Program(IntPtr handle) 
     { 
      notepad = new WindowWrapper(handle); 
     } 

     static void Main(string[] args) 
     { 
      Process[] procs = Process.GetProcessesByName("notepad"); 
      if (procs.Length > 0) 
      { 
       Console.WriteLine("Notepad detected..."); 
       Program program = new Program(procs[0].MainWindowHandle); 
       Thread thread = new Thread(new ThreadStart(program.ShowMessage)); 
       thread.IsBackground = true; 
       thread.Start(); 
       Console.Write("Press any key to end the program and lock notepad..."); 
       Console.ReadKey(); 
      } 
     } 

     void ShowMessage() 
     { 
      MessageBox.Show(notepad, "If this is open when the program ends\nit will lock up notepad..."); 
     } 
    } 

    /// <summary> 
    /// Wrapper class so that we can return an IWin32Window given a hwnd 
    /// </summary> 
    public class WindowWrapper : System.Windows.Forms.IWin32Window 
    { 
     public WindowWrapper(IntPtr handle) 
     { 
      _hwnd = handle; 
     } 
     public IntPtr Handle 
     { 
      get { return _hwnd; } 
     } 
     private IntPtr _hwnd; 
    } 

} 

Comment éviter cela?

Répondre

1

Le fait d'afficher une boîte de dialogue modale désactive la fenêtre parente de la boîte de dialogue (fenêtre du Bloc-notes dans votre exemple). Lorsque la boîte de dialogue modale est fermée, la fenêtre parente est réactivée.

Si votre programme meurt avant de réactiver la fenêtre, cette fenêtre ne sera jamais réactivée - c'est au thread qui affiche la boîte de dialogue de réactiver le parent. (Dans votre exemple, cela se produit dans MessageBox.Show(), après que l'utilisateur clique sur OK ou autre chose.)

La seule façon de faire ce travail serait d'avoir un second processus dont la responsabilité était de remettre les choses à leur place si le processus de création du dialogue modal meurt prématurément, mais c'est horrible. Et ce n'est toujours pas à l'épreuve des balles - que se passe-t-il si le processus d'observation disparaît aussi?

+0

Wow, c'est un mauvais design. Comment un programme externe peut-il verrouiller toutes les fenêtres du système? :( Mon application devra montrer un formulaire modal, et je voulais le rendre à sécurité intégrée, donc si quelque chose arrive à mon application, l'application cible peut continuer son activité ... –

+0

@Luiz: Comment se fait un Le programme externe peut montrer un MessageBox comme le dialogue modal d'une fenêtre sur un autre processus? 8-) Il coupe les deux manières - soit vous avez un système flexible qui vous permet de faire ce que vous faites avec le Bloc-notes, ou vous avez un système plus sûr. Dans ce cas, la question ne se poserait pas. – RichieHindle

+0

@Richie: Ce que je voulais dire, c'est que si un processus n'est plus exécuté, le système d'exploitation devrait être suffisamment intelligent pour savoir que tout verrou provoqué par ses poignées devrait être libéré. Il est différent d'un blocage provoqué par quelque chose qui a cessé de répondre, le processus et son handle n'existe plus. Cela fait longtemps que je n'ai pas eu ma dernière classe d'OS, donc je ne sais pas si c'est possible pour un OS de fonctionner comme ça dans le monde réel ... :( –

Questions connexes