【问题标题】: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; }
}
}