事件系统
关键词:
- withevents
- event
- raiseevent
名为TimerState的类模块,作为事主:
Option Explicit
Public Event UpdateTime(ByVal dblJump As Double)
Public Event ChangeText()
Public Sub TimerTask(ByVal Duration As Double)
Dim dblStart As Double
Dim dblSecond As Double
Dim dblSoFar As Double
dblStart = Timer
dblSoFar = dblStart
Do While Timer < dblStart + Duration
If Timer - dblSoFar >= 1 Then
dblSoFar = dblSoFar + 1
RaiseEvent UpdateTime(Timer - dblStart)
End If
Loop
RaiseEvent ChangeText
End Sub
事发现场模块:Form1 的代码指定了窗体的最初状态和结束状态。它同时还包括当事件被引发时所要执行的代码。
调用事主:
Option Explicit
Private WithEvents mText As TimerState
Private Sub Command1_Click()
Text1.Text = "From Now"
Text1.Refresh
Text2.Text = "0"
Text2.Refresh
Call mText.TimerTask(9.84) '注意这个方法里包含raiseevent语句
End Sub
Private Sub Form_Load()
Command1.Caption = "Click to Start Timer"
Text1.Text = ""
Text2.Text = ""
Label1.Caption = "The fastest 100 meters ever run took this long:"
Set mText = New TimerState
End Sub
Private Sub mText_ChangeText() '事件过程1
Text1.Text = "Until Now"
Text2.Text = "9.84"
End Sub
Private Sub mText_UpdateTime(ByVal dblJump As Double) '事件过程2
Text2.Text = Str(Format(dblJump, "0"))
DoEvents
End Sub
定义事件
定义对象用的是Event语句。事件都是和事主绑定在一起的定义的,event语句都是出现在事主类定义模块中的。event必须public
2. 触发事件使用RaiseEvent
调用事主类的包含RaiseEvent事件的公共方法。
事件过程和方法的区别。
如果你需要事情发生后,事主对象自己的某些属性发生一些变化,那么就调用对象的方法;如果你需要事情发生后(也就是事主对象到达某一状态后),事主对象所在的环境里其他一些对象(不是事主类对象)发生回应,那么就用事件过程。
withevents声明和事件过程
事主对象的事件被触发后,要执行一系列的动作来响应,这些动作写在事件过程里,由系统在事件触发时自动调用。
现在再动脑筋想一想,事件过程是应该在类模块中还是在使用类的模块中呢?所谓“使用类的模块”是指,声明类对象,把类实例化的模块,我们不妨称它为事发现场模块。OK,MY question是:事件过程应该在事主类模块呢还是在事发现场模块呢?
答案是:应该在事发现场模块。其实呢,从逻辑上说,搁哪儿都行、都有它的道理;不过,既然VBA现在这么规定,咱们就本着帮助记忆的目的,尽量把它的规定解释得合理一些吧。之所以事件过程要放在事发现场,原因是:事件过程要处理事件的各种情况,自然要知道事发现场的各种事情了,还要操作事发现场的各种对象以便善后,所以,当然在事发现场处理是最好的了。