Introduction:
Graphics enhance the user interface of Windows Forms applications by generating graphical charts, graphical reports, and edit or create images. The .NET Framework includes tools that allow you to draw lines, shapes, patterns, and text. The focus of this paper is to help the beginner use the System.Drawing namespace. To that end, please note that this is meant for beginners. The paper will begin by, of course, using System.Windows.Forms in order to establish how a C# file can contain a Windows Form.
The objective of this article:
- Enhance the user interface of a .NET Framework application by using brushes, pens, colors, and fonts.
- Enhance the user interface of a .NET Framework application by using graphics, images, bitmaps, and icons.
- Enhance the user interface of a .NET Framework application by using shapes and sizes.
This article assumes that the reader is familiar with both creating a basic Windows Forms application in Microsoft Visual Studio using either Visual Basic or C# , as well as writing to files and streams.
Consider this basic code:
//file: dialog.cs
using System;
using System.Windows.Forms;
class Program
{
static void Main()
{
MessageBox.Show("This is a dialog box!");
}
}
We compile this code on the .NET Framework.
C:\Windows\Microsoft.NET\Framework\v2.0.50727>csc.exe /target:winexe dialog.cs
C:\Windows\Microsoft.NET\Framework\v2.0.50727>dialog.exe
The output is a square dialog box containing the above text and the button control. In and of itself, however, it does not do much. In Windows, video memory is allocated in 4 kb blocks and the icons on the desktop are called Windows objects. The click of an icon of a program sends a message to the operating system; the program loader must associate the corresponding icon with the application program, as corresponded by the bitmap location of the icon. The loader, will, in turn, search the hard disk for the code and data of the program (code, data, IL, and metadata if it is a .NET application), along with any other necessary information to load and launch the program into runtime. In a similar fashion, if we drag and drop an icon we have dragged an object from its source and dropped it to its destination. The moment the mouse clicks on the object, a message is sent its window. The moment the icon is When the object is dropped at a target, a message is sent back to complete what is called a message loop. As a matter of fact, when any form of standard input - a keyboard press, a mouse click a Windows message is sent. For each event the Windows operating system creates a message which it sends to the application at hand. Each message contains:
-
A message identifier which indicates the type of event ( mouse left click, mouse right click, a key press.
-
The parameters whose type and number vary depending on the type of message (mouse position, a particular keyboard press.)
The following example outputs a Windows object, or actually a Windows Form with controls on it. There is an area for user input to enter a number. The callback procedure, called (in this context an event handler) will indicate if the number is prime or divisible by prime number:
//File: showprime.cs
using System;
using System.ComponentModel;
using System.Windows.Forms; // importing the namespaces that contain the classes
// that define the methods meant to work on the data
public class PrimeForm : Form
{
// the class declaration the public part that exposes the
public PrimeForm()
{
// its implementation
InitializeComponent();
InitializeBackgoundWorker();
}
private void InitializeBackgoundWorker()
{
backgroundWorker.DoWork += DoWork;
backgroundWorker.RunWorkerCompleted += Complete;
backgroundWorker.ProgressChanged += ProgressChanged;
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
}
private void DoWork( object sender,DoWorkEventArgs e )
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = IsPrime( (int)e.Argument, worker, e );
}
private void ProgressChanged( object sender, ProgressChangedEventArgs e )
{
progressBar.Value = e.ProgressPercentage;
}
private void Complete( object sender,RunWorkerCompletedEventArgs e )
{
textBoxInput.Enabled = true;
buttonStart.Enabled = true;
buttonCancel.Enabled = false;
if ( e.Error != null )
MessageBox.Show( e.Error.Message );
else if ( e.Cancelled )
textBoxResult.Text = "Processing cancelled!";
else
textBoxResult.Text = e.Result.ToString();
}
private void buttonStart_Click( object sender, EventArgs e )
{
int number = 0;
if ( int.TryParse( textBoxInput.Text, out number) )
{
textBoxResult.Text = String.Empty;
textBoxInput.Enabled = false;
buttonStart.Enabled = false;
buttonCancel.Enabled = true;
progressBar.Value = 0;
backgroundWorker.RunWorkerAsync( number );
}
else textBoxResult.Text = "input invalid!";
}
private void buttonCancel_Click( object sender, EventArgs e )
{
backgroundWorker.CancelAsync();
buttonCancel.Enabled = false;
}
private string IsPrime( int number,BackgroundWorker worker, DoWorkEventArgs e)
{
int root = ( (int) System.Math.Sqrt(number) )+1;
int highestPercentageReached = 0;
for ( int i = 2; i < root; i++ )
{
if ( worker.CancellationPending )
{
e.Cancel = true;
return String.Empty;
}
else
{
if (number % i == 0)
return "can be divided by " + i.ToString();
int percentComplete =(int)((float)i / (float)root * 100);
if ( percentComplete > highestPercentageReached ) {
highestPercentageReached = percentComplete;
worker.ReportProgress(percentComplete);
}
}
}
return "is prime";
}
[STAThread]
static void Main()
{
// program entry point after importing class libraries as
Application.Run(new PrimeForm()); // separated by namespaces
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose( bool disposing )
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.progressBar = new System.Windows.Forms.ProgressBar();
this.label1 = new System.Windows.Forms.Label();
this.textBoxInput = new System.Windows.Forms.TextBox();
this.textBoxResult = new System.Windows.Forms.TextBox();
this.buttonStart = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
this.SuspendLayout();
// Location, Name, Size,TabIndex, Name and Text properties as set in Visual Studio
this.progressBar.Location = new System.Drawing.Point(12, 33);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(392, 23);
this.progressBar.TabIndex = 0;
this.label1.AutoSize = true; // the property for Label1 sets autosize=true
this.label1.Location = new System.Drawing.Point(11, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(28, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Num:"; // the text property is set to Num
this.textBoxInput.Location = new System.Drawing.Point(48, 5);
this.textBoxInput.Name = "textBoxInput";
this.textBoxInput.Size = new System.Drawing.Size(181, 20);
this.textBoxInput.TabIndex = 2;
this.textBoxResult.Location = new System.Drawing.Point(235, 5);
this.textBoxResult.Name = "textBoxResult";
this.textBoxResult.ReadOnly = true;
this.textBoxResult.Size = new System.Drawing.Size(169, 20);
this.textBoxResult.TabIndex = 3;
this.buttonStart.Location = new System.Drawing.Point(412, 4);
this.buttonStart.Name = "buttonStart";
this.buttonStart.Size = new System.Drawing.Size(75, 23);
this.buttonStart.TabIndex = 4;
this.buttonStart.Text = "Start";
this.buttonStart.Click += new
System.EventHandler(this.buttonStart_Click);
this.buttonCancel.Location = new System.Drawing.Point(412, 33);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 5;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.Click += new
System.EventHandler(this.buttonCancel_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(499, 70);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonStart);
this.Controls.Add(this.textBoxResult);
this.Controls.Add(this.textBoxInput);
this.Controls.Add(this.label1);
this.Controls.Add(this.progressBar);
this.Name = "PrimeForm";
this.Text = "PrimeForm";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBoxInput;
private System.Windows.Forms.TextBox textBoxResult;
private System.Windows.Forms.Button buttonStart;
private System.Windows.Forms.Button buttonCancel;
private System.ComponentModel.BackgroundWorker backgroundWorker;
We compile this code:
C:Windows\Microsoft.NET\Framework\v2.0.50727> csc.exe /t:winexe /out:showprime.exe showprime.cs
C:Windows\Microsoft.NET\Framework\v2.0.50727> showprime.exe
And the output is a prime number indicator containing an array of boxes to indicate the number itself.
The main Windows key system components are ntdll.dll, hal.dll, kernel32.dll, csrss.exe, and two others: user32.dll and gdi32.dll. These last two are used for Windows objects and the graphics contained in them. Anyone who uses Visual Studio knows that a Windows Form can be completely contained in C# source code file. You drag and drop controls onto the user interface, inform the system of the name of the name of the control, gives names by manipulating the text properties, and then write (since the .NET Framework 2.0 enabled partial classes) write an event handler to handle the event of the mouse click on the control. GDI stands for Graphical Interface Device and the GDI+ library contained in the .NET Framework enables you to display images, render lines, curves, etc. On the Internet, the most widely used classes that comprise the System.Drawing namespace are the System.Drawing.Graphics class, the System.Drawing.Pen class, and the System.Drawing.Brush class.
Many times the user-define type is called a structure. A structure is a composite of other types that make it easier to work with related data. The simplest example is System.Drawing.Point, which contains X and Y integer properties that define the horizontal and vertical coordinates of a point. The Point structure simplifies working with coordinates by providing the constructor and members demonstrated here:
// create point
System.Drawing.Point p = new System.Drawing.Point(20, 30);
// now move point diagonally:
p.Offset(-1, -1);
Console.WriteLine("Point X {0}, Y{1}", p.X, p.Y);