2011-08-09 41 views
6

我正在使用EZShellExtensions.NET在C#中编写Windows外壳扩展。关闭父项时关闭子对话框

我提供了一个显示对话框的上下文菜单。

假设我显示一个资源管理器窗口(A)。然后我使用上下文菜单显示非模态窗口(B)。

在Windows XP和Windows Vista中,当我关闭A时,B关闭(我想要这种行为)。但是,在Windows 7中,当我关闭A时,B未关闭,但它不响应事件。我的问题是:

  • 你知道为什么Windows 7管理显示的表单作为一个孩子的形式吗?
  • 如果关闭A,是否有办法维护消息循环?

EDIT:如果设置A作为B的所有者,当我关闭A,B也被关闭。但它会创建new issue。 B总是结束A.

回答

0

最后我用下面的方法实现它。该对话框使用ShowDialog()显示,但已启动(并在线程中创建)。 ShowDialog()实现了自己的消息循环,因此当表单在线程中启动时,主窗体会响应事件,并且您可以关闭主窗体并且子窗体仍然响应事件。这对于ShellExtension应用程序非常有用。

请记住为了释放线程以及外壳扩展线程(每个外壳扩展窗口和孩子都在一个线程中执行),在表单上全部处理。

下面的代码固定我的问题:

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