逐步解說: 建立核心編輯器和登錄編輯器 」 的檔案類型
本逐步解說會示範如何建立啟動 VSPackage Visual Studio核心編輯器時具有.myext 副檔名的檔案會載入。
必要條件
若要完成這個逐步解說中,您必須安裝Visual Studio 2010 SDK。
![]() |
---|
如需有關 Visual Studio 的 SDK 的詳細資訊,請參閱擴充 Visual Studio 的概觀。若要了解如何下載 Visual Studio 的 SDK,請參閱Visual Studio 擴充性開發人員中心 MSDN 網站上。 |
Visual Studio 的封裝專案範本的位置
Visual Studio 的封裝的專案範本,請參閱以下三個不同的位置,在新的專案對話方塊:
在 [Visual Basic 擴充性。 專案的預設語言是 Visual Basic。
在 [C# 擴充性。 專案的預設語言是 C#。
在 [其他專案的型別擴充性。 專案的預設語言是 c + +。
若要建立 VSPackage
- 開始Visual Studio ,並建立Visual C# VSPackage 名為 MyPackage中所述, Walkthrough: Creating a Menu Command VSPackage。
若要加入編輯器工廠
以滑鼠右鍵按一下 MyPackage 專案,並指向新增 ,然後按一下 [ 類別。
在加入新項目 對話方塊方塊中,請確定 類別 選取範本時,型別 EditorFactory.cs 做為名稱,然後按一下 [ 新增來將類別加入至您的專案。
應該會自動開啟 EditorFactory.cs 檔案。
請參考下列組件從您的程式碼。
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;
加入 GUID 用來EditorFactory類別加上Guid類別宣告之前緊接的屬性。
您可以藉由使用 guidgen.exe 程式在產生新的 GUID Visual Studio指令提示,或按一下建立 GUID 的工具功能表。 此處使用 GUID 是僅為範例。 不要使用它在專案中。
<Guid("0eea3187-c5fa-48d4-aa72-b5eecd3b17b1")> _
[Guid("0eea3187-c5fa-48d4-aa72-b5eecd3b17b1")]
在類別定義中,加入兩個私用變數以包含父封裝和服務提供者。
Class EditorFactory Private parentPackage As Package Private serviceProvider As IOleServiceProvider
class EditorFactory { private Package parentPackage; private IOleServiceProvider serviceProvider; }
加入採用一個參數型別的公用類別建構函式Package:
Public Sub New(ByVal parentPackage As Package) Me.parentPackage = parentPackage End Sub
public EditorFactory(Package parentPackage) { this.parentPackage = parentPackage; }
修改EditorFactory類別宣告為衍生自IVsEditorFactory介面。
Class EditorFactory Implements IVsEditorFacto
class EditorFactory : IVsEditorFactory
以滑鼠右鍵按一下IVsEditorFactory,按一下 [ 實作介面,然後按一下 [ 明確實作介面。
如此會將四種方法必須在實作IVsEditorFactory介面。
取代的內容IVsEditorFactory.Close與下列程式碼的方法。
Return VSConstants.S_OK
return VSConstants.S_OK;
取代的內容IVsEditorFactory.SetSite與下列程式碼。
Me.serviceProvider = psp Return VSConstants.S_OK
this.serviceProvider = psp; return VSConstants.S_OK;
取代的內容IVsEditorFactory.MapLogicalView與下列程式碼的方法。
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;
取代的內容IVsEditorFactory.CreateEditorInstance與下列程式碼的方法。
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;
編譯專案,並請確定沒有任何錯誤。
登錄編輯器工廠
在方案總管] 中,連按兩下以開啟 [字串資料表,其中的 Resources.resx 檔案的項目 String1 是選取。
變更識別項名稱 IDS_EDITORNAME 至 MyPackage 編輯器的文字。 這個字串會顯示為您的編輯器名稱。
開啟 VSPackage.resx 檔案,並加入新的字串,請將名稱設定為 101、 以值 IDS_EDITORNAME。 這會將套件提供的資源 ID,才能存取您剛建立的字串。
注意事項
如果 VSPackage.resx 檔案包含另一個字串, name屬性設定為 101,此處並以下列的步驟,以取代另一個的唯一、 數字值。
在方案總管] 中,開啟 MyPackagePackage.cs 檔案。
這是主要封裝檔案。
加入下列的使用者屬性之前Guid屬性。
<ProvideEditorFactoryAttribute(GetType(EditorFactory), 101)> _ <ProvideEditorExtensionAttribute(GetType(EditorFactory), _ ".myext", 32, NameResourceID:=101 )> _
[ProvideEditorFactory(typeof(EditorFactory), 101)] [ProvideEditorExtension(typeof(EditorFactory), ".myext", 32, NameResourceID = 101)]
ProvideEditorExtensionAttribute屬性會將關聯編輯器工廠.myext 檔案的副檔名,這樣每當有擴充功能會載入,、 編輯器工廠會叫用的檔案。
加入私用變數MyPackage類別之前的建構函式,, 並為它指定型別EditorFactory。
Private editorFactory As EditorFactory
private EditorFactory editorFactory;
找出Initialize方法 (您可能需要開啟Package Members隱藏的區域),並加入下列程式碼呼叫之後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);
編譯這個程式,請確定沒有任何錯誤。
這個步驟中登錄的實驗性質的登錄 hive 中的 [編輯器工廠Visual Studio。 如果提示您覆寫 resource.h 檔時,請按一下 [ 確定。
建立一個名為 TextFile1.myext 的範例檔案。
按下 F5 開啟的實驗性執行個體Visual Studio。
在實驗Visual Studio、 起檔案 功能表上指向開啟,然後按一下 檔案。
找出 TextFile1.myext,然後按一下 [ 開啟。
現在應載入檔案。
健全的程式設計
Visual Studio核心編輯器處理大範圍的文字為基礎的檔案類型,以及 works 密切語言服務與提供一組豐富的功能,例如語法反白顯示,括號對稱,IntelliSense 的文字自動完成] 和 [成員完成的清單。 如果您正在使用 [以文字為主的檔案,您可以使用核心編輯器,加上支援特定的檔案類型的自訂語言服務。
可以叫用 VSPackage Visual Studio提供編輯器工廠的核心編輯器。 這個編輯器處理站會使用與它相關聯的檔案載入任何時間。 如果檔案是專案的一部分,然後核心編輯器會自動叫用除非覆寫您的 VSPackage。 不過,如果專案外的已載入的檔案,然後核心編輯器必須明確叫用由您的 VSPackage。
如需有關核心編輯器的詳細資訊,請參閱核心編輯器內。