Have a question? ask www.kenlet.com
Home  |  FAQ  |  About  |  Contact  |  View Source   
 
SEARCH:
 
BROWSE:
    My Hood
Edit My Info
View Events
Read Tutorials
Training Modules
View Presentations
Download Tools
Scan News
Get Jobs
Message Forums
School Forums
Member Directory
   
CONTRIBUTE:
    Sign me up!
Post an Event
Submit Tutorials
Upload Tools
Link News
Post Jobs
   
   
Home >  Tutorials >  General Coding >  From Structured to Event-Driven Programming
Add to MyHood
   From Structured to Event-Driven Programming   [ printer friendly ]
Stats
  Rating: 3.91 out of 5 by 11 users
  Submitted: 08/21/02
Ben Watson (dev@benwatson.org)

 
Transitioning from Structured to Event-Driven Programming
by Ben Watson, 8/17/2002

Introduction

When I started programming, I used Borland C++ 3.1. Without using external libraries that I didn't know how to use anyway, the software I created was in a strictly text-console environment. That is how I learned. When I first got my hands on Borland's Object Windows Library for Windows programming, I was hopelessly lost. The paradigm shift was too much for me, and I didn't understand the new model at all. For that reason I believe this tutorial can help some people understand how to make the transition from old-style techniques to modern event-driven ways of writing code.

Event-driven programming vastly improves on older models because it transfers the flow of the program from the programmer to the user. It is ideal for creating any type of user-focused application.

Structured Programming

The standard method of programming in that environment is structured. That is, we interact with the data (primitives and objects) through control structures such as IF...THEN, WHILE..., SWITCH..., FOR..., etc. The entire program's nature is defined by these structures. Let's look at a simple example in C++:


void main() {
    int input=0;
    while (input!=-1) {
        cout << "Enter an integer (-1 to quit): ";
        cin >> input;
    }
    cout << input;
}


This program reads in integers until -1 is entered. It's exceedingly simple, but it demonstrates a fundamental point about structured programming. We are always waiting for the input. The flow of the program is completely controlled by the while loop. The loop provides one way of exiting it--by inputting a specific value. Even extremely large programs based on structures merely extend this concept to larger scales. They still highly-define the user's path through the program.

Event-Driven Programming

What if instead of tightly controlling the run of a program, the software just sits idle until the user does something? In other words, the flow of the program is controlled by user-generated events.

The meat of event-driven programming is in the event-handlers. These are functions in the software that you call in response to certain events

This is probably the most important conceptual part of even-driven programming: the user is in control of your code. This has vast-implications on the type of code you write. For one, you can't expect the user to follow a predefined execution path (unless you go to great pains to enforce one). Instead, the system must be much more open-ended. This means more robust error-handling--you can NEVER assume the user has entered data in a certain order or processed one event over another, etc.

For an example, imagine a window that has two buttons. One of them lets you input an integer, and puts it on a stack. The other button adds every number on that stack. In a structured environment, you could go through a loop, inputing numbers, then adding them. If your program is event-driven, you can't assume a certain number of integers, you can't even assume that any integers have been entered at all.

That's a simplistic example, but it illustrates the fact that even-driven code must be robust enough to handle the results of other events--or, more commonly, what happens when other events haven't happened. Even-driven idioms are non-sequential.

Messaging

How does our program know there is an event? Most modern event-driven programs have something called a message loop. A message loop is usually an internal structure, hidden by the class libraries (FCL with .NET) if you're using an object-oriented system of programming. If you're programming in pure API (such as the Win32 API), then you may have to write the message loop yourself. A simple message loop can look like this:

while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 
    { 
        switch(msg.message) 
        { 
            case WM_LBUTTONDOWN: 
            case WM_RBUTTONDOWN: 
            case WM_KEYDOWN: 
                // 
                // Perform any required cleanup. 
                // 
                fDone = TRUE; 
        } 
    } 


This looks at the next message in the queue, removes it from the queue, and then performs some function based on the contents of that message. In this case, if the message is a mouse-click or a key-press, fDone is set to TRUE.

