简体   繁体   English

关闭父级时关闭子级对话框

[英]Close child dialogs when closing the parent

I'm writing a Windows shell extension in C# using EZShellExtensions.NET .我正在使用EZShellExtensions.NET在 C# 中编写 Windows shell 扩展。

I contribute a context menu that shows dialogs.我提供了一个显示对话框的上下文菜单。

Suppose that I show an Explorer window (A).假设我展示了一个 Explorer window (A)。 Then I use the context menu to show non modal window (B).然后我使用上下文菜单显示非模态 window (B)。

In Windows XP and Windows Vista, when I close A, B is closed (I want this behavior).在 Windows XP 和 Windows Vista 中,当我关闭 A 时,B 也关闭(我想要这种行为)。 However, in Windows 7, when I close A, B is not closed but it doesn't respond to events.但是,在 Windows 7 中,当我关闭 A 时,B 没有关闭但它不响应事件。 My questions are:我的问题是:

  • Do you know why Windows 7 manage the showed form as a child form?您知道为什么 Windows 7 将显示的表单作为子表单管理吗?
  • Is there a way to maintain the message loop if I close A?如果我关闭 A,有没有办法维持消息循环?

EDIT : If I set A as owner of B, when I close A, B is also closed.编辑:如果我将 A 设置为 B 的所有者,当我关闭 A 时,B 也会关闭。 But it creates a new issue .但它产生了一个新问题 B is always over A. B总是在A之上。

Finally I have implemented it in the following way.最后我通过以下方式实现了它。 The dialog is shown using ShowDialog() but is launched (and created in a thread).该对话框使用ShowDialog()显示,但已启动(并在线程中创建)。 ShowDialog() implements its own message loop, so as the form is launched in a thread, the main form respond to events, and also you can close the main form and the child form still respond to events. ShowDialog()实现了自己的消息循环,所以当窗体在线程中启动时,主窗体响应事件,也可以关闭主窗体,子窗体仍然响应事件。 This is very useful for a ShellExtension application.这对于 ShellExtension 应用程序非常有用。

Remember dispose all on your form, in order to free the thread, and also the shell extension thread (each shell extension window and childs are executed in a thread).请记住在您的表单上处理所有内容,以便释放线程,以及 shell 扩展线程(每个 shell 扩展 window 和子线程都在一个线程中执行)

The following code fixed my issue:以下代码解决了我的问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM