Declaring and Raising Events

See Also

Assume for the moment that you have a Widget class. Your Widget class has a method that can take a long time to execute, and you'd like your application to be able to put up some kind of completion indicator.

Of course, you could make the Widget object show a percent-complete dialog box, but then you'd be stuck with that dialog box in every project in which you used the Widget class. A good principle of object design is to let the application that uses an object handle the user interface — unless the whole purpose of the object is to manage a form or dialog box.

The Widget's purpose is to perform other tasks, so it's reasonable to give it a PercentDone event, and to let the procedure that calls the Widget's methods handle that event. The PercentDone event can also provide a mechanism for canceling the task.

You can start building the code example for this topic by opening a Standard Exe project, and adding two buttons and a label to Form1. On the Project menu, select Add Class Module to add a class module to the project. Name the objects as shown in the following table.

Object Property Setting
Class module Name Widget
First Button Caption Start Task
Second Button Caption Cancel
Label Name
Caption
lblPercentDone
"0"

The Widget Class

You declare an event in the Declarations section of a class module, using the Event keyword. An event can have ByVal and ByRef arguments, as the Widget's PercentDone event demonstrates:

Option Explicit
Public Event PercentDone(ByVal Percent As Single, _
ByRef Cancel As Boolean)

When the calling object receives a PercentDone event, the Percent argument contains the percentage of the task that's complete. The ByRef Cancel argument can be set to True to cancel the method that raised the event.

Note   You can declare event arguments just as you do arguments of procedures, with the following exceptions: Events cannot have named arguments, optional arguments, or ParamArray arguments. Events do not have return values.

Raising the PercentDone Event

The PercentDone event is raised by the LongTask method of the Widget class. The LongTask method takes two arguments: the length of time the method will pretend to be doing work, and the minimum time interval before LongTask pauses to raise the PercentDone event.

Public Sub LongTask(ByVal Duration As Single, _
ByVal MinimumInterval As Single)
   Dim sngThreshold As Single
   Dim sngStart As Single
   Dim blnCancel As Boolean
   
   ' The Timer function returns the fractional number
   ' of seconds since Midnight, as a Single.
   sngStart = Timer
   sngThreshold = MinimumInterval
   
   Do While Timer < (sngStart + Duration)
      ' In a real application, some unit of work would
      ' be done here each time through the loop.
      
      If Timer > (sngStart + sngThreshold) Then
         RaiseEvent PercentDone( _
         sngThreshold / Duration, blnCancel)
         ' Check to see if the operation was canceled.
         If blnCancel Then Exit Sub
         sngThreshold = sngThreshold + MinimumInterval
      End If
   Loop
End Sub

Every MinimumInterval seconds, the PercentDone event is raised. When the event returns, LongTask checks to see if the Cancel argument was set to True.

Note   For simplicity, LongTask assumes you know in advance how long the task will take. This is almost never the case. Dividing tasks into chunks of even size can be difficult, and often what matters most to users is simply the amount of time that passes before they get an indication that something is happening.

For More Information   Now that you've declared an event and raised it, how do you get another object to handle it? "Handling an Object's Events" continues the saga of the Widget object.