关闭父级时关闭子对话框

时间:2011-08-09 17:51:13

标签: c# .net winforms shell-extensions

我正在使用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之上。

1 个答案:

答案 0 :(得分:0)

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

请记住在表单上部署所有内容,以释放线程,以及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; }
        }
    }