Using Visual Studio Editor Services in a legacy Non-MEF Component
I have multiple VS Extensions originally written in VS 2008. I have successfully upgraded the solutions to VS 2019 and to the latest NuGet packages and everything works except for one item. We have an editor with multiple panes. 2 of 3 panes load correctly, but one doesn't and it is a code editor pane. It remains a black area that won't even accept focus. The code runs without error (other than not displaying the pane as it should).
It is also supposed to use our custom language extension for syntax highlighting and intellisense. The language extension works on its own if you just open a code file with the specified extension/type. But even without specifying that the code pane use our language extension, the pane won't load and show the text. So I don't think that part is the problem (yet).
Since this is a legacy project, I've tried following this document: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/extensibility/adapting-legacy-code-to-the-editor?view=vs-2015. Specifically, the last section adapting-legacy-code-to-the-editor.
Our relevant code is below. What are we doing wrong and/or missing?
private void CreateVsCodeWindow()
{
try
{
ThreadHelper.ThrowIfNotOnUIThread();
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;
IComponentModel _compModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
IOleServiceProvider _OleSvcProvider = (IOleServiceProvider)Package.GetGlobalService(typeof(IOleServiceProvider));
IVsEditorAdaptersFactoryService ivsEditorAdaptersFactoryService = _compModel.GetService<IVsEditorAdaptersFactoryService>();
ITextBufferFactoryService textBufferFactoryService = _compModel.GetService<ITextBufferFactoryService>();
//commented out here because this is trying to use our custom language service, but with or with it, the code window doesn't load correctly.
//IContentTypeRegistryService contentTypeRegSvc = _compModel.GetService<IContentTypeRegistryService>();
//IContentType contentTypeFLD = contentTypeRegSvc.GetContentType("CryLanguage");
// create/site a VsTextBuffer object
IVsTextBuffer vsTextBufferAdapter = ivsEditorAdaptersFactoryService.CreateVsTextBufferAdapter(_OleSvcProvider);//, contentTypeFLD);
//IVsTextBuffer vsTextBuffer = (IVsTextBuffer)VSPackage.Instance.CreateInstance(ref clsidVsTextBuffer, ref iidVsTextLines, typeof(IVsTextBuffer));
//https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/extensibility/new-or-changed-behavior-with-editor-adapters?view=vs-2015
//... (calling SetSite) is not necessary if you use the IVsEditorAdaptersFactoryService to create them, because this service's Create() methods themselves call SetSite.
//IObjectWithSite ows = (IObjectWithSite)vsTextBufferAdapter;
//ows.SetSite(_editor);
//ows.SetSite(_OleSvcProvider);
//////hr = vsTextBufferAdapter.SetLanguageServiceID(ref GuidList.guidCRYLangSvc);
//Guid lguid = new Guid(VSConstants.VsLanguageServiceGuid.HtmlLanguageService_string);
//hr = vsTextBuffer.SetLanguageServiceID(ref lguid);
vsTextLines = (IVsTextLines)vsTextBufferAdapter;
// create/initialize/site a VsCodeWindow object
_vsCodeWindow = ivsEditorAdaptersFactoryService.CreateVsCodeWindowAdapter(_OleSvcProvider);
hr = _vsCodeWindow.SetBuffer(vsTextLines);
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,
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_SUPPRESSBORDER, // |
//(uint)TextViewInitFlags2.VIF_SUPPRESSTRACKCHANGES |
//(uint)TextViewInitFlags2.VIF_SUPPRESSTRACKGOBACK,
initView);
IVsWindowPane vsWindowPane = (IVsWindowPane)vsCodeWindowEx;
hr = vsWindowPane.CreatePaneWindow(this.Handle, 0, 0, this.Parent.Size.Width, this.Parent.Size.Height, out _hWndCodeWindow);
IVsTextView vsTextView;
hr = _vsCodeWindow.GetPrimaryView(out vsTextView);
//commenting out the following does not change the outcome of failing to load the code window.
// 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 the data is changed
IConnectionPointContainer txtCntr = (IConnectionPointContainer)vsTextBufferAdapter;
if (txtCntr != null)
{
Guid iidConPt = typeof(IVsTextLinesEvents).GUID;
txtCntr.FindConnectionPoint(ref iidConPt, out cp);
cp.Advise((IVsTextLinesEvents)this, out txtcookie);
}
}
catch { }
}