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