如果撤销操作是在文档级别上管理的,那么您可能需要使用RunningDocumentTable来枚举表格、获取它们的撤销管理器并从轨道上摧毁它们:
class NavigateListener: IVsRunningDocTableEvents3
{
private HashSet<IVsTextView> views = new HashSet<IVsTextView>();
private IVsRunningDocumentTable table;
private uint cookie;
...
在外部,称之为注册调用 - 添加一个取消注册调用来取消建议的事件。
public void Register()
{
table =(IVsRunningDocumentTable) Package.GetGlobalService(typeof(SVsRunningDocumentTable));
table.AdviseRunningDocTableEvents(this, out cookie);
}
运行表有很多事件,例如保存等,但您可以监听视图何时被注册:
public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
{
IVsTextView view = VsShellUtilities.GetTextView(pFrame);
if (view != null)
{
views.Add(view);
}
}
您可能会遇到已保存更改但随后被关闭的文档问题...现在先将它们删除...
public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
{
IVsTextView view = VsShellUtilities.GetTextView(pFrame);
if (view != null)
{
views.Remove(view);
}
return VSConstants.S_OK;
}
然后你可以执行超级撤销核弹。我还没有测试这部分 - 你需要自己尝试。
private void NukeFromOrbit()
{
foreach( var view in views )
{
IVsTextLines buffer;
view.GetBuffer(out buffer);
IOleUndoManager manager;
buffer.GetUndoManager(out manager);
IEnumOleUndoUnits units;
manager.EnumUndoable(out units);
uint fetched=0;
var unitArray = new IOleUndoUnit[1];
while( units.Next(1, unitArray , out fetched ) == VSConstants.S_OK)
{
unitArray[0].Do(manager);
}
}
}