2011-08-09 9 views
6

Estoy escribiendo una extensión de shell de Windows en C# utilizando EZShellExtensions.NET.Cerrar los cuadros de diálogo secundarios al cerrar el elemento primario

Aporto un menú contextual que muestra los cuadros de diálogo.

Supongamos que muestro una ventana del Explorador (A). Luego utilizo el menú contextual para mostrar la ventana no modal (B).

En Windows XP y Windows Vista, cuando cierro A, B se cierra (deseo este comportamiento). Sin embargo, en Windows 7, cuando cierro A, B no está cerrado, pero no responde a los eventos. Mis preguntas son:

  • ¿Sabe por qué Windows 7 administra el formulario mostrado como un formulario secundario?
  • ¿Hay alguna forma de mantener el bucle de mensajes si cierro A?

EDITAR: Si el conjunto A como propietario de B, cuando cierro A, B también está cerrado. Pero crea un new issue. B siempre es más de A.

Respuesta

0

Finalmente lo he implementado de la siguiente manera. El diálogo se muestra usando ShowDialog() pero se inicia (y se crea en un hilo). ShowDialog() implementa su propio bucle de mensajes, de modo que cuando el formulario se inicia en un hilo, el formulario principal responde a los eventos, y también puede cerrar el formulario principal y el formulario secundario aún responder a los eventos. Esto es muy útil para una aplicación ShellExtension.

Recuerde desechar todo en su formulario, para liberar el hilo, y también el hilo de la extensión del caparazón (cada ventana de extensión del caparazón y los elementos secundarios se ejecutan en una secuencia).

el siguiente código fijo mi problema:

protected virtual void SetupViewControl() 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(DoSetupViewControl)); 

     while (!mViewControlCreated) 
     { 
      // wait for view control created 
      Thread.Sleep(100); 
     } 
    } 

    private bool mViewControlCreated = false; 

    protected virtual void DoSetupViewControl(object state) 
    { 
     mViewControl = ViewControlFactory.CreateViewControl(); 

     mViewControl.Dock = DockStyle.Fill; 
     mViewControl.Initialize(); 

     this.Controls.Clear(); 
     this.Controls.Add(mViewControl); 

     IntPtr wHnd = GetActiveWindow(); 
     IWin32Window owner = GetOwner(wHnd); 

     mViewControlCreated = true; 

     ShowDialog(owner); 

     this.Dispose(); 
    } 

    private IWin32Window GetOwner(IntPtr wHnd) 
    { 
     if (wHnd == IntPtr.Zero) return null; 

     return new WindowWrapper(wHnd); 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    private static extern IntPtr GetActiveWindow(); 

    private class WindowWrapper : IWin32Window 
    { 
     private IntPtr mHwnd; 

     public WindowWrapper(IntPtr handle) 
     { 
      mHwnd = handle; 
     } 

     public IntPtr Handle 
     { 
      get { return mHwnd; } 
     } 
    } 
Cuestiones relacionadas