2015-10-04 41 views
0

我已经创建了IVsInvisibleEditor的一个实例。我用下面的代码来实现这一目标:句法突出显示不适用于IVsInvisibleEditor

public IWpfTextViewHost CreateEditor(string targetFile) 
    { 
     var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)); 
     var editorAdapter = componentModel.GetService<IVsEditorAdaptersFactoryService>(); 
     var editorFactoryService = componentModel.GetService<ITextEditorFactoryService>(); 
     var invisibleEditorManager = (IVsInvisibleEditorManager)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsInvisibleEditorManager)); 

     IVsInvisibleEditor invisibleEditor; 
     ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(
      targetFile, 
      pProject: null, 
      dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING, 
      pFactory: null, 
      ppEditor: out invisibleEditor)); 

     var docDataPointer = IntPtr.Zero; 
     Guid guidIVsTextLines = typeof(IVsTextLines).GUID; 

     ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData(
      fEnsureWritable: 1, 
      riid: ref guidIVsTextLines, 
      ppDocData: out docDataPointer)); 

     //Create a code window adapter 
     IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);   
     var codeWindow = editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider); 
     ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData)); 
     IVsTextView textView; 
     ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView)); 

     var userData = (IVsUserData)codeWindow; 
     var uniqueMoniker = Guid.NewGuid().ToString(); 
     Guid bufferMonikerGuid = typeof(IVsUserData).GUID; 
     userData.SetData(ref bufferMonikerGuid, uniqueMoniker); 
     var guid = VSConstants.VsTextBufferUserDataGuid.VsTextViewRoles_guid; 
     userData.SetData(ref guid, editorFactoryService.CreateTextViewRoleSet(editorFactoryService.DefaultRoles).ToString()); 

     var host = editorAdapter.GetWpfTextViewHost(textView); 
     host.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.ZoomControlId, false); 

     return host; 
    } 

它所有的作品,除了没有语法高亮如果,例如,我使用C#(的.cs)文件,以无形的编辑器中显示。经过一番研究,我发现,我也需要一个文档添加到RDT,我用下面的函数做的:现在

uint RegisterDocument(string targetFile) 
    { 
     //Then when creating the IVsInvisibleEditor, find and lock the document 
     uint itemID; 
     IntPtr docData; 
     uint docCookie; 
     IVsHierarchy hierarchy; 
     var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable)); 

     var result = runningDocTable.FindAndLockDocument(
      dwRDTLockType: (uint)_VSRDTFLAGS.RDT_EditLock, 
      pszMkDocument: targetFile, 
      ppHier: out hierarchy, 
      pitemid: out itemID, 
      ppunkDocData: out docData, 
      pdwCookie: out docCookie); 

     return docCookie; 
    } 

,如果我显示C#文件,然后突出显示(也智能感知作品),但如果我例如显示一个SQL文件,那么我再次没有语法突出显示。现在,我调查得远一点,意识到也许我应该在一个文档附加语言服务,所以我用这个代码来实现这一目标:

 Guid sqlGuid = LanguageServices.Guids.TSQL; 
     docData.SetLanguageServiceID(ref sqlGuid); 

,瞧,它的工作原理,现在语法高亮也在努力上的SQL文件,但现在我有另一个问题,多视图上的SQL文件将无法正常工作。例如,如果我有一个文件MyQuery.sql,并用不可见的编辑器打开它,它将被打开,语法将显示并且一切按预期工作,但现在,如果我尝试打开相同的文件(而不可见编辑器是仍处于打开状态),然后我得到了以下信息:

enter image description here

我相信使用SQL文件时的东西与RDT也不行,看来,当没有附加的语言服务,然后添加到RDT以某种方式忽略,这很奇怪,因为相同的代码适用于C#文件。有没有其他的方式来打开特定的文件(可以是任何类型)使用不可见的编辑器,我错过了什么?

回答

0

在这个问题上花费几天后,我终于发现是什么问题。所以,如果别人也有问题,这里是解释:

创建InvisibleEditor时,“底下”发生了很多事情,应该设置的一件事情也是特定ITextBuffer的ContentType。当使用SQL文件(作为绰号参数RegisterInvisibleEditor方法传递),则contentType设置为纯文本(但在CSHARP文件的情况下,它被设置为CSHARP的ContentType),这显然是错误的,但是,调用:

Guid sqlGuid = LanguageServices.Guids.TSQL; 
    docData.SetLanguageServiceID(ref sqlGuid); 

要解决这个问题,设置语言服务将设置正确的ContentType,但由于某种原因,在我的情况下,并没有工作。经过一些调试后,我发现ContentType在解决方案资源管理器中通过dbl单击打开时与预期的不同。这是“SQL Server工具”的ContentType不是“T-SQL90”,所以,我试图找到GUID,它类型使用IVsTextBuffer的:

 Guid langId; 
     vsTextBuffer.GetLanguageServiceID(out langId); 

这给了我正确的GUID,所以当我的TSQL的语服务所取代,它按预期工作。如果有人需要这些GUID,他们可以在 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \微软\ VisualStudio的\ 10.0 \语言 (取决于VS安装)中找到。

最后,这里是辅助类,这在我以前这些GUID映射:

public static class LanguageServices 
    { 
     public static class Guids 
     { 
      public static Guid VisualBasic = new Guid("E34ACDC0-BAAE-11D0-88BF-00A0C9110049"); 
      public static Guid CSharp = new Guid("694DD9B6-B865-4C5B-AD85-86356E9C88DC"); 
      public static Guid FSharp = new Guid("bc6dd5a5-d4d6-4dab-a00d-a51242dbaf1b"); 
      public static Guid CPlusPlus = new Guid("B2F072B0-ABC1-11D0-9D62-00C04FD9DFD9"); 
      public static Guid Css = new Guid("A764E898-518D-11d2-9A89-00C04F79EFC3"); 
      public static Guid Html = new Guid("58E975A0-F8FE-11D2-A6AE-00104BCC7269"); 
      public static Guid JavaScript = new Guid("59E2F421-410A-4fc9-9803-1F4E79216BE8"); 
      public static Guid TSQL = new Guid("43AF1158-FED5-432e-8E8F-23B6FD592857"); 
      public static Guid SQL = new Guid("ed1a9c1c-d95c-4dc1-8db8-e5a28707a864"); 
      public static Guid Xaml = new Guid("c9164055-039b-4669-832d-f257bd5554d4"); 
      public static Guid Xml = new Guid("f6819a78-a205-47b5-be1c-675b3c7f0b8e"); 
     } 
    }