Windows Event Programming





Windows Event Programming

So far in this book, all but one of the network programming examples have used the console mode in .NET. Windows console-mode programming uses a traditional structured programming model. In structured programming, program flow is controlled within the program itself. Each method within the class is called in turn by the functions as they occur in the program execution. The customer does not have options for changing the program execution other than what is allowed by the program. By contrast, Windows programming uses an event programming model.

Windows event programming bases program flow on events. As events occur within the program, specific methods are called and performed based on the events, as illustrated in Figure. This does not work well with blocking network functions, however. When an application presents a graphical interface to a customer, it will wait for events from the customer to determine what functions to perform. Event programming assumes that while other functions are processing (such as network access), the customer will still have control over the graphical interface. This allows the customer to perform other functions while waiting for a network response, or even abort network connections if necessary. However, if the blocking network functions were used, program execution would wait while the function was performed, and the customer would have control over neither the interface nor the program.

Click To expand
Figure: The Windows event programming model

This section describes how Windows event programming is accomplished using C# constructs and how the .NET asynchronous network methods work within the Windows event programming model.

Using Events and Delegates

The .NET programming environment is closely tied to the Windows environment, so it is not surprising that .NET fully supports the event programming model. In .NET event programming, the two key constructs are the events and delegates.

An event is a message sent by an object that represents an action that has taken place. The message identifies the action and gives any useful data related to the action. Events can be anything from the customer clicking a button (where the message represents the button name), to a packet being received on a socket (where the message represents the socket that received the data). The event sender does not necessarily know what object will handle the event message once it is sent through the Windows system. It is up to the event receiver to register with the Windows system and inform it of what types of events the receiver wants to receive. Figure demonstrates this function.

Click To expand
Figure: Windows event senders and receivers

The event receiver is identified within the Windows system by a pointer class called a delegate. The delegate is a class that holds a reference to a method that can handle the received event. When Windows receives an event, it checks to see if any delegates are registered to handle it. If any delegates are registered to handle the event, the event message is passed to the methods defined by the delegates. After the methods complete, the Windows system processes the next event that occurs, until an event signals the end of the program.

Sample Event Program

Successful event programming is, of course, vital to writing successful Windows programs. Every object produced in a Windows graphical program can generate one or more events based on what the customer is doing with the object. The .NET Framework System.Windows.Forms namespace contains classes for all the Windows objects necessary to create full-featured graphical programs in the Windows environment. These include the following:

  • Buttons

  • Text boxes

  • List boxes

  • Combo boxes

  • Check boxes

  • Text labels

  • Scroll bars

  • Window menus

It’s easy to create professional-quality network programs using these Windows objects. As each object is added to a Window form, you must register the method that will be used for its event handler. When the event is generated, Windows passes control of the program to the event handler method. Listing 8.1 demonstrates a simple Windows Forms program that uses some simple Windows objects.

Listing 8.1: The WindowSample.cs program
Start example
using System;
using System.Drawing;
using System.Windows.Forms;
class WindowSample    Form:
{
  private TextBox data;
  private ListBox results;
  public WindowSample()
  {
   Text = "Sample Window Program";
   Size = new Size(400, 380);
   Label label1 = new Label();
   label1.Parent = this;
   label1.Text = "Enter text string:";
   label1.AutoSize = true;
   label1.Location = new Point(10, 10);
   data = new TextBox();
   data.Parent = this;
   data.Size = new Size(200, 2 * Font.Height);
   data.Location = new Point(10, 35);
   results = new ListBox();
   results.Parent = this;
   results.Location = new Point(10, 65);
   results.Size = new Size(350, 20 * Font.Height);
   Button checkit = new Button();
   checkit.Parent = this;
   checkit.Text = "test";
   checkit.Location = new Point(235,32);
   checkit.Size = new Size(7 * Font.Height, 2 * Font.Height);
   checkit.Click += new
      EventHandler(checkit_OnClick);
  }
  void checkit_OnClick(object obj, EventArgs ea)
  {
   results.Items.Add(data.Text);
   data.Clear();
  }
  public static void Main()
  {
   Application.Run(new WindowSample());
  }
}
End example

This sample program is pretty simplistic from the Forms point of view so you can focus on what it teaches you about event programming. First, remember that all Windows Forms programs must use the System.Windows.Forms namespace, along with the System.Drawing namespace, to help position objects in the window:

using System.Drawing;
using System.Windows.Forms;

Because the application creates a window, it must inherit the standard window Form class:

class WindowSample : Form

The constructor for the class must define all the graphical objects that are used in the form. First, the standard values for the Windows header and default size are defined:

Text = "Sample Window Program";
Size = new Size(400, 380);

Next, each object that will appear in the window is defined, along with its own properties. This example creates the following objects:

  • A Label object to display an instructional text string

  • A TextBox object to allow the customer to enter data

  • A ListBox object to easily display output to the customer

  • A Button object to allow the customer to control when the action will occur

The key to the action in this program is the EventHandler registered for the Button object, which registers the method ButtonOnClick() with a click event on the Button object checkit:

checkit.Click += new EventHandler(ButtonOnClick);

When the customer clicks the button, the program control moves to the ButtonOnClick() method:

void ButtonOnClick(object obj, EventArgs ea)
{
  results.Items.Add(data.Text);
  data.Clear();
}

This simple method performs only two functions. First it extracts the text string entered in the TextBox object and writes it to the ListBox object. Next, it clears the text in the TextBox. Each time the customer clicks the Button object, a new text string is placed in the ListBox as a new line. These simple Windows Forms programming objects will be utilized in a network programming example in the "Sample Programs Using Asynchronous Sockets" section later in this chapter.

Note 

When compiling a Windows Forms program, you should use the csc command compiler /t:winexe option, as follows: csc /t:winexe WindowSample.cs. This creates a Windows executable program, which does not needlessly open a command prompt window when it is run.

The AsyncCallback Class

Just as events can trigger delegates, .NET also provides a way for methods to trigger delegates. The .NET AsyncCallback class allows methods to start an asynchronous function and supply a delegate method to call when the asynchronous function completes.

This process is different from standard event programming in that the event is not generated from a Windows object, but rather from another method in the program. This method itself registers an AsyncCallback delegate to call when the method completes its function. As soon as this occurs and the method indicates its completion to the Windows OS, an event is triggered to transfer the program control to the method defined in the registered AsyncCallback delegate.

The Socket class utilizes the method defined in the AsyncCallback to allow network functions to operate asynchronously in background processing. It signals the OS when the network functions have completed and passes program control to the AsyncCallback method to finish the network function. In a Windows programming environment, these methods often help avoid the occurrence of an application lock-up while waiting for network functions to complete.


 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows