将数据传递回事件源

使用通过引用传递的参数

事件可以定义要返回给调用者的 ByRef 参数:

Public Event BeforeSomething(ByRef cancel As Boolean)
Public Event AfterSomething()

Public Sub DoSomething()
    Dim cancel As Boolean
    RaiseEvent BeforeSomething(cancel)
    If cancel Then Exit Sub

    'todo: actually do something

    RaiseEvent AfterSomething
End Sub

如果 BeforeSomething 事件有一个处理程序将其 cancel 参数设置为 True,那么当执行程序从处理程序返回时,cancel 将是 TrueAfterSomething 将永远不会被引发。

Private WithEvents foo As Something

Private Sub foo_BeforeSomething(ByRef cancel As Boolean)
    cancel = MsgBox("Cancel?", vbYesNo) = vbYes
End Sub

Private Sub foo_AfterSomething()
    MsgBox "Didn't cancel!"
End Sub

假设 foo 对象引用是在某处分配的,当 foo.DoSomething 运行时,一个消息框提示是否取消,第二个消息框仅在 No 选中时显示未取消

使用可变对象

你也可以传递一个可变对象 ByVal 的副本,并让处理程序修改该对象的属性; 然后,调用者可以读取修改后的属性值并相应地执行操作。

'class module ReturnBoolean
Option Explicit
Private encapsulated As Boolean

Public Property Get ReturnValue() As Boolean
'Attribute ReturnValue.VB_UserMemId = 0
    ReturnValue = encapsulated
End Property

Public Property Let ReturnValue(ByVal value As Boolean)
    encapsulated = value
End Property

结合 Variant 类型,这可以用来创建非常明显的方法来将值返回给调用者:

Public Event SomeEvent(ByVal foo As Variant)

Public Sub DoSomething()
    Dim result As ReturnBoolean
    result = New ReturnBoolean

    RaiseEvent SomeEvent(result)

    If result Then ' If result.ReturnValue Then
        'handler changed the value to True
    Else
        'handler didn't modify the value
    End If
End Sub

处理程序看起来像这样:

Private Sub source_SomeEvent(ByVal foo As Variant) 'foo is actually a ReturnBoolean object
    foo = True 'True is actually assigned to foo.ReturnValue, the class' default member
End Sub