Introducing Microsoft .NET (Pro-Developer)
|
As I’ve done with the other topics in this book, I started my exploration of Windows Forms by writing the simplest example I could think of, shown in Figure 5-1. You can download the code from this book’s Web site (http://www.introducingmicrosoft.net) and work along with me. Visual Studio is a great tool for creating this type of project, and I have used it in other examples in this chapter, but to underline the tool and language independence of Windows Forms, I wrote this Visual Basic example in Notepad. The app will seem trivial, and I wrote very little code for it, but you will see that it demonstrates several of the most basic and important features of Windows Forms.
A Windows Forms sample, written in Visual Basic using Notepad, begins here.
Listing 5-1 shows the code for my sample app. You’ll notice that I didn’t import any namespaces in this example. (See Chapter 2 for an explanation of namespaces.) I never have to do that if I don’t want to; it’s simply a matter of convenience when I want to call objects by their short names instead of their fully qualified names. I decided to do the latter in this case so that you can see exactly which namespace each object comes from. You do need to include some system DLLs in the compilation by reference, which you can see in the compilation batch file in the downloaded source code. Visual Studio automatically does this if you use it for a Windows Forms project.
The sample doesn’t bother to import namespaces.
Listing 5-1: Simplest sample app’s code listing.
Namespace IMDN.SimplestHelloWorld ‘ Declare a new class that derives from the runtime base ‘ class System.Windows.Forms.Form. Public Class SimplestHelloWorld : Inherits System.Windows.Forms.Form ’ Class constructor. Forward call to the base class for ’ its initialization, and then set our window’s caption. Public Sub New() MyBase.New Me.Text = "Introducing Microsoft .Net: Hello World" End Sub ’ This function is the entry point for a Windows Forms ’ application. Create a new instance of our form ’ object, and then pass that to the system function that ’ runs the application. Shared Sub Main() System.Windows.Forms.Application.Run(New SimplestHelloWorld()) End Sub End Class End Namespace
A top-level window in Windows Forms is called a form, and every nonconsole application needs to have at least one. This requirement will be familiar to Visual Basic programmers. C++ programmers should think of this form as their application’s main window. Windows Forms provides a prefabricated implementation of the basic functionality that every top-level window needs to have in the base class System.Windows.Forms.Form. This base class provides such features as hosting controls, supporting the docking of child windows, and responding to events.
We derive our own form class from a system base class that provides basic prefabricated form functionality.
I start this simple app by deriving a new class, called SimplestHelloWorld, from this base class. By using this inheritance notation, I tell the compiler to take all the functionality of the base class that Microsoft wrote and include it by reference in my new derived class. (See Chapter 2 for a further discussion of inheritance.)
Now that we have our new class representing our own top-level window, we need to write code that says how our object differs from the base class. In this case, we override the base class’s New method (known as a constructor, you’ll remember from Chapter 2), which is called whenever an instance of our object is created. In Visual Basic, we first call our base class’s constructor, thereby allowing the base class to complete its initialization before we attempt anything in our derived class. Failing to do this is a common cause of bugs in Visual Basic programming. C# does this for us automatically. The base class contains a property named Text, which represents the string in the form’s title bar. We set that property to a distinctive title that we will recognize.
We override the base class’s constructor to tack on new functionality when our form is created.
We now need to hook up our top-level form so that the system loader will know which code to execute when the program starts running. Visual Studio would add this code to the project for us automatically if we were using it. Since we’re not, it’s up to us to add the code. When a program starts up, the loader looks for a function called Main, which you will see I’ve placed in our object. Only your startup form can contain this method, and the loader will call it only once. The qualifier Shared means that there is only one instance of this function shared among all objects of the class (static for you C#/C++ geeks). The runtime loader calls this function to start the application. It is up to you to put in this function whatever code you need to make the application go. A Windows Forms application requires that a thread run a message loop to receive user interface messages (such as keystrokes and mouse clicks) from the operating system and route them to the correct event handlers. The static runtime function System.Windows.Forms.Application.Run runs exactly such a loop on the application’s main thread. We pass this function a new instance of our form object to tell it which form to make visible at the program’s start.
We create an instance of our form object and tell the loader to run it.
When you distribute your Windows Forms application, you can’t depend on the user having the .NET Framework installed on his or her machine. Your setup program needs to look for the presence of the correct version of the .NET Framework and install it if it isn’t already there. As is so often the case, Microsoft provides a redistributable program called dotnetfx.exe (search for that name on Microsoft’s Web site) that installs the necessary framework and class libraries. My clients report that they find it useful to keep at least one testing machine on which they have NEVER installed the .NET Framework SDK or any other development tools. They check their release versions on these machines to detect any dependencies on components such as control packages installed by those tools.
|