private void CreateEditor(string filePath) { //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. //Language services, highlighting and error squiggles are hooked up to these editors //for us once we convert them to WpfTextViews. IVsInvisibleEditor invisibleEditor; ErrorHandler.ThrowOnFailure(_invisibleEditorManager.RegisterInvisibleEditor( filePath , pProject: null , dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING , pFactory: null , ppEditor: out invisibleEditor)); //Then when creating the IVsInvisibleEditor, find and lock the document IntPtr docData; IVsHierarchy hierarchy; var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable)); uint docCookie; ErrorHandler.ThrowOnFailure(runningDocTable.FindAndLockDocument( dwRDTLockType: (uint)_VSRDTFLAGS.RDT_ReadLock, pszMkDocument: filePath, ppHier: out hierarchy, pitemid: out uint itemId, ppunkDocData: out docData, pdwCookie: out docCookie)); IntPtr docDataPointer; var guidIVsTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( fEnsureWritable: 1 , riid: ref guidIVsTextLines , ppDocData: out docDataPointer)); _docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Make Buffer Readonly _docData.GetStateFlags(out uint oldFlags); _docData.SetStateFlags(oldFlags | (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY); //Create a code window adapter _codeWindow = _editorAdapter.CreateVsCodeWindowAdapter(ProfilerPlugin.Instance.OLEServiceProvider); //Disable the splitter control on the editor as leaving it enabled causes a crash if the user //tries to use it here :( IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)_codeWindow; INITVIEW[] initView = new INITVIEW[1]; codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER,// | ((uint)TextViewInitFlags2.VIF_READONLY), VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, szNameAuxUserContext: "", szValueAuxUserContext: "", InitViewFlags: 0, pInitView: initView); ErrorHandler.ThrowOnFailure(_codeWindow.SetBuffer(_docData)); //Get a text view for our editor which we will then use to get the WPF control for that editor. ErrorHandler.ThrowOnFailure(_codeWindow.GetPrimaryView(out _textView)); _textViewHost = _editorAdapter.GetWpfTextViewHost(_textView); }
/// <summary> /// Method to call to cause us to place the file at the given path into our hosted editor. /// </summary> public void SetDisplayedFile(string filePath) { ClearOldEditor(); //Get an invisible editor over the file, this makes it much easier than having to manually figure out the right content type, //language service, and it will automatically associate the document with its owning project, meaning we will get intellisense //in our editor with no extra work. IVsInvisibleEditorManager invisibleEditorManager = (IVsInvisibleEditorManager)GetService(typeof(SVsInvisibleEditorManager)); ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(filePath, pProject: null, dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING, pFactory: null, ppEditor: out this.invisibleEditor)); //The doc data is the IVsTextLines that represents the in-memory version of the file we opened in our invisibe editor, we need //to extract that so that we can create our real (visible) editor. IntPtr docDataPointer = IntPtr.Zero; Guid guidIVSTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(this.invisibleEditor.GetDocData(fEnsureWritable: 1, riid: ref guidIVSTextLines, ppDocData: out docDataPointer)); try { IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Get the component model so we can request the editor adapter factory which we can use to spin up an editor instance. IComponentModel componentModel = (IComponentModel)GetService(typeof(SComponentModel)); IVsEditorAdaptersFactoryService editorAdapterFactoryService = componentModel.GetService <IVsEditorAdaptersFactoryService>(); //Create a code window adapter. this.codeWindow = editorAdapterFactoryService.CreateVsCodeWindowAdapter(OleServiceProvider); //Disable the splitter control on the editor as leaving it enabled causes a crash if the user //tries to use it here :( IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)this.codeWindow; INITVIEW[] initView = new INITVIEW[1]; codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER, VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, szNameAuxUserContext: "", szValueAuxUserContext: "", InitViewFlags: 0, pInitView: initView); //Associate our IVsTextLines with our new code window. ErrorHandler.ThrowOnFailure(this.codeWindow.SetBuffer((IVsTextLines)docData)); //Get our text view for our editor which we will use to get the WPF control that hosts said editor. ErrorHandler.ThrowOnFailure(this.codeWindow.GetPrimaryView(out this.textView)); //Get our WPF host from our text view (from our code window). IWpfTextViewHost textViewHost = editorAdapterFactoryService.GetWpfTextViewHost(this.textView); Debug.Assert(this.control != null); //We already have an open window, so just insert this editor in place of the old one. this.control.InsertNewEditor(textViewHost.HostControl); } finally { if (docDataPointer != IntPtr.Zero) { //Release the doc data from the invisible editor since it gave us a ref-counted copy. Marshal.Release(docDataPointer); } } }
private void CreateVsCodeWindow() { int hr = VSConstants.S_OK; Guid clsidVsCodeWindow = typeof(VsCodeWindowClass).GUID; Guid iidVsCodeWindow = typeof(IVsCodeWindow).GUID; Guid clsidVsTextBuffer = typeof(VsTextBufferClass).GUID; Guid iidVsTextLines = typeof(IVsTextLines).GUID; // create/site a VsTextBuffer object _vsTextBuffer = (IVsTextBuffer)NuoDbVSPackagePackage.Instance.CreateInstance(ref clsidVsTextBuffer, ref iidVsTextLines, typeof(IVsTextBuffer)); IObjectWithSite ows = (IObjectWithSite)_vsTextBuffer; ows.SetSite(_editor); //string strSQL = "select * from sometable"; //hr = _vsTextBuffer.InitializeContent(strSQL, strSQL.Length); switch (NuoDbVSPackagePackage.Instance.GetMajorVStudioVersion()) { case 10: hr = _vsTextBuffer.SetLanguageServiceID(ref GuidList.guidSQLLangSvc_VS2010); break; case 11: hr = _vsTextBuffer.SetLanguageServiceID(ref GuidList.guidSQLLangSvc_VS2012); break; } // create/initialize/site a VsCodeWindow object _vsCodeWindow = (IVsCodeWindow)NuoDbVSPackagePackage.Instance.CreateInstance(ref clsidVsCodeWindow, ref iidVsCodeWindow, typeof(IVsCodeWindow)); INITVIEW[] initView = new INITVIEW[1]; initView[0].fSelectionMargin = 0; initView[0].fWidgetMargin = 0; initView[0].fVirtualSpace = 0; initView[0].fDragDropMove = 1; initView[0].fVirtualSpace = 0; IVsCodeWindowEx vsCodeWindowEx = (IVsCodeWindowEx)_vsCodeWindow; hr = vsCodeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLEDROPDOWNBAR | (uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER, 0, null, null, (uint)TextViewInitFlags.VIF_SET_WIDGET_MARGIN | (uint)TextViewInitFlags.VIF_SET_SELECTION_MARGIN | (uint)TextViewInitFlags.VIF_SET_VIRTUAL_SPACE | (uint)TextViewInitFlags.VIF_SET_DRAGDROPMOVE | (uint)TextViewInitFlags2.VIF_SUPPRESS_STATUS_BAR_UPDATE | (uint)TextViewInitFlags2.VIF_SUPPRESSBORDER | (uint)TextViewInitFlags2.VIF_SUPPRESSTRACKCHANGES | (uint)TextViewInitFlags2.VIF_SUPPRESSTRACKGOBACK, initView); hr = _vsCodeWindow.SetBuffer((IVsTextLines)_vsTextBuffer); IVsWindowPane vsWindowPane = (IVsWindowPane)_vsCodeWindow; hr = vsWindowPane.SetSite(_editor); hr = vsWindowPane.CreatePaneWindow(this.Handle, 0, 0, this.Parent.Size.Width, this.Parent.Size.Height, out _hWndCodeWindow); IVsTextView vsTextView; hr = _vsCodeWindow.GetPrimaryView(out vsTextView); // sink IVsTextViewEvents, so we can determine when a VsCodeWindow object actually has the focus. IConnectionPointContainer connptCntr = (IConnectionPointContainer)vsTextView; Guid riid = typeof(IVsTextViewEvents).GUID; IConnectionPoint cp; connptCntr.FindConnectionPoint(ref riid, out cp); cp.Advise(_editor, out cookie); // sink IVsTextLinesEvents, so we can determine when a VsCodeWindow text has been changed. connptCntr = (IConnectionPointContainer)_vsTextBuffer; riid = typeof(IVsTextLinesEvents).GUID; connptCntr.FindConnectionPoint(ref riid, out cp); cp.Advise(_editor, out cookie); }