Learning Windows Forms: Writing and Deploying a Visual Basic Program
This article is for the beginning student of both Visual Basic and the Microsoft Visual Studio 2005 (or 2008 beta). This article assumes a basic to intermediate knowledge of Visual Basic 2005 and its migration to Visual Basic 2006.
This article is largely referenced from the MSDN library and Microsoft Educational writings. My intention is to describe the basics involved with Windows Forms and how the developer can add logic to the user interface by OLE Uniform Data Transfer. Frameworks like MFC and ATL were created to assist Windows application developers focus more on the task of solving business problems rather than handling Windows messages. The transition from 16 bit DOS to Windows, however, brought about the introduction to Windows messages. For each movement of the mouse (or key presses on the keyboard), the Windows Operating System creates a message which is sent to the concerned application. The MFC and ATL frameworks provide the plumbing, or the template, of a Windows application. It is then up to the developer to contrive the business logic. While facilitating the Windows application development process, these frameworks do not provide the controls needed to insert more logic into the user interface. This is why many developers choose Visual Basic. In order to understand how to develop an application, turn it into an executable, and perhaps even deploy it as a distributable, it is necessary to start with the basics:
- Create the user interface with controls available in the Visual Studio toolbox.
- Customize these controls by setting their properties.
- Identify exactly what your program should do and then write the code accordingly.
At minimum, a Windows Forms application consists of the following elements:
- One or more classes that derive from
System.Windows.Forms.Form
.
- A
main
method that invokes the static
(Shared
) System.Windows.Forms.Application.Run
method and passes a Form
instance to it.
The application Run
method processes messages from the Operating System to the application.
The following code illustrates the essential elements of a Windows Forms application:
Option Explicit //all variables must be declared prior to use
Option Strict
Imports System
Import System.Windows.Forms
Public Class MyForm
Inherits Form
Public Sub New()
Me.Text = "Hello, World!"
End Sub
<stathread>
Public Shared Sub Main()
Dim aform as New MyForm()
Application.Run(aform)
End Sub
End Class
To compile this on the .NET Framework: vbc.exe /t:winexe your_code.vb.
A simple way to understand the message loop is to envision the data transfer process called drag and drop. Drag is like cut/copy; a drop is like paste. This occurs when you transfer or drag an icon across your desktop. When the operation begins (that is, when the source detects the appropriate mouse click), the source passes its data object and the IDropSource
interface to OLE, which enters a message loop that detects mouse events and keyboard events (standard input). When the data object is dropped after the mouse hovers over the destination, or more to the point, a registered window, OLE tells the target IDropTarget
. The object is dropped and the message loop is complete. We recall that many IDEs have toolboxes that enable drag and drop.
So here is a program to develop using the Microsoft Visual Studio 2005: Lucky Seven.
This program will output a scenic, graphic image every time the number seven comes up. You click the spin button and if a seven show up in one of the three numerical output boxes, then the image appears.
Programming Steps
Programming Step |
Number of items |
Creating the user interface |
7 data objects |
Set the properties |
13 properties |
Write the program's code |
2 objects |
Creating the User Interface
Create a new project.
- Start Visual Studio
- On the File menu, click New Project.
- Click the Windows Application template.
- In the name box, type myGame.
- Click OK.
In order to set the size of the form, position your mouse pointer over the lower-right corner until its shape changes to a resizing pointer, and then drag it until the form is big enough for the objects that will be dragged onto it: the Form1
properties container should have a size set to around 485 pixels by 278 pixels. Now go to the View choice on the menu and click the Toolbox tab. Using the standard tools, double-click the Button
control in the ToolBox, and move the mouse pointer away. You will notice the button automatically snaps to the upper left. Position the mouse over "Button1
" so that it changes to a four-headed arrow, and drag the button down and to right. Repeat this process for the next button that will be positioned underneath the first button. Now we are going to add labels to our program, that when our buttons are pressed while the program runs, the labels will function as a user interface element designed to display the numbers. Double-click the label button and then drag it to the right of Button1
. Do this until there are three label boxes to the right of button number one. Double-click a fourth label object and drag it beneath Button2
. Remember, the button "Spin" is clicked and if a number seven appears, the graphic object appears; therefore, we need to click the image (or picture box) object in the Toolbox. The interface is created, so now we must set the properties.
Setting the Properties
Set the button properties
- Press F4 to get the Properties window.
- Click the first button (
Button1
).
- Scroll to the
Text
property.
- Double-click the text property window.
- Type in "Spin".
- Repeat for
Button2
and type in "End".
For the label object's properties, set the AutoSize
property to false
. Set the TextAlign
property to MiddleCenter
. Click the BorderStyle
property to FixedSingle
. Click the Font
property, and then click the ellipsis button (the button with three dots that's located next to the current font setting). Change the font to TimesNewRoman, the font style to Bold, and the point size to 24. Now double-click the Text
property and type in the digit 0 for each of the top three label boxes. For the fourth label box, change the Text
property to LuckySeven. Change the font property to Ariel, the font style to Bold, and the point size to 18. Set the AutoSize
property for true
(this is for Label4
only). The Visual Basic source code below should serve to clarify this reasoning:
Public Class Form1
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
End
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
PictureBox1.Visible = False Label1.Text = CStr(Int(Rnd() * 10)) Label2.Text = CStr(Int(Rnd() * 10))
Label3.Text = CStr(Int(Rnd() * 10))
If (Label1.Text = "7") Or (Label2.Text = "7") _
Or (Label3.Text = "7") Then
PictureBox1.Visible = True
Beep()
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Randomize()
End Sub
End Class
Now the PictureBox
properties:
Set the Picture Box properties
- Click the
PictureBox
on the form.
- Set the
SizeMode
property to StretchImage
.
- Size the picture to 148 pixels to 138 pixels high.
- Double-click the
Image
property and then click the ellipsis button.
- The Select Resource dialog box appears.
- In the Open dialog box, navigate to where you extracted the downloaded files.
- Choose PayCoins.jpg, and then click Open.
- Set the
Visible
property to False
.
Here is the code that is generated in the container solution:
<global.microsoft.visualbasic.compilerservices.designergenerated()> _
Partial Public Class Form1
Inherits System.Windows.Forms.Form
<system.diagnostics.debuggernonusercode() /> _
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
Private components As System.ComponentModel.IContainer
<system.diagnostics.debuggerstepthrough() /> _
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = _
New System.ComponentModel.ComponentResourceManager(GetType(Form1))
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.Label2 = New System.Windows.Forms.Label
Me.Label3 = New System.Windows.Forms.Label
Me.Label4 = New System.Windows.Forms.Label
Me.PictureBox1 = New System.Windows.Forms.PictureBox
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
Me.Button1.Location = New System.Drawing.Point(12, 12)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 23)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Spin"
Me.Button2.Location = New System.Drawing.Point(12, 41)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(75, 24)
Me.Button2.TabIndex = 1
Me.Button2.Text = "End"
Me.Label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.Label1.Font = New System.Drawing.Font("Times New Roman", _
24.0!, System.Drawing.FontStyle.Bold, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label1.Location = New System.Drawing.Point(125, 25)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(71, 57)
Me.Label1.TabIndex = 2
Me.Label1.Text = "0"
Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.Label2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.Label2.Font = New System.Drawing.Font("Times New Roman", _
24.0!, System.Drawing.FontStyle.Bold, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label2.Location = New System.Drawing.Point(214, 25)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(70, 57)
Me.Label2.TabIndex = 3
Me.Label2.Text = "0"
Me.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.Label3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.Label3.Font = New System.Drawing.Font("Times New Roman", _
24.0!, System.Drawing.FontStyle.Bold, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label3.Location = New System.Drawing.Point(304, 25)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(71, 57)
Me.Label3.TabIndex = 4
Me.Label3.Text = "0"
Me.Label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.Label4.AutoSize = True
Me.Label4.Font = New System.Drawing.Font("Arial", 18.0!, _
System.Drawing.FontStyle.Bold, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.Label4.ForeColor = System.Drawing.Color.Purple
Me.Label4.Location = New System.Drawing.Point(12, 104)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(153, 29)
Me.Label4.TabIndex = 5
Me.Label4.Text = "Lucky Seven"
Me.PictureBox1.Image = CType(resources.GetObject("PictureBox1.Image"), _
System.Drawing.Image)
Me.PictureBox1.Location = New System.Drawing.Point(214, 94)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size = New System.Drawing.Size(148, 138)
Me.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.PictureBox1.TabIndex = 6
Me.PictureBox1.TabStop = False
Me.PictureBox1.Visible = False
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(438, 244)
Me.Controls.Add(Me.PictureBox1)
Me.Controls.Add(Me.Label4)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
CType(Me.PictureBox1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Label3 As System.Windows.Forms.Label
Friend WithEvents Label4 As System.Windows.Forms.Label
Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
End Class