Windows Primer

Introduction

Visual Studio .Net 2003 Note

Creating the Window

Handling Input

Final Bits

Lesson Downloads

Further Reading

Introduction

First, I'd like to say that I'm very new to .Net development. I've tried to make the code clear as well as robust. If you see anything questionable, please let me know and I will look into it. I will not be attempting to teach C# or VB.Net so some familiarity is recommended.

In my opinion one of the most exciting things about .Net is that it's a chance to break away from the horrible legacy that is the Win32 API. The Win32 API still shows its 16-bit roots and a clean break was long overdue. I haven't been using .Net for long, but so far it looks good.

Visual Studio .Net 2003 Note

This lesson uses a file from the Common library. If you use the Solution and Project files provided you have nothing extra to do, but if you're building your own project there is something you need to be aware of. When you add an existing file to a project (Add Existing) by default it makes a copy of that file in the project directory. If the file is really a shared file then that is likely not what you want. When adding the file, a file dialog will pop-up to allow you to choose the file. Navigate to the file and select it. The "Open" button has an arrow on the side, click the arrow and select "Link". The file should now be shown in your workspace with a shortcut icon.

Creating the Window

Not surprisingly, the central element in all Windows applications is the window. In the typical Windows application, every visible object is a window. Whether it's a button or an edit box, they are all windows. Unlike the Win32 API, .Net is designed to be Object Oriented. So rather than calling functions to create a window, we create a class which inherits from the standard Windows Form and customize it to our needs. The standard Windows form is in the System.Windows.Forms namespace. The minimal Window definition is this:

public class WindowsPrimer : System.Windows.Forms.Form {

   static void Main() {

      Application.Run(new WindowsPrimer());

   }

}
Public Class WindowsPrimer
   Inherits System.Windows.Forms.Form
 
   Public Shared Sub Main()
      Application.Run(New WindowsPrimer())
   End Sub
End Class

This code is enough to create a window and display it. It's not a very useful window. In Win32 you had to specify every window attribute, whereas .Net gives you a window with reasonable defaults. This means you only have to define the things you want to change, and for a simple application there isn't much you need to change.

I created a ConfigureWindow method in a Utility class. It sets up our window for windowed or full-screen mode. Here is the code that is common between windowed and full-screen. The application name and window title are set to our project name and the background is set to black. Also, the window is centered in the display.

   //Application Name

   form.Name = name;

   //Titlebar text

   form.Text = name;

   //Background colour

   form.BackColor = System.Drawing.Color.Black;

   //Center this window

   form.StartPosition = FormStartPosition.CenterScreen;
   'Application Name

   Me.Name = _name

   'Title bar text

   Me.Text = _name

   'Background colour

   Me.BackColor = System.Drawing.Color.Black

   'Center this window

   Me.StartPosition = FormStartPosition.CenterScreen

For windowed mode we want a nice 3D border, but no sizing control or minimize or maximize buttons. We also want to set the size of the window. NOTE: There are 2 different "size" members in a Form: ClientSize and Size. Size is the total size including borders, whereas ClientSize is just the drawable area. For a graphical application the focus is typically on the drawable area, so we use ClientSize in all cases.

   //Window Size

   form.ClientSize = new System.Drawing.Size(width,height);

   //Nice 3D border, but no sizing

   form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
   'Window Size

   Me.ClientSize = New System.Drawing.Size(_width, _height)

   'Nice 3D border, but no sizing

   Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D

In full-screen mode, we have to find the current size of the display and set our window to be that size. We also want it to be borderless. And while we're at it, we hide the cursor for a nice minimalist look.

System.Drawing.Rectangle rect;

   //Set window to be borderless

   form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

   //Get the rectangle describing the primary display

   rect = System.Windows.Forms.Screen.PrimaryScreen.Bounds;

   //Set our window to cover the entire display

   form.ClientSize = rect.Size;

   //Hide the cursor

   Cursor.Hide();
Dim rect As System.Drawing.Rectangle

   'Set window to be borderless

   Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None

   'Get the rectangle describing the primary display

   rect = System.Windows.Forms.Screen.PrimaryScreen.Bounds

   'Set our window to cover the entire display

   Me.ClientSize = rect.Size

   'Hide the cursor

   Me.Cursor.Hide()

Handling Input

The common messages that are sent to a window are defined as methods in the parent class, so to add your own custom handling you just have to override those methods in your own class. For our application we want to shutdown when the user clicks the mouse. To do that we override the OnClick method. An EventArgs object is passed in but we don't need it in this case.

protected override void OnClick(System.EventArgs e) {

   this.Close();

}
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)

   Me.Close()

End Sub

Similarly, we want to shutdown when the user hits the Escape key. For this we need to examine the KeyEventArgs that are passed to our handler.

protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e) {
   if (e.KeyCode == Keys.Escape) {

      this.Close();

   }
}
Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
   If e.KeyCode = Keys.Escape Then

      Me.Close()

   End If
End Sub

Final Bits

If you compare the size of the code in this lesson to the similar code in the C++ lesson you'll see one of the benefits that .Net brings.

Lesson Downloads

Further Reading

Programming Windows with C# (Core Reference) by Charles Petzold
From Amazon:

Back