Passo a passo: Criando um Editor de núcleo e registrando um tipo de arquivo do Editor
Esta explicação passo a passo demonstra como criar um VSPackage que inicia a Visual Studio editor principal quando um arquivo que possui a extensão de nome de arquivo .myext for carregado.
Pré-requisitos
Para concluir este passo a passo, você deve instalar o SDL do Visual Studio 2010.
Dica
Para obter mais informações sobre o SDK de Visual Studio, consulte Ampliando a visão geral de Visual Studio.Para descobrir como fazer o download do SDK do Visual Studio, consulte Visual Studio extensibilidade Developer Center no site do MSDN.
Locais para o modelo de projeto de pacote de Visual Studio
O modelo de projeto do pacote de Visual Studio pode ser encontrado em três locais diferentes de Novo projeto caixa de diálogo:
Em Visual Basic extensibilidade. O idioma padrão do projeto é Visual Basic.
Em C# extensibilidade. O idioma padrão do projeto é C#.
Em outra extensibilidade de tipos de projeto. O idioma padrão do projeto é C++.
Para criar o VSPackage
- Iniciar Visual Studio e criar um Visual C# VSPackage chamado MyPackage, conforme descrito no Walkthrough: Creating a Menu Command VSPackage.
Para adicionar a fábrica de editor
Com o botão direito do MyPackage de projeto, aponte para Add e, em seguida, clique em classe.
No Add New Item caixa de diálogo caixa, certifique-se a classe modelo é selecionado, tipo EditorFactory.cs para o nome e, em seguida, clique Add para adicionar a classe ao seu projeto.
O arquivo de EditorFactory.cs deve ser aberto automaticamente.
Os seguintes assemblies de referência do seu código.
Imports System.Runtime.InteropServices Imports Microsoft.VisualStudio Imports Microsoft.VisualStudio.Shell Imports Microsoft.VisualStudio.Shell.Interop Imports Microsoft.VisualStudio.OLE.Interop Imports Microsoft.VisualStudio.TextManager.Interop Imports IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider
using System.Runtime.InteropServices; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.TextManager.Interop; using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
Adicionar um GUID para o EditorFactory classe adicionando a Guid atributo imediatamente antes da declaração de classe.
Você pode gerar um novo GUID usando-se o programa de Guidgen a Visual Studio command prompt, ou clicando em Criar GUID sobre o Ferramentas menu. O GUID usado aqui é apenas um exemplo; não usá-lo em seu projeto.
<Guid("0eea3187-c5fa-48d4-aa72-b5eecd3b17b1")> _
[Guid("0eea3187-c5fa-48d4-aa72-b5eecd3b17b1")]
Na definição de classe, adicione duas variáveis particulares para conter o pacote pai e um provedor de serviços.
Class EditorFactory Private parentPackage As Package Private serviceProvider As IOleServiceProvider
class EditorFactory { private Package parentPackage; private IOleServiceProvider serviceProvider; }
Adicionar um construtor de classe pública que recebe um parâmetro do tipo Package:
Public Sub New(ByVal parentPackage As Package) Me.parentPackage = parentPackage End Sub
public EditorFactory(Package parentPackage) { this.parentPackage = parentPackage; }
Modificar o EditorFactory declaração para derivar a partir da classe de IVsEditorFactory interface.
Class EditorFactory Implements IVsEditorFacto
class EditorFactory : IVsEditorFactory
Com o botão direito IVsEditorFactory, clique em Implementar Interfacee, em seguida, clique em Implementar Interface explicitamente.
Isso adiciona os quatro métodos que devem ser implementados na IVsEditorFactory interface.
Substituir o conteúdo da IVsEditorFactory.Close método com o código a seguir.
Return VSConstants.S_OK
return VSConstants.S_OK;
Substituir o conteúdo da IVsEditorFactory.SetSite com o código a seguir.
Me.serviceProvider = psp Return VSConstants.S_OK
this.serviceProvider = psp; return VSConstants.S_OK;
Substituir o conteúdo da IVsEditorFactory.MapLogicalView método com o código a seguir.
Dim retval As Integer = VSConstants.E_NOTIMPL pbstrPhysicalView = Nothing ' We support only one view. If rguidLogicalView.Equals(VSConstants.LOGVIEWID_Designer)OrElse _ rguidLogicalView.Equals(VSConstants.LOGVIEWID_Primary) Then retval = VSConstants.S_OK End If Return retval
int retval = VSConstants.E_NOTIMPL; pbstrPhysicalView = null; // We support only one view. if (rguidLogicalView.Equals(VSConstants.LOGVIEWID_Designer) || rguidLogicalView.Equals(VSConstants.LOGVIEWID_Primary)) { retval = VSConstants.S_OK; } return retval;
Substituir o conteúdo da IVsEditorFactory.CreateEditorInstance método com o código a seguir.
Dim retval As Integer = VSConstants.E_FAIL ' Initialize these to empty to start with ppunkDocView = IntPtr.Zero ppunkDocData = IntPtr.Zero pbstrEditorCaption = "" pguidCmdUI = Guid.Empty pgrfCDW = 0 If (grfCreateDoc And (VSConstants.CEF_OPENFILE Or _ VSConstants.CEF_SILENT)) = 0 Then Throw New ArgumentException("Only Open or Silent is valid") End If If punkDocDataExisting <> IntPtr.Zero Then Return VSConstants.VS_E_INCOMPATIBLEDOCDATA End If ' Instantiate a text buffer of type VsTextBuffer. ' Note: we only need an IUnknown (object) interface for ' this invocation. Dim clsidTextBuffer As Guid = GetType(VsTextBufferClass).GUID Dim iidTextBuffer As Guid = VSConstants.IID_IUnknown Dim pTextBuffer As Object = pTextBuffer = _ parentPackage.CreateInstance(clsidTextBuffer, iidTextBuffer, _ GetType(Object)) If Not pTextBuffer Is Nothing Then ' "Site" the text buffer with the service provider we were ' provided. Dim textBufferSite As IObjectWithSite = TryCast(pTextBuffer, _ IObjectWithSite) If Not textBufferSite Is Nothing Then textBufferSite.SetSite(Me.serviceProvider) End If ' Instantiate a code window of type IVsCodeWindow. Dim clsidCodeWindow As Guid = GetType(VsCodeWindowClass).GUID Dim iidCodeWindow As Guid = GetType(IVsCodeWindow).GUID Dim pCodeWindow As IVsCodeWindow = _ CType(Me.parentPackage.CreateInstance(clsidCodeWindow, _ iidCodeWindow, GetType(IVsCodeWindow)), IVsCodeWindow) If Not pCodeWindow Is Nothing Then ' Give the text buffer to the code window. ' We are giving up ownership of the text buffer! pCodeWindow.SetBuffer(CType(pTextBuffer, IVsTextLines)) ' Now tell the caller about all this new stuff ' that has been created. ppunkDocView = Marshal.GetIUnknownForObject(pCodeWindow) ppunkDocData = Marshal.GetIUnknownForObject(pTextBuffer) ' Specify the command UI to use so keypresses are ' automatically dealt with. pguidCmdUI = VSConstants.GUID_TextEditorFactory ' This caption is appended to the filename and ' lets us know our invocation of the core editor ' is up and running. pbstrEditorCaption = " [MyPackage]" retval = VSConstants.S_OK End If End If Return retval
int retval = VSConstants.E_FAIL; // Initialize these to empty to start with ppunkDocView = IntPtr.Zero; ppunkDocData = IntPtr.Zero; pbstrEditorCaption = ""; pguidCmdUI = Guid.Empty; pgrfCDW = 0; if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) { throw new ArgumentException("Only Open or Silent is valid"); } if (punkDocDataExisting != IntPtr.Zero) { return VSConstants.VS_E_INCOMPATIBLEDOCDATA; } // Instantiate a text buffer of type VsTextBuffer. // Note: we only need an IUnknown (object) interface for // this invocation. Guid clsidTextBuffer = typeof(VsTextBufferClass).GUID; Guid iidTextBuffer = VSConstants.IID_IUnknown; object pTextBuffer = pTextBuffer = parentPackage.CreateInstance( ref clsidTextBuffer, ref iidTextBuffer, typeof(object)); if (pTextBuffer != null) { // "Site" the text buffer with the service provider we were // provided. IObjectWithSite textBufferSite = pTextBuffer as IObjectWithSite; if (textBufferSite != null) { textBufferSite.SetSite(this.serviceProvider); } // Instantiate a code window of type IVsCodeWindow. Guid clsidCodeWindow = typeof(VsCodeWindowClass).GUID; Guid iidCodeWindow = typeof(IVsCodeWindow).GUID; IVsCodeWindow pCodeWindow = (IVsCodeWindow)this.parentPackage.CreateInstance( ref clsidCodeWindow, ref iidCodeWindow, typeof(IVsCodeWindow)); if (pCodeWindow != null) { // Give the text buffer to the code window. // We are giving up ownership of the text buffer! pCodeWindow.SetBuffer((IVsTextLines)pTextBuffer); // Now tell the caller about all this new stuff // that has been created. ppunkDocView = Marshal.GetIUnknownForObject(pCodeWindow); ppunkDocData = Marshal.GetIUnknownForObject(pTextBuffer); // Specify the command UI to use so keypresses are // automatically dealt with. pguidCmdUI = VSConstants.GUID_TextEditorFactory; // This caption is appended to the filename and // lets us know our invocation of the core editor // is up and running. pbstrEditorCaption = " [MyPackage]"; retval = VSConstants.S_OK; } } return retval;
Compile o projeto e certificar-se de que não existem erros.
Para registrar a fábrica de editor
Em Solution Explorer, duas vezes no arquivo resx para abri-lo à tabela de cadeia de caracteres, no qual a entrada String1 for selecionada.
Alterar o nome do identificador para IDS_EDITORNAME e o texto para o Editor de MyPackage. Essa seqüência aparecerá como o nome do seu editor.
Abra o arquivo VSPackage.resx e adicione uma nova string, defina o nome como 101 e o valor para IDS_EDITORNAME. Isso oferece o pacote com um ID de recurso para acessar a seqüência de caracteres que você acabou de criar.
Dica
Se o arquivo VSPackage.resx contém outra seqüência de caracteres que o name atributo definido como 101, substitua o outro valor exclusivo, numérico, aqui e nas etapas a seguir.
Em Solution Explorer, abra o arquivo MyPackagePackage.cs.
Este é o arquivo de pacote principal.
Adicione os seguintes atributos de usuário antes de Guid atributo.
<ProvideEditorFactoryAttribute(GetType(EditorFactory), 101)> _ <ProvideEditorExtensionAttribute(GetType(EditorFactory), _ ".myext", 32, NameResourceID:=101 )> _
[ProvideEditorFactory(typeof(EditorFactory), 101)] [ProvideEditorExtension(typeof(EditorFactory), ".myext", 32, NameResourceID = 101)]
O ProvideEditorExtensionAttribute atributo associa a extensão de arquivo de .myext sua fábrica de editor para que um arquivo que tenha que a extensão é carregado, sua fábrica de editor é chamada a qualquer hora.
Adicione uma variável privada para o MyPackage de classe, antes do construtor e dê a ele o tipo de EditorFactory.
Private editorFactory As EditorFactory
private EditorFactory editorFactory;
Encontrar o Initialize método (talvez você precise abrir o Package Members região oculta) e adicione o seguinte código após a chamada para base.Initialize().
'Create our editor factory and register it. Me.editorFactory = New EditorFactory(Me) MyBase.RegisterEditorFactory(Me.editorFactory)
// Create our editor factory and register it. this.editorFactory = new EditorFactory(this); base.RegisterEditorFactory(this.editorFactory);
Compilação do programa e certificar-se de que não existem erros.
Esta etapa registra a fábrica de editor na ramificação do registro experimental para Visual Studio. Se você for solicitado a substituir o arquivo resource.h, clique em OK.
Crie um arquivo de exemplo chamado TextFile1.myext.
Pressione F5 para abrir uma instância do experimental Visual Studio.
No experimental Visual Studiodiante do arquivo , aponte para Abrir e, em seguida, clique em arquivo.
Localizar TextFile1.myext e, em seguida, clique em Abrir.
Agora, o arquivo deve ser carregado.
Programação robusta
O Visual Studio editor núcleo manipula uma ampla gama de tipos de arquivo de texto e trabalha com os serviços de linguagem para fornecer um rico conjunto de recursos, como realce de sintaxe, correspondência de chaves e listas de conclusão do word e a conclusão do membro IntelliSense. Se você estiver trabalhando com arquivos de texto, você pode usar o editor de núcleo em conjunto com um serviço de idioma personalizada que ofereça suporte os tipos de arquivo específicos.
Um VSPackage pode chamar o Visual Studio editor do núcleo, fornecendo uma fábrica de editor. Esta fábrica de editor é usada toda vez que um arquivo que está associado ele é carregado. Se o arquivo for parte de um projeto, o editor do núcleo é invocado automaticamente a menos que substituída por seu VSPackage. No entanto, se o arquivo for carregado fora de um projeto, em seguida, o editor do núcleo deve ser explicitamente invocado por seu VSPackage.
Para obter mais informações sobre o editor de núcleo, consulte Dentro do Editor de núcleo.
Consulte também
Conceitos
Instanciar o Editor de núcleo, usando a API Legacy