事件系统

关键词:

  • withevents
  • event
  • raiseevent

名为TimerState的类模块,作为事主:

  1. Option Explicit
  2. Public Event UpdateTime(ByVal dblJump As Double)
  3. Public Event ChangeText()
  4. Public Sub TimerTask(ByVal Duration As Double)
  5. Dim dblStart As Double
  6. Dim dblSecond As Double
  7. Dim dblSoFar As Double
  8. dblStart = Timer
  9. dblSoFar = dblStart
  10. Do While Timer < dblStart + Duration
  11. If Timer - dblSoFar >= 1 Then
  12. dblSoFar = dblSoFar + 1
  13. RaiseEvent UpdateTime(Timer - dblStart)
  14. End If
  15. Loop
  16. RaiseEvent ChangeText
  17. 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现在这么规定,咱们就本着帮助记忆的目的,尽量把它的规定解释得合理一些吧。之所以事件过程要放在事发现场,原因是:事件过程要处理事件的各种情况,自然要知道事发现场的各种事情了,还要操作事发现场的各种对象以便善后,所以,当然在事发现场处理是最好的了。