【问题标题】:Close child dialogs when closing the parent关闭父级时关闭子级对话框
【发布时间】:2011-08-09 17:51:12
【问题描述】:

我正在使用EZShellExtensions.NET 在 C# 中编写 Windows shell 扩展。

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

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

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

  • 您知道为什么 Windows 7 将显示的表单作为子表单管理吗?
  • 如果我关闭 A,有没有办法维持消息循环?

编辑:如果我将 A 设置为 B 的所有者,当我关闭 A 时,B 也将关闭。但它会创建一个new issue。 B 总是在 A 之上。

【问题讨论】:

    标签: c# .net winforms shell-extensions


    【解决方案1】:

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

    请记住 dispose all 在您的表单上,以便释放线程以及 shell 扩展线程(每个 shell 扩展窗口和子窗口都在一个线程中执行)。

    以下代码解决了我的问题:

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

    【讨论】:

      猜你喜欢
      • 2012-09-02
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多