Visual Studio for Application 內幕之四
除了HostObject,vsa還有一個利於開發的特性,Event source Object(怎麼翻譯,提供事件的對象)
重點
首先,我們需要明確Event Source Object是通過IVsaCodeItem介面的AddEventSource來增加到指令碼中,在運行時,則通過其IVsaSite的GetEventSourceInstance來擷取,而事件程序的定製,則是通過vsa Ide實現
希望下面的講解有助於大家理解這個過程,在這個過程中,我們用到了許多hostObject節的代碼
準備
1、我們在document類中增加一個事件和方法
Public Event BeforeSave(ByRef Cancel As Boolean)
Public Sub Save()
Dim blnCancel As Boolean
RaiseEvent BeforeSave(blnCancel)
If Not blnCancel Then
System.Windows.Forms.MessageBox.Show("儲存文檔")
Else
System.Windows.Forms.MessageBox.Show("不儲存文檔")
End If
End Sub
2、編譯
vbc document.vb /t:library /out:bin\document.dll /r:system.windows.forms.dll
3、在項目中引用document.dll
4、定位到MyVsaSite 類,增加一個SaveDocument過程
Public Sub SaveDocument()
doc.Save()
End Sub
5、定位到MyVsaSite類,實現GetEventSourceInstance方法
這裡itemName 是下面我們所要講到的IVsaCodeItem 的名稱,eventSourceName則是IVsaCodeItem.AddEventSource的第一個參數
Public Function GetEventSourceInstance(ByVal itemName As String, ByVal eventSourceName As String) As Object Implements Microsoft.Vsa.IVsaSite.GetEventSourceInstance
Select Case itemName.ToLower & "+" & eventSourceName.ToLower
Case "test+hostobject"
Return doc
End Select
End Function
下面我們來描述重點
如何增加一個Event Source Object到script中
IVsaCodeItem的AddEventSource方法
該方法需要兩個參數,一個是在指令碼中使用的Event Source Object名,一個是其類型名,在我們這個例子中,我們把對象名命名為HostObject,類型名,當然是Document了
Dim codeItem As VsaCodeItem
codeItem = m_VsaEngine.Items.CreateItem("test", Microsoft.Vsa.VsaItemType.Code, Microsoft.Vsa.VsaItemFlag.Class)
codeItem.AddEventSource("HostObject", "Document")
在運行時擷取Event soruce Object的執行個體
見上
然後,我們通過vsa ide,為這個事件程序增加代碼
大家可以看到vsa 自動產生的聲明
Public WithEvents HostObject as Document
和我們添加的部分
儲存我們的代碼,同代碼同內幕2的一致
If m_VsaEngine.Compile() Then
Dim pe() As Byte
Dim pdb() As Byte
m_VsaEngine.SaveCompiledState(pe, pdb)
Dim fs As New FileStream("c:\test.dll", FileMode.Create)
Dim bs As New BinaryWriter(fs)
bs.Write(pe)
fs.Close()
bs.Close()
fs = New FileStream("c:\test.pdb", FileMode.Create)
bs = New BinaryWriter(fs)
bs.Write(pdb)
fs.Close()
bs.Close()
End If
運行
m_VsaEngine = New Microsoft.Vsa.VsaLoader
m_VsaEngine.RootNamespace = "test"
m_VsaEngine.RootMoniker = "test://project1"
Dim mysite As New MyVsaSite
m_VsaEngine.Site = mysite
m_VsaEngine.Run()
mysite.SaveDocument()
看看是否出現我們需要的結果
在這個例子中,我們使用vsa sdk中提供的Microsoft.VisualBasic.Vsa.Dt.dll,來顯示vsa的Ide,我們將在以後來介紹如何顯示vsa的ide,以下是我們這個例子中的代碼
Dim mySite As Microsoft.Vsa.IVsaSite
mySite = New MyVsaSite
m_VsaEngine = New Microsoft.VisualBasic.Vsa.Dt.VsaEngine
m_VsaEngine.Name = "Engine1"
With m_VsaEngine
.RootNamespace = "test"
.RootMoniker = "test://project1"
.Site = mySite
End With
m_VsaEngine.InitNew()
Dim ReferenceItem As Microsoft.Vsa.IVsaReferenceItem
ReferenceItem = m_VsaEngine.Items.CreateItem("Document", Microsoft.Vsa.VsaItemType.Reference, Microsoft.Vsa.VsaItemFlag.None)
ReferenceItem.AssemblyName = "C:\Documents and Settings\Administrator\My Documents\Visual Studio Projects\WindowsApplication2\WindowsApplication2\bin\Document.Dll"
Dim codeItem As VsaCodeItem
codeItem = m_VsaEngine.Items.CreateItem("test", Microsoft.Vsa.VsaItemType.Code, Microsoft.Vsa.VsaItemFlag.Class)
codeItem.AddEventSource("HostObject", "Document")
m_VsaDTEngine = CType(m_VsaEngine, Microsoft.Vsa.IVsaDTEngine)
m_VsaDTEngine.InitCompleted()
m_Ide = m_VsaDTEngine.GetIDE
m_Ide.Site = mySite
If m_VsaEngine.Compile() Then
Try
m_Ide.ShowIDE(True)
Catch ex As Exception
Debug.WriteLine(ex)
End Try
End If