Пример #1
0
        protected virtual IVsTextLines GetTextBuffer(System.IntPtr docDataExisting, string filename)
        {
            IVsTextLines textLines;

            if (docDataExisting == IntPtr.Zero)
            {
                // Create a new IVsTextLines buffer.
                Type textLinesType = typeof(IVsTextLines);
                Guid riid          = textLinesType.GUID;
                Guid clsid         = typeof(VsTextBufferClass).GUID;
                textLines = _package.CreateInstance(ref clsid, ref riid, textLinesType) as IVsTextLines;

                // set the buffer's site
                ((IObjectWithSite)textLines).SetSite(_serviceProvider.GetService(typeof(IOleServiceProvider)));
            }
            else
            {
                // Use the existing text buffer
                Object dataObject = Marshal.GetObjectForIUnknown(docDataExisting);
                textLines = dataObject as IVsTextLines;
                if (textLines == null)
                {
                    // Try get the text buffer from textbuffer provider
                    IVsTextBufferProvider textBufferProvider = dataObject as IVsTextBufferProvider;
                    if (textBufferProvider != null)
                    {
                        textBufferProvider.GetTextBuffer(out textLines);
                    }
                }
                if (textLines == null)
                {
                    // Unknown docData type then, so we have to force VS to close the other editor.
                    throw Marshal.GetExceptionForHR(VSConstants.VS_E_INCOMPATIBLEDOCDATA);
                }
            }
            return(textLines);
        }
Пример #2
0
        /// <include file='doc\EditorFactory.uex' path='docs/doc[@for="EditorFactory.CreateEditorInstance"]/*' />
        /// <summary>
        /// This method checks to see if the specified file is one that your editor supports
        /// and if so, creates the core text editor and associated your language service
        /// with it.  To figure out if the file is one that your editor supports it performs
        /// the following check:
        /// <list>
        /// <item>
        /// Call IsRegisteredExtension to see if the file extension is explicitly
        /// registered to your editor.
        /// </item>
        /// <item>
        /// Call GetUserDefinedEditor to see if the user has explicitly mapped the
        /// extension to your editor.
        /// </item>
        /// <item>
        /// If your editor registered the "*" extension, then it also calls
        /// IsFileExtensionWeShouldEditAnyway and IsOurFileFormat to let you sniff
        /// the file and see if you think it contains stuff that your editor recognizes
        /// </item>
        /// </list>
        /// If all this is true then it goes ahead with the next step which is to
        /// get an IVsTextLines buffer and set it up as follows:
        /// <list>
        /// <item>
        /// If existingDocData is non-null then it checks to see if it can get an
        /// IVsTextLines buffer from this docData, and if not, returns VS_E_INCOMPATIBLEDOCDATA.
        /// Otherwise it creates a new VsTextBufferClass.
        /// </item>
        /// Calls IVsUserData.SetData on the IVsTextLines buffer with any code page prompt
        /// flags you have provided via the CodePagePrompt property.
        /// </list>
        /// <list>
        /// Calls SetLanguageServiceID to pass in your language service Guid and
        /// sets the GuidVSBufferDetectLangSid IVsUserData to false to stop the core
        /// text editor from looking up a different language service.
        /// </list>
        /// Lastly it calls CreateEditorView to create the docView.
        /// </summary>
        public virtual int CreateEditorInstance(uint createDocFlags, string moniker, string physicalView, IVsHierarchy pHier, uint itemid, IntPtr existingDocData, out IntPtr docView, out IntPtr docData, out string editorCaption, out Guid cmdUI, out int cancelled)
        {
            docView       = IntPtr.Zero;
            docData       = IntPtr.Zero;
            editorCaption = null;
            cmdUI         = Guid.Empty;
            cancelled     = 0;
            int hr = VSErr.S_OK;

            if (this.promptFlags == __PROMPTONLOADFLAGS.codepagePrompt && existingDocData != IntPtr.Zero)
            {
                //since we are trying to open with encoding just return
                hr = (int)VSConstants.VS_E_INCOMPATIBLEDOCDATA;
                goto cleanup;
            }

            bool takeover = false;

            if (!string.IsNullOrEmpty(moniker))
            {
                string ext = Path.GetExtension(moniker);
                docData       = IntPtr.Zero;
                docView       = IntPtr.Zero;
                editorCaption = null;

                bool openSpecific = (createDocFlags & (uint)__VSCREATEEDITORFLAGS2.CEF_OPENSPECIFIC) != 0;

                bool isOurs        = IsRegisteredExtension(ext);
                bool isUserDefined = (GetUserDefinedEditor(ext) == this.GetType().GUID);

                // If this file extension belongs to a different language service, then we should not open it,
                // unless the user specifically requested our editor in the Open With... dialog.
                if (!isOurs && !isUserDefined && !this.IsFileExtensionWeShouldEditAnyway(ext) && !openSpecific)
                {
                    return(VSConstants.VS_E_UNSUPPORTEDFORMAT);
                }

                takeover = (CheckAllFileTypes() && !isOurs);
                if (takeover && !isOurs && !isUserDefined && !openSpecific)
                {
                    if (!IsOurFileFormat(moniker))
                    {
                        return(VSConstants.VS_E_UNSUPPORTEDFORMAT);
                    }
                }
            }

            IVsTextLines buffer = null;

            if (existingDocData != IntPtr.Zero)
            {
                object dataObject = Marshal.GetObjectForIUnknown(existingDocData);
                buffer = dataObject as IVsTextLines;
                if (buffer == null)
                {
                    IVsTextBufferProvider bp = dataObject as IVsTextBufferProvider;
                    if (bp != null)
                    {
                        Marshal.ThrowExceptionForHR(bp.GetTextBuffer(out buffer));
                    }
                }
                if (buffer == null)
                {
                    // unknown docData type then, so we have to force VS to close the other editor.
                    hr = VSConstants.VS_E_INCOMPATIBLEDOCDATA;
                    goto cleanup;
                }
            }
            else
            {
                // Create a new IVsTextLines buffer.
                Type textLinesType = typeof(IVsTextLines);
                Guid riid          = textLinesType.GUID;
                Guid clsid         = typeof(VsTextBufferClass).GUID;
                buffer = (IVsTextLines)package.CreateInstance(ref clsid, ref riid, textLinesType);
                if (!string.IsNullOrEmpty(moniker))
                {
                    IVsUserData iud = buffer as IVsUserData;
                    if (iud != null)
                    {
                        Guid GUID_VsBufferMoniker = typeof(IVsUserData).GUID;
                        // Must be set in time for language service GetColorizer call in case the colorizer
                        // is file name dependent.
                        Marshal.ThrowExceptionForHR(iud.SetData(ref GUID_VsBufferMoniker, moniker));
                    }
                }
                IObjectWithSite ows = buffer as IObjectWithSite;
                if (ows != null)
                {
                    ows.SetSite(this.site.GetService(typeof(IOleServiceProvider)));
                }
            }

            if (this.promptFlags == __PROMPTONLOADFLAGS.codepagePrompt && buffer is IVsUserData)
            {
                IVsUserData iud = (IVsUserData)buffer;
                Guid        GUID_VsBufferEncodingPromptOnLoad = new Guid(0x99ec03f0, 0xc843, 0x4c09, 0xbe, 0x74, 0xcd, 0xca, 0x51, 0x58, 0xd3, 0x6c);
                Marshal.ThrowExceptionForHR(iud.SetData(ref GUID_VsBufferEncodingPromptOnLoad, (uint)this.CodePagePrompt));
            }

            Guid langSid = GetLanguageServiceGuid();

            if (langSid != Guid.Empty)
            {
                Guid vsCoreSid = new Guid("{8239bec4-ee87-11d0-8c98-00c04fc2ab22}");
                Guid currentSid;
                Marshal.ThrowExceptionForHR(buffer.GetLanguageServiceID(out currentSid));
                // If the language service is set to the default SID, then
                // set it to our language
                if (currentSid == vsCoreSid)
                {
                    Marshal.ThrowExceptionForHR(buffer.SetLanguageServiceID(ref langSid));
                }
                else if (currentSid != langSid)
                {
                    // Some other language service has it, so return VS_E_INCOMPATIBLEDOCDATA
                    hr = VSConstants.VS_E_INCOMPATIBLEDOCDATA;
                    goto cleanup;
                }

                takeover = true;
            }

            if (takeover)
            {
                IVsUserData vud = (IVsUserData)buffer;
                Guid        bufferDetectLang = GuidVSBufferDetectLangSid;
                Marshal.ThrowExceptionForHR(vud.SetData(ref bufferDetectLang, false));
            }

            if (existingDocData != IntPtr.Zero)
            {
                docData = existingDocData;
                Marshal.AddRef(docData);
            }
            else
            {
                docData = Marshal.GetIUnknownForObject(buffer);
            }
            docView = CreateEditorView(moniker, buffer, physicalView, out editorCaption, out cmdUI);

            if (docView == IntPtr.Zero)
            {
                // We couldn't create the view, so return this special error code so
                // VS can try another editor factory.
                hr = VSConstants.VS_E_UNSUPPORTEDFORMAT;
            }

cleanup:
            if (docView == IntPtr.Zero)
            {
                if (existingDocData != docData && docData != IntPtr.Zero)
                {
                    Marshal.Release(docData);
                    docData = IntPtr.Zero;
                }
            }
            return(hr);
        }