2011-08-09 91 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; } 
     } 
    }