如何从EnvDTE.Window中获取ITextBuffer?

jus*_*ase 8 c# visual-studio-2010 envdte

我有一个使用新的VS扩展性API的托管语法高亮显示器,它给了我一个ITextBuffer很好的.

在我的扩展的另一部分,我得到一个DTE对象并附加到活动窗口更改事件,这给了我一个EnvDTE.Window对象.

var dte = (EnvDTE.DTE)this.GetService(typeof(EnvDTE.DTE));
dte.Events.WindowEvents.WindowActivated += WindowEvents_WindowActivated;
// ...

private void WindowEvents_WindowActivated(EnvDTE.Window GotFocus, EnvDTE.Window LostFocus)
{
  // ???
  // Profit
}
Run Code Online (Sandbox Code Playgroud)

我想在这个方法中将ITextBuffer从Window中取出.谁能告诉我一个直接的方法呢?

jus*_*ase 10

我使用的解决方案是获取Windows路径,然后将其与IVsEditorAdaptersFactoryServiceand一起使用VsShellUtilities.

var openWindowPath = Path.Combine(window.Document.Path, window.Document.Name);
var buffer = GetBufferAt(openWindowPath);
Run Code Online (Sandbox Code Playgroud)

internal ITextBuffer GetBufferAt(string filePath)
{
  var componentModel = (IComponentModel)GetService(typeof(SComponentModel));
  var editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
  var serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(MetaSharpPackage.OleServiceProvider);

  IVsUIHierarchy uiHierarchy;
  uint itemID;
  IVsWindowFrame windowFrame;
  if (VsShellUtilities.IsDocumentOpen(
    serviceProvider,
    filePath,
    Guid.Empty,
    out uiHierarchy,
    out itemID,
    out windowFrame))
  {
    IVsTextView view = VsShellUtilities.GetTextView(windowFrame);
    IVsTextLines lines;
    if (view.GetBuffer(out lines) == 0)
    {
      var buffer = lines as IVsTextBuffer;
      if (buffer != null)
        return editorAdapterFactoryService.GetDataBuffer(buffer);
    }
  }

  return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 另外,据我所知,嵌入式查看文档窗口没有“IVsWindowFrame”,因此即使文档在运行的文档表中“打开”,“IsDocumentOpen”也会失败。您仍然可以直接使用“IVsRunningDocumentTable”的“FindAndLockDocument”方法获取缓冲区(这是“IsDocumentOpen”在内部调用的方法)。显然,如果您首先有一个“EnvDTE.Window”对象,则这不适用,但如果您只有路径,那么了解这个极端情况很重要。 (2认同)