So how do messages get put in the queue? Who puts them there? This is the job of the operating system. Most modern operating systems completely control the user's interaction with the system. All mouse-clicks, key presses, video-output go through the OS between the user and the application.

This would be a good place to speak of GUIs.

The GUI

The history of the GUI is a long one, frought with complex politics that are very curious to learn about if you're interested. How would all of our lives be different if Xerox had done this, or HP accepted the idea of the Apple, or Bill Gates not given the oppurtunity to write DOS? Interesting things to think about...

Most modern operating systems in wide use rely on the use of a Graphical User Interface to communicate. This does wonders for productivity. Non-programmers/hobbyists can use a computer to get work done.

As it pertains to our discussion, though, a GUI is important because it defines not only how our program looks, but how it interacts with the user. All modern GUIs contain similar elements: forms (also called windows), controls to fill those forms, menus, etc.

A control is both a graphical element and an input/output object. I am writing this in Windows XP, using Notepad, which is a form with a menu, and an edit control which allows me to type in text. This control is created and managed by Windows itself--the code for Notepad merely tells Windows, "Hey, I want to use one of your edit control-thingamajiggies in my program, and I want it to have these options on it." Those options can be setting it to multi-line, a certain font, or whatever options the control supports.

The Windows Edit control ships in a library included in every system. Other operating systems/GUIs may differ in the details, but the point is that there is usually a large library of controls already coded for us that our programs can make use of. This is great! We don't have to reinvent the wheel every time we need an edit control, or a button (also a control). Common controls included with GUIs include: buttons, edit controls, labels, tree-views, lists, status bars, progress bars, etc. A programmer can use any of those, as well as invent his/her own control for a custom need.

Having all of these interface elements part of the operating system is a boon for programmers. Remember DOS? Do you know how much work has to go into creating a usable GUI for DOS? A LOT. You have to write everything from scratch. (Yes, there were proprietary libraries available to simplify the task).

Now that the operating system manages all of our interace, it is the one that recognizes that the user has a clicked a button. The OS gathers all of the information it can about this event, packages it into a structure called the message, and sticks it in our application's message loop, as we looked at above. The only code we have to worry about is responding to these events, creating our program's own logic, and telling the OS to update the interface as necessary.

The code for a full C# implementation of our integer adding example would take too much space here, so I'll write the important functions in C#/pseudo-code. The form is simple: two text boxes, and two buttons. The first button take an integer input from the first text box, and puts in a list of integers. The second button adds up all the integers in the list and displays the result in the second text box.

//this is called every time we hit the first button
void OnPutIntegerInList() {
    if (textbox1.Text=="")//nothing entered
        DisplayError();
    else 
        integerList.Add(Convert.ToInt32(textbox1.Text));
}

//this is called every time we hit the second button
void OnAddIntegers() {
    if (integerList.Count==0)//no numbers to add!
        DisplayError();
    else {
        int sum=0;
        for (int i=0;i<integerList.Count;i++)
            sum+=integerList[i];
        textBox2.Text=sum.ToString();
    }
        
}


This short sample illustrates the two important event-handlers: what to do when a button is clicked. As you can see, what needs to be done is different depending on what data has been input so far.

Conclusion
At first glance, even-driven programming seems more complex than structured programming, and in a sense this is true. However, an event-driven structure eases complexity by allowing you to program in the context of what the user is doing. If the problem can be thought of in the user's terms, that can make programming it a much more satisfying, and less-error prone process.



Return to Browsing Tutorials

Email this Tutorial to a Friend

Rate this Content:  
low quality  1 2 3 4 5  high quality

Reader's Comments Post a Comment
 
Interesting tutorial. It would have been nice to have a simple introduction like this when I started event-driven programming. Thanks.
-- Brent Bishop, August 29, 2002
 
Good newbie tutorial. Makes you think about a couple of issues with GUI programming if you've never done it before.
-- Beau Neal, August 29, 2002
 

Copyright © 2001 DevHood® All Rights Reserved