Event-Driven Programming

Visual Basic programming (and Windows programming, more generally) is almost entirely geared towards event-driven programming. This means that our programs are typically composed of subroutines that are run only in response to external events - such as a mouse click. It is a rare Windows program that runs a series of procedures from top to bottom and is done.

Most mini-computer, mainframe and DOS-based applications were sequential in nature. They gathered the user's input in a specific order, processed it, and generated specific output. This was all very predictable, since the application itself was very much in control.

In an event-driven environment, such as Windows, our applications effectively give control over to the user. The user gets to choose in which order they want to enter any input, when it should be processed and often how and where the results should be displayed. Rather than being in control, our application code sits in the background waiting for the user to indicate what should be done.

For instance, let's look at how we might get input from the user. In a sequential application, we'd prompt the user for input when we needed it. In some form of DOS BASIC, that process might look like this:

Print "Name? ";
Input strName
Print "Age? ";
Input intAge
Call DoProcessing(strName, intAge)

Here, the program is in control: it asks the user for each bit of information in turn, and the user has no choice but to follow the program's flow from top to bottom.

Within Visual Basic, the approach is entirely different. We display a form to the user, allowing them to choose into which field, if any, they want to enter information:

Our code, rather than being a single sequential list of commands, now becomes a series of subroutines that are only run when specific events occur. For instance, as the user enters values into each text box on the screen, we may react to the input events and store the values in variables:

Private Sub txtName_Change()
  strName = txtName
End Sub

Private Sub txtAge_Change()
  intAge = Val(txtAge)
End Sub

Then, in response to the Click event caused when the user clicks the OK button, we might perform some processing:

Private Sub cmdOK_Click()
  DoProcessing(strName, intAge)
End Sub

Either approach gets the job done, but the event-driven approach turns a lot of control back over to the user. This is, generally, a positive thing: users usually like to have a choice about how they use their applications.

Events and Objects

Event-driven programming works well when we're dealing with objects. This is because an event is basically a type of message. When the user clicks on a button, our program gets a message saying, "Hey, the user clicked the button". Of course, the message comes to us in the form of an event - in this case, the Click event for our button. Still, what we basically received was a message that something happened.

When we're dealing with objects, we always interact with an object though its interface; that is, its properties and methods. When we call an object's method, we do so by sending it a message. This may not be very obvious, since, within our code, it looks as if we just called a method on the object. Take this line of code, for example:

  objCustomer.CreateInvoice

This code looks like a call to the CreateInvoice subroutine within the Customer class module. However, it's important to remember, when dealing with objects, that this kind of code actually sends a CreateInvoice message to the objCustomer object.

Our objects react to such events in the same way that Visual Basic programs have always reacted to events: using a subroutine.

Public Sub CreateInvoice()
  ' create the invoice here
End Sub

Any time we interact with an object, we're doing so by sending it a message. From the object's perspective, a message is basically an event caused by some outside force (typically, our program's code or some other object), and so our objects are always driven by events - just like our traditional Visual Basic applications.