6

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

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

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

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

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

编辑:如果我将 A 设置为 B 的所有者,当我关闭 A 时,B 也会关闭。但它产生了一个新问题。B总是在A之上。

4

1 回答 1

0

最后我通过以下方式实现了它。该对话框显示为使用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; }
        }
    }
于 2011-08-11T08:11:10.813 回答