Compartilhar via


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:

  1. Em Visual Basic extensibilidade. O idioma padrão do projeto é Visual Basic.

  2. Em C# extensibilidade. O idioma padrão do projeto é C#.

  3. Em outra extensibilidade de tipos de projeto. O idioma padrão do projeto é C++.

Para criar o VSPackage

Para adicionar a fábrica de editor

  1. Com o botão direito do MyPackage de projeto, aponte para Add e, em seguida, clique em classe.

  2. 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.

  3. 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;
    
  4. 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")] 
    
  5. 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;
    }
    
  6. 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;
    }
    
  7. Modificar o EditorFactory declaração para derivar a partir da classe de IVsEditorFactory interface.

    Class EditorFactory Implements IVsEditorFacto
    
    class EditorFactory : IVsEditorFactory
    
  8. 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.

  9. Substituir o conteúdo da IVsEditorFactory.Close método com o código a seguir.

    Return VSConstants.S_OK
    
    return VSConstants.S_OK;
    
  10. 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;
    
  11. 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;
    
  12. 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; 
    
  13. Compile o projeto e certificar-se de que não existem erros.

Para registrar a fábrica de editor

  1. Em Solution Explorer, duas vezes no arquivo resx para abri-lo à tabela de cadeia de caracteres, no qual a entrada String1 for selecionada.

  2. 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.

  3. 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.

  4. Em Solution Explorer, abra o arquivo MyPackagePackage.cs.

    Este é o arquivo de pacote principal.

  5. 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.

  6. 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;
    
  7. 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);
    
  8. 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.

  9. Crie um arquivo de exemplo chamado TextFile1.myext.

  10. Pressione F5 para abrir uma instância do experimental Visual Studio.

  11. No experimental Visual Studiodiante do arquivo , aponte para Abrir e, em seguida, clique em arquivo.

  12. 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

Outros recursos

Dentro do Editor de núcleo