在使用Windows Ribbon Framework时,无论是直接在C++中使用,还是在.NET环境中通过Windows Ribbon for WinForms库间接使用,经常会遇到一个令人头疼的问题:在ribbon中添加一个关闭按钮,用于关闭应用程序,但应用程序在关闭时却崩溃了。
问题的核心在于,在ribbon命令处理器中调用了ribbon.DestroyFramework,这最终会调用IUIFramework.Destroy。换句话说,在处理ribbon事件的同时,试图销毁ribbon本身。ribbon控制自然不会坐以待毙,它会引发问题。
为了解决这个问题,有两个选择:
第一种方法是异步调用Close()方法。在C#中,代码如下:
void _exitButton_OnExecute(
PropertyKeyRef key,
PropVariantRef currentValue,
IUISimplePropertySet commandExecutionProperties)
{
// 异步关闭窗体,因为处于ribbon事件处理中
// 如果直接调用Close(),最终会调用_ribbon.DestroyFramework()
// 如果ribbon仍在使用中,调用Close()是不合适的
this.BeginInvoke(
new MethodInvoker(
this.Close));
}
第二种方法是在关闭应用程序时不要调用DestroyFramework(并信任Windows来释放资源)。顺便说一句,C++的解决方案是调用PostMessage(WM_CLOSE)而不是SendMessage(WM_CLOSE)。
为了帮助未来的用户,更新了项目网站上的示例04-TabGroupHelp,使其在ribbon上有一个真正的退出按钮,可以关闭窗体。