anx.framework/Visual Studio/MPF11/Dev11/Src/CSharp/CommonEditorFactory.cs
Konstantin Koch 8287c54432 Included the Visual Studio extension and made the necessary changes to make it run.
Replaced the old VS templates with ones that offer more flexiblity.
Started replacing the Content Project for the samples with our custom project type.
Inlcuded a basic not yet working AssimpImporter.
2015-04-08 14:50:03 +02:00

308 lines
14 KiB
C#

/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Designer.Interfaces;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop;
using ErrorHandler = Microsoft.VisualStudio.ErrorHandler;
using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
using VSConstants = Microsoft.VisualStudio.VSConstants;
namespace Microsoft.VisualStudio.Project {
/// <summary>
/// Common factory for creating our editor
/// </summary>
public abstract class CommonEditorFactory : IVsEditorFactory {
private CommonProjectPackage _package;
private ServiceProvider _serviceProvider;
private readonly bool _promptEncodingOnLoad;
public CommonEditorFactory(CommonProjectPackage package) {
_package = package;
}
public CommonEditorFactory(CommonProjectPackage package, bool promptEncodingOnLoad) {
_package = package;
_promptEncodingOnLoad = promptEncodingOnLoad;
}
#region IVsEditorFactory Members
public virtual int SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp) {
_serviceProvider = new ServiceProvider(psp);
return VSConstants.S_OK;
}
public virtual object GetService(Type serviceType) {
return _serviceProvider.GetService(serviceType);
}
// This method is called by the Environment (inside IVsUIShellOpenDocument::
// OpenStandardEditor and OpenSpecificEditor) to map a LOGICAL view to a
// PHYSICAL view. A LOGICAL view identifies the purpose of the view that is
// desired (e.g. a view appropriate for Debugging [LOGVIEWID_Debugging], or a
// view appropriate for text view manipulation as by navigating to a find
// result [LOGVIEWID_TextView]). A PHYSICAL view identifies an actual type
// of view implementation that an IVsEditorFactory can create.
//
// NOTE: Physical views are identified by a string of your choice with the
// one constraint that the default/primary physical view for an editor
// *MUST* use a NULL string as its physical view name (*pbstrPhysicalView = NULL).
//
// NOTE: It is essential that the implementation of MapLogicalView properly
// validates that the LogicalView desired is actually supported by the editor.
// If an unsupported LogicalView is requested then E_NOTIMPL must be returned.
//
// NOTE: The special Logical Views supported by an Editor Factory must also
// be registered in the local registry hive. LOGVIEWID_Primary is implicitly
// supported by all editor types and does not need to be registered.
// For example, an editor that supports a ViewCode/ViewDesigner scenario
// might register something like the following:
// HKLM\Software\Microsoft\VisualStudio\9.0\Editors\
// {...guidEditor...}\
// LogicalViews\
// {...LOGVIEWID_TextView...} = s ''
// {...LOGVIEWID_Code...} = s ''
// {...LOGVIEWID_Debugging...} = s ''
// {...LOGVIEWID_Designer...} = s 'Form'
//
public virtual int MapLogicalView(ref Guid logicalView, out string physicalView) {
// initialize out parameter
physicalView = null;
bool isSupportedView = false;
// Determine the physical view
if (VSConstants.LOGVIEWID_Primary == logicalView ||
VSConstants.LOGVIEWID_Debugging == logicalView ||
VSConstants.LOGVIEWID_Code == logicalView ||
VSConstants.LOGVIEWID_TextView == logicalView) {
// primary view uses NULL as pbstrPhysicalView
isSupportedView = true;
} else if (VSConstants.LOGVIEWID_Designer == logicalView) {
physicalView = "Design";
isSupportedView = true;
}
if (isSupportedView)
return VSConstants.S_OK;
else {
// E_NOTIMPL must be returned for any unrecognized rguidLogicalView values
return VSConstants.E_NOTIMPL;
}
}
public virtual int Close() {
return VSConstants.S_OK;
}
/// <summary>
///
/// </summary>
/// <param name="grfCreateDoc"></param>
/// <param name="pszMkDocument"></param>
/// <param name="pszPhysicalView"></param>
/// <param name="pvHier"></param>
/// <param name="itemid"></param>
/// <param name="punkDocDataExisting"></param>
/// <param name="ppunkDocView"></param>
/// <param name="ppunkDocData"></param>
/// <param name="pbstrEditorCaption"></param>
/// <param name="pguidCmdUI"></param>
/// <param name="pgrfCDW"></param>
/// <returns></returns>
public virtual int CreateEditorInstance(
uint createEditorFlags,
string documentMoniker,
string physicalView,
IVsHierarchy hierarchy,
uint itemid,
System.IntPtr docDataExisting,
out System.IntPtr docView,
out System.IntPtr docData,
out string editorCaption,
out Guid commandUIGuid,
out int createDocumentWindowFlags) {
// Initialize output parameters
docView = IntPtr.Zero;
docData = IntPtr.Zero;
commandUIGuid = this.GetType().GUID;
createDocumentWindowFlags = 0;
editorCaption = null;
// Validate inputs
if ((createEditorFlags & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) {
return VSConstants.E_INVALIDARG;
}
// Get a text buffer
IVsTextLines textLines = GetTextBuffer(docDataExisting);
// Assign docData IntPtr to either existing docData or the new text buffer
if (docDataExisting != IntPtr.Zero) {
docData = docDataExisting;
Marshal.AddRef(docData);
} else {
docData = Marshal.GetIUnknownForObject(textLines);
}
try {
docView = CreateDocumentView(documentMoniker, physicalView, hierarchy, itemid, textLines, out editorCaption, out commandUIGuid);
} finally {
if (docView == IntPtr.Zero) {
if (docDataExisting != docData && docData != IntPtr.Zero) {
// Cleanup the instance of the docData that we have addref'ed
Marshal.Release(docData);
docData = IntPtr.Zero;
}
}
}
return VSConstants.S_OK;
}
#endregion
#region Helper methods
private IVsTextLines GetTextBuffer(System.IntPtr docDataExisting) {
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.
ErrorHandler.ThrowOnFailure((int)VSConstants.VS_E_INCOMPATIBLEDOCDATA);
}
}
return textLines;
}
private IntPtr CreateDocumentView(string documentMoniker, string physicalView, IVsHierarchy hierarchy, uint itemid, IVsTextLines textLines, out string editorCaption, out Guid cmdUI) {
//Init out params
editorCaption = string.Empty;
cmdUI = Guid.Empty;
if (string.IsNullOrEmpty(physicalView)) {
// create code window as default physical view
return CreateCodeView(documentMoniker, textLines, ref editorCaption, ref cmdUI);
} else if (string.Compare(physicalView, "design", true, CultureInfo.InvariantCulture) == 0) {
// Create Form view
return CreateFormView(hierarchy, itemid, textLines, ref editorCaption, ref cmdUI);
}
// We couldn't create the view
// Return special error code so VS can try another editor factory.
ErrorHandler.ThrowOnFailure((int)VSConstants.VS_E_UNSUPPORTEDFORMAT);
return IntPtr.Zero;
}
private IntPtr CreateFormView(IVsHierarchy hierarchy, uint itemid, IVsTextLines textLines, ref string editorCaption, ref Guid cmdUI) {
// Request the Designer Service
IVSMDDesignerService designerService = (IVSMDDesignerService)GetService(typeof(IVSMDDesignerService));
// Create loader for the designer
IVSMDDesignerLoader designerLoader = (IVSMDDesignerLoader)designerService.CreateDesignerLoader("Microsoft.VisualStudio.Designer.Serialization.VSDesignerLoader");
bool loaderInitalized = false;
try {
IOleServiceProvider provider = _serviceProvider.GetService(typeof(IOleServiceProvider)) as IOleServiceProvider;
// Initialize designer loader
designerLoader.Initialize(provider, hierarchy, (int)itemid, textLines);
loaderInitalized = true;
// Create the designer
IVSMDDesigner designer = designerService.CreateDesigner(provider, designerLoader);
// Get editor caption
editorCaption = designerLoader.GetEditorCaption((int)READONLYSTATUS.ROSTATUS_Unknown);
// Get view from designer
object docView = designer.View;
// Get command guid from designer
cmdUI = designer.CommandGuid;
return Marshal.GetIUnknownForObject(docView);
} catch {
// The designer loader may have created a reference to the shell or the text buffer.
// In case we fail to create the designer we should manually dispose the loader
// in order to release the references to the shell and the textbuffer
if (loaderInitalized) {
designerLoader.Dispose();
}
throw;
}
}
private IntPtr CreateCodeView(string documentMoniker, IVsTextLines textLines, ref string editorCaption, ref Guid cmdUI) {
Type codeWindowType = typeof(IVsCodeWindow);
Guid riid = codeWindowType.GUID;
Guid clsid = typeof(VsCodeWindowClass).GUID;
IVsCodeWindow window = (IVsCodeWindow)_package.CreateInstance(ref clsid, ref riid, codeWindowType);
ErrorHandler.ThrowOnFailure(window.SetBuffer(textLines));
ErrorHandler.ThrowOnFailure(window.SetBaseEditorCaption(null));
ErrorHandler.ThrowOnFailure(window.GetEditorCaption(READONLYSTATUS.ROSTATUS_Unknown, out editorCaption));
IVsUserData userData = textLines as IVsUserData;
if (userData != null) {
if (_promptEncodingOnLoad) {
var guid = VSConstants.VsTextBufferUserDataGuid.VsBufferEncodingPromptOnLoad_guid;
userData.SetData(ref guid, (uint)1);
}
}
InitializeLanguageService(textLines);
cmdUI = VSConstants.GUID_TextEditorFactory;
return Marshal.GetIUnknownForObject(window);
}
/// <summary>
/// Initializes the language service for the given file. This allows files with different
/// extensions to be opened by the editor type and get correct highlighting and intellisense
/// controllers.
///
/// New in 1.1
/// </summary>
protected virtual void InitializeLanguageService(IVsTextLines textLines) {
}
#endregion
}
}