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);