Hosting Code Editor in Tool Windows


Deploying Visual Studio 2003 managed VSPackages(Reposted here)

Hosting Code Editor in a ToolWindow

         I am pretty sure you have thought about doing this. Come on! I know you have. I had been thinking about implementing it for quite some time now. But one of our resident surgeons Ed Dore beat me to it. Read on and have fun.

 

       Hosting the Visual Studio code editor in a tool window and attaching a language service to it is very simple. The bigger unknown to me is how to hook up intellisense. As soon as I figure it out I will add to this article. If you beat me to that, which I know you can, do post it here.

§          Create the Text Buffer using the ILocalRegistry interface

§          Site the Text Buffer

§          Create the Code Window, to be used as Tool window, using the ILocalRegistry

§          Attach the Text Buffer to the Code Window

§          Create the Tool window using the IVsUIShell::CreateToolWindow

§          Set an appropiate language service for the text buffer

§          Optionally set the Key Bindings to the editor of your choice

 

Sample Code using VB Code Editor in a ToolWindow

// Define the following in Guids.cs file

public static Guid guidVBLangSvc =

   new Guid("{E34ACDC0-BAAE-11D0-88BF-00A0C9110049}");

public static Guid guidCmdUI_TextEditor =

   new Guid("{8B382828-6202-11d1-8870-0000F87579D2}");

 

// Using

using Microsoft.VisualStudio.Shell.Interop;

using OleInterop = Microsoft.VisualStudio.Ole.Interop;

 

Guid guidTextLines = typeof(IVsTextLines).GUID;

Guid guidCodeWindow = typeof(IVsCodeWindow).GUID; ;

Guid guidNull = Guid.Empty;

int[] position = new int[1];

IntPtr objPtr = IntPtr.Zero;

 

// Use ILocalRegistry to create text buffer and code window

ILocalRegistry localRegistry = (ILocalRegistry)GetService(typeof(ILocalRegistry));

Debug.Assert(localRegistry != null, "Unable to retrieve ILocalRegistry");

 

// Create a new text buffer

int hr = localRegistry.CreateInstance(typeof(VsTextBufferClass).GUID, null, ref  

      guidTextLines,                              Microsoft.VisualStudio.NativeMethods.CLSCTX_INPROC_SERVER, out objPtr);

   

Debug.Assert(hr == 0, "Failed to create instance of TextBuffer");

IVsTextLines textLines = Marshal.GetObjectForIUnknown(objPtr) as IVsTextLines;

Marshal.Release(objPtr);

objPtr = IntPtr.Zero;

 

// site it

OleInterop.IServiceProvider sp =

 (OleInterop.IServiceProvider)

  GetService(typeof(OleInterop.IServiceProvider));

 

IObjectWithSite ows = (IObjectWithSite)textLines;

ows.SetSite(sp);

 

// Create a codewindow to use as our toolwindow.

hr = localRegistry.CreateInstance(typeof(VsCodeWindowClass).GUID, 

     null, ref guidCodeWindow,

     Microsoft.VisualStudio.NativeMethods.CLSCTX_INPROC_SERVER,

     out objPtr);

Debug.Assert(hr == 0, "Failed to create instance of

     CodeWindow");

IVsCodeWindow codeWindow =

     Marshal.GetObjectForIUnknown(objPtr) as IVsCodeWindow;

 

Marshal.Release(objPtr);

objPtr = IntPtr.Zero;

 

// Attached codewindow to buffer

codeWindow.SetBuffer(textLines);

 

// Use IVsUIShell::CreateToolWindow to create the frame.

IVsUIShell vsUiShell =  

     (IVsUIShell)GetService(typeof(SVsUIShell));

hr = vsUiShell.CreateToolWindow((uint)

     (__VSCREATETOOLWIN.CTW_fForceCreate),

    0,                                                   codeWindow,

    ref guidNull,                            

    ref guidPersistenceSlot,

    ref guidNull,                            

    null,                                    

    "VB Code Editor ToolWindow",              

    position,

    out windowFrame);

 

if(NativeMethods.Failed(hr))

    return hr;

   

// Make it a VB code window by default

hr = textLines.SetLanguageServiceID(ref GuidList.guidVBLangSvc);

 

// enable editor key bindings

hr =  windowFrame.SetGuidProperty(

      (int)__VSFPROPID.VSFPROPID_InheritKeyBindings,

    ref GuidList.guidCmdUI_TextEditor);

 

 

 

      

 

 

 

 


Comments (6)
  1. Are these all of the steps necessary to deploy a VSIP to a user’s machine or is this just what an individual developer should do on his or her machine to get started writing their own VSIP? I think it’s the former, but wanted to check to be sure.

  2. I am not sure you can hook up intellisense. Assigning language service to the text buffer provides colorization, but that is pretty much it. For example, when you choose Open With… and open HTML file in Text Editor, it still gets colorized even when you don’t see Design and Source tabs. This is because colorizer is still getting invoked. HOWEVER, HTML editor does not gets instantiated. I am sure that HTML editor (that I own) cannot be hosted in a random toolwindow, sorry 🙂 As far as I know, VB intellisense is driven from a compiler parse tree so you’ll have to create a compiler probject, provide all required references and create all required helper objects.

  3. Code Feed says:

    There is a rather timely article about VSIP package deployment on the Microsoft extensibility blog (Dr Ex). Due to some recent Clover.NET experiences I think there are a few additional points to be made. Most of the problems we had…

  4. Cris says:

    Is it possible to do the hosting in .NET as well? Are there any examples available?

    Great article. Congrats.

    Cris

  5. Lukasz says:

    Is there any programatically way to reset package inforations without calling devenv /setup ? The devenv /setup reset any toolbars which sometimes is not what the user want.

Comments are closed.

Skip to main content