Home

Methods and Events of Windows Controls

 

Fundamentals of Controls Methods

 

Introduction

A method is a procedure created as a member of a class. Methods are used to access or manipulate the characteristics of an object or a variable. There are mainly two categories of methods you will use in your classes:

  • If you are using a control such as one of those provided by the Toolbox, you can call any of its public methods. The requirements of such a method depend on the class being used
  • If none of the existing methods can perform your desired task, you can add a method to a class
 

Control's Construction and Destruction

As you know from your study of the C# language, every class has a fundamental method called a default constructor. Every control of the .NET Framework is based on a class that has a default constructor and most of those classes have only one constructor: the default. The default constructor allows you to instantiate the class without necessarily initializing it. To use it, you must know the name of the control you want to use since each control bears the same name as its class. Here is an example:

using System;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
	private Button btnReset;
	
	public Exercise()
	{
		InitializeComponent();
	}

	#region Section Used to Initialize Controls
	private void InitializeComponent()
	{
		btnReset = new Button();
	}
	#endregion

	static void Main() 
	{
		Application.Run(new Exercise());
	}
}

If you are not planning to use a control straight from the .NET Framework, you can also create your own class that is derived from the class of the control, as we have mentioned in previous lessons. 

As mentioned in the previous lesson, after instantiating a control, it is available but the user cannot see. Each control that acts as a parent of another control has a property called Controls. This property, which is a ControlCollection type, is equipped with an Add() method. If you want to display the new control to the user, you should pass it to the Control.Controls.Add() method. Here is an example:

using System;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
	private Button btnReset;
	
	public Exercise()
	{
		InitializeComponent();
	}

	#region Section Used to Initialize Controls
	private void InitializeComponent()
	{
		btnReset = new Button();
		Controls.Add(btnReset);
	}
	#endregion

	static void Main() 
	{
		Application.Run(new Exercise());
	}
}

This displays the control to the user.

After using a control, it must be destroyed. In C++, this is traditionally done using the delete operator in the destructor of the parent of all controls, which could be a form. Another detail of Windows controls is that they use or consume computer resources during their lifetime. When the controls are not used anymore, such as when their application closes, these resources should be freed and given back to the operating system to make them available to other controls. This task can be performed using the Dispose() method to the Control class, which can then be overridden by its child controls. The syntax of the Control.Dispose() method is:

protected override void Dispose(bool disposing);

This method takes one argument, disposing, that indicates how the resources would be released. If this argument is passed with a false value, only the unmanaged resources would be released. If it is passed as true, then both managed and unmanaged resources would be released.

Control's Visibility

In the previous lesson, we saw that you can call the Visible property to hide a visible control or to display a hidden control. Besides the Visible property, you can also display a control using the Show() method. Its syntax is:

Public Sub Show()

When you use this method, if the control is visible, nothing would happen. If it were hidden, then it would be revealed. In the following example, a text box named textBox1 is asked to display:

private void button1_Click(object sender, EventArgs e)
{
	this.textBox1.Visible = false;
}

private void button2_Click(object sender, EventArgs e)
{
	this.textBox1.Show();
}

The Show() method internally sets the Visible property to true. We also saw that, to hide a control, you can set its Visible property to False. In the same way, to hide a control, you call can the Control.Hide() method. Its syntax is:

Public Sub Hide()

In the following example, the visibility of a text box named textBox1 is toggled by the user clicks a button named button1:

private void button1_Click(object sender, EventArgs e)
{
	if( this.textBox1.Visible == true )
		this.textBox1.Hide();
	else
		this.textBox1.Show();
}

Keep in mind that hiding a control does not close or destroy it.

Control's Focus

Once a control is visible, the user can use it. Some controls allow the user only to read their text or view what they display. Some other controls allow the user to retrieve their value or to change it. To perform such operations, the user must first give focus to the control. The focus is a visual aspect that indicates that a control is ready to receive input from the user. Various controls have different ways of expressing that they have received focus.

Button-based controls indicate that they have focus by drawing a thick border and a dotted rectangle around their caption. In the following picture, the button on the right has focus:

Focus

A text-based control indicates that it has focus by displaying a blinking cursor. A list-based control indicates that it has focus when one of its items has a surrounding dotted rectangle:

Focus

To give focus to a control, the user can press a key such as Tab. To programmatically give focus to a control, call the Focus() method. Here is an example:

private void button2_Click(object sender, EventArgs e)
{
	this.textBox1.Focus();
}

The Z-Order of Controls

In the previous lesson, we saw how you can position controls visually or manually. In some cases, you end up with one control positioned on top of another. Of course the first remedy that comes in mind would consist of moving one of the controls away from the other. This would also imply sometimes that you would have to enlarge and/or heighten the controls' container. There are situations that either you don't want to resize the parent or you can't: your only solution is to have one control on top of another. Fortunately, you can cope with this situation by specifying, when needed, what control at what time should be displayed to the user.

When one control is positioned on top of another, they use a third axis whose origin, like that or the other axes, is on the top-left corner of the parent. This third axis, also considered the z-axis, is oriented so that it moves from the monitor towards the user. The operating system is in charge of positioning and drawing the objects on the screen. You as the programmer can direct the operating system as to what object should be on top and what object should be behind. To support these changes the Control class uses two methods that its appropriate children derive also.

When a control A is positioned behind a control be, this causes control be either partially or completely hidden. If you want the control A to change its z-order and become on top of control B, you can call its BringToFront() method. The syntax of this method is:

public void BringToFront();

On the other hand, if a control B is positioned on top of a control A, if you want control B to become positioned behind control A, you can call control B's SendToBack() method. Its syntax is:

public void SendToBack();

After the controls have been positioned, at any time, when you access a control, if you want to know whether that control is the most top object, you can call its GetTopLevel() method. Its syntax is:

proteced bool GetTopLevel();

Creating New Methods

The Windows controls available from the .NET Framework and that we will user throughout this site are fully functional. They are equipped with various methods ready to be used. Of course, no library can surely provide every single type of method that every programmer would use. For this reason, it will not be unusual that you need a method that is not available for a control you are using. In the same way, when you create a Windows Application that is based on a Form class, you will likely need a method that is not defined in the Form class. In this case, you can create your own and new method.

A method is created like a normal procedure. If you want to add it to a form, you can open the Code Editor and write your procedure outside of any existing procedure. Here is an example:

/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		double CalculateRectangleArea(Rectangle Recto)
		{
			return Recto.Width * Recto.Height;
		}
	}
}

In the same way, if you derive a class from one of the existing classes because you want to get a custom control from it, you can declare a new method as you see fit and use it appropriately.

Probably the best way is to let the Code Editor insert the new method based on your specifications. To do that, in the Class View, first expand the name of the project. Then, right-click the name of the class where you want to add a new method, position the mouse on Add, and click Add Method. This would open the C# Method Wizard dialog box you can fill out and click Finish. After the method's body has been defined you

Using External Libraries

 

Introduction

The Windows controls featured in the .NET Framework are highly varied and provide all the necessary regular functionality a normal application would need. They do this through various properties and their different methods. To enhance their functionality and speed up application development, you can either create your own new library or use a library created in another language.

Microsoft Visual Basic Functions

Microsoft Visual Basic offers a very large set of functions.  You can use most of those functions in your application if you follow the appropriate steps. To use a Microsoft Visual Basic function in your application, you must reference its library. Most (if not all) of the functions of Visual Basic are created in the Microsoft.VisualBasic.dll assembly but they might be in different namespaces. Based on this, you can include any Visual Basic function in your program. Here is an example:

Using a Library

If the .NET Framework doesn't have a class you are looking for, you can create one and be able to use it over and over again in different programs. You can even create a commercial class and be able to distribute or sell it. To make this possible, you can "package" one or more classes in a library. A library is a program that contains classes and/or other resources that other programs can use. Such a program is created with the same approach as the programs we have done so far. Because a library is not an executable, it doesn't need the Main() function. A library usually has the extension .dll.

A library can be made of a single file or as many files as necessary. A file that is part of a library can contain one or more classes. Each class should implement a behavior that can eventually be useful and accessible to other classes. The classes in a library are created exactly like those we have used so far. Everything depends on how you compile it.

To create a library, start by typing its code in a text file. Once the library is ready, to compile it, at the Command Prompt, you would type:

csc /target:library NameOfFile.cs

and press Enter. After doing this, a library with the name of the file and the extension .dll would be created. If you want a custom name, use the following syntax:

csc /target:library /out:DesiredNameOfLibrary.dll NameOfFile.cs

Using a Visual C++/CLI Library

One of the most important sought goals in .NET is to allow different languages to collaborate, such as sharing code. One way this can happen is to be able to use the functionality of one language into another. As an illustration, we saw earlier that you could use the rich library of Visual Basic functions in a C# application. As no library is ever complete, you may still need functionality that is not easily found. Furthermore, you may be working with a team of C++ programmers who have already created a set of functions or complex operations. You should be able to use that existing code.

In previous years, it used to be a challenge to create a library, especially in C++. Fortunately, Microsoft Visual C++ now makes it particularly easy to create one, because a wizard highly assists you. To create a library, first display the New Project dialog box. After specifying Visual C++, in the Templates list, click Class Library and give it a name. In the body of the file, you can create the classes and/or functions as you see fit.

Using the Win32 Library

The Microsoft Windows operating system was originally written in C, the parent language of C++ and C# (also of Java and JavaScript). To allow programmers to create applications, Microsoft released a library called Win32. This is a series of functions and classes, etc, that you previously had to use. As time has changed, you don't need to exclusively use Win32 anymore to create a Windows application. Nonetheless, Win32 is still everywhere and it is not completely avoidable because many or some of the actions you would want to perform in a Windows application are still available only in Win32. Fortunately, in most cases, it is not always difficult to use some of these functions in a C# applications, as long as you observe some rules. Here is an example:

using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("Kernel32.dll")]
    public static extern bool SetConsoleTitle(string strMessage);

    static int Main()
    {
 	SetConsoleTitle("C# Programming");

	return 0;
    }
}

A Review of Delegates

 

Introduction

The C and C++ concept of function pointer was very useful when programming for the Microsoft Windows operating systems because the Win32 library relies on the concept of callback functions to process messages. For this reason and because of their functionality, callback functions were carried out in the .NET Framework but they were defined with the name of delegate.

A delegate is a special type of user-defined variable that is declared globally, like a class. In fact, a delegate is created like an interface but appearing as a method. Based on this, a delegate provides a template for a method, like an interface provides a template for a class. Like an interface, a delegate is not defined. Its role is to show what a useful method would look like. To support this concept, a delegate can provide all the necessary information that would be used on a method. This includes a return type, either no argument or one or more arguments.

Declaring a Delegate

To declare a delegate, you use the delegate keyword. The basic formula used to create a delegate is:

[attributes] [modifiers] delegate result-type identifier ([formal-parameters]);

The attributes factor can be a normal C# attribute.

The modifier can be one or an appropriate combination of the following keywords: new, public, private, protected, or internal.

The delegate keyword is required.

The ReturnType can be any of the data types we have used so far. It can also be a type void or the name of a class.

The Name must be a valid name for a method.

Because a delegate is some type of a template for a method, you must use parentheses, required for every method. If this method will not take any argument, you can leave the parentheses empty.

After declaring a delegate, remember that it only provides a template for a method, not an actual method. In order to use it, you must define a method that would carry an assignment the method is supposed to perform. That method must have the same return type and the same (number of) argument(s), if any. For example, the above declared delegate is of  type void and it does not take any argument. After implementing the method, you can associate it to the name of the delegate. To do that, where you want to use the method, first declare a variable of the type of the delegate using the new operator. In the parentheses of the constructor, pass the name of the method. The declaration gives meaning to the delegate. To actually use the method, call the name of the delegate as if it were a defined method.

Here is an example that uses a delegate:

using System;
using System.Windows.Forms;

delegate void dlgSimple();

class Exercise : Form
{
	public Exercise()
	{
		dlgSimple Announce = new dlgSimple(Welcome);

		Announce();

		this.InitializeComponent();
	}

	private static void Welcome()
	{
	
	}

	private void InitializeComponent()
	{
	}

	static void Main()
	{
		Exercise form;

		form = new Exercise();
		Application.Run(form);
	}
}

You can also declare a delegate that returns a value. When defining a method that would be associated with the delegate, remember that that method must return the same type of value. Here is an example:

using System;
using System.Windows.Forms;

delegate double Addition();

class Exercise : Form
{
	public Exercise()
	{
		Addition  Add = new Addition(Plus);

		this.InitializeComponent();

		TextBox txtBox = new TextBox();
		Controls.Add(txtBox);

		txtBox.Text = Add().ToString();
	}

	private static double Plus()
	{
		double a = 248.66, b = 50.28;

		return a + b;
	}

	private void InitializeComponent()
	{
	}

	static void Main()
	{
		Exercise form;

		form = new Exercise();
		Application.Run(form);
	}
}

This would produce:

Delegate

Delegates and Classes

In the above introductions, we associated delegates with only methods of the main class. Because delegates are usually declared globally, that is outside of a class, they can be associated with a method of any class, provided the method has the same return type (and the same (number of) argument(s)) as the delegate. When we created the methods of the main class, we defined them as static, since all methods of the main class must be declared static.

Methods of any class can also be associated to delegates. Here is an example of two methods associated with a common delegate:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
    delegate double Multiplication();

    public class Cube
    {
        private double _side;

        public double Side
        {
            get { return _side; }

            set { _side = value; }
        }

        public Cube()
        {
            _side = 0;
        }

        public Cube(double s)
        {
            _side = s;
        }

        public double Area()
        {
            return 6 * Side * Side;
        }

        public double Volume()
        {
            return Side * Side * Side;
        }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            Cube SmallBox = new Cube(25.58);

            Multiplication AreaDefinition = new Multiplication(SmallBox.Area);
            Multiplication VolDefinition = new Multiplication(SmallBox.Volume);

            InitializeComponent();

            txtSide.Text = SmallBox.Side.ToString();
            txtArea.Text = AreaDefinition().ToString();
            txtVolume.Text = VolDefinition().ToString();
        }
    }
}

This would produce:

Delegate

Delegates Compositions

One of the characteristics that set delegates apart from C/C++ function pointers is that one delegate can be added to another using the + operation. This is referred to as composition. This is done by adding one delegate variable to another as in a = b + c.

A Delegate That Takes One of More Arguments

If you want to associate a method that takes arguments to a delegate, when declaring the delegate, provide the necessary argument(s) in its parentheses. Here is an example of a delegate that takes two arguments (and returns a value):

delegate double Addition(double x, double y);

When defining the associated method, besides returning the same type of value if not void, make sure that the method takes the same number of arguments. Here is an example:

using System;

delegate double Addition(double x, double y);

class Exercise
{
	private static double Plus(double a, double b)
	{
		return a + b;
	}

	static int Main()
	{
		return 0;
	}
}

Once again, to associate the method, declare a variable of the type of delegate and pass the name of the method to the constructor of the delegate. Here is an example:

Addition Add = new Addition(Plus);

Notice that only the name of the method is passed to the delegate. To actually use the delegate, when calling it, in its parentheses, provide a value for the argument(s) conform to the type specified when declaring the delegate.

A Delegate Passed as Argument

Using delegates, one method can be indirectly passed as argument to another method. To proceed, first declare the necessary delegate. Here is a example of such a delegate:

using System;

namespace GeometricFormulas
{
	public delegate double Squared(double x);

	public class Circle
	{
		private double _radius;

		public double Radius
		{
			get { return _radius; }

			set  { _radius = value; }
		}
	}
}

A delegate can be passed as argument to a method. Such an argument would be used as if it were a method itself. This means that, when accessed in the body of the method, the name of the delegate must be accompanied by parentheses and if the delegate takes an argument or argument, the argument(s) must be provided in the parentheses of the called delegate. Here is an example:

using System;

namespace GeometricFormulas
{
	public delegate double Squared(double x);

	public class Circle
	{
		private double _radius;

		public double Radius
		{
			get { return _radius; }

			set	{ _radius = value; }
		}

		public double Area(Squared sqd)
		{
			return sqd(_radius) * Math.PI;
		}
	}
}

After declaring a delegate, remember to define a method that implements the needed behavior of that delegate. Here is an example:

using System;

namespace GeometricFormulas
{
	public delegate double Squared(double x);

	public class Circle
	{
		private double _radius;

		public static double ValueTimesValue(double Value)
		{
			return Value * Value;
		}
	}
}

You can also define the associated method in another class, not necessarily in the class where the delegate would be needed. Once the method that implements the delegate is known, you can use the delegate as you see fit. To do that, you can declare a variable of the type of that delegate and pass the implementing method to its constructor. Here is an example:

using System;

namespace GeometricFormulas
{
	public delegate double Squared(double x);

	public class Circle
	{
		private double _radius;


		public static double ValueTimesValue(double Value)
		{
			return Value * Value;
		}

		public double Area(Squared sqd)
		{
			return sqd(_radius) * Math.PI;
		}

		public void CircleCharacteristics()
		{
			Squared Sq = new Squared(ValueTimesValue);
		}
	}

}

This declaration gives life to the delegate and can then be used as we have proceed with delegates so far.

Events

 

Introduction

Except for the main class of your program (the class that contains the Main() method), every class is mostly meant to interact with others, either to request values and methods of the other classes or to provide other classes with some values or a behavior they need. When a class A requests a value or service from another class B, class A is referred to as a client of class B. This relationship is important not simply because it establishes a relationship between both classes but also because class B should be ready to provide the value or behavior that a client needs at a certain time.

While a class B is asked to provide some values to, or perform some assignment(s) for, another class A, many things would happen. In fact, there is an order that the actions should follow. For example, during the lifetime of a program, that is, while a program is running, a class may be holding a value it can provide to its client but at another time, that value may not be available anymore, for any reason; nothing strange, this is just the ways it happens. Because different things can happen to a class B while a program is running, and because only class B would be aware of these, it must be able to signal to the other classes when there is a change. This is the basis of events: An event is an action that occurs on an object and affects it in a way that its clients must be made aware of. 

Event Creation

An event is declared like a pseudo-variable but based on a delegate. Therefore, to declare an event, you must have a delegate that would implement it. To actually declare an event, you use the event keyword with the following formula:

[attributes] [modifiers] event type declarator;
[attributes] [modifiers] event type member-name {accessor-declarations};

The attributes factor can be a normal C# attribute.

The modifier can be one or a combination of the following keywords: public, private, protected, internal, abstract, new, override, static, virtual, or extern.

The event keyword is required. It is followed by the name of the delegate that specifies its behavior. If the event is declared in the main class, it should be made static. Like everything in a program, an event must have a name. This would allow the clients to know what (particular) event occurred. Here is an example:

using System;

delegate void dlgSimple();

class Exercise
{
	public static event dlgSimple Simply;

	public static void Welcome()
	{
	
	}
}

When the event occurs, its delegate would be invoked. This specification is also referred to as hooking up an event. As the event occurs (or fires), the method that implements the delegate runs. This provides complete functionality for the event and makes the event ready to be used. Before using an event, you must combine it to the method that implements it. This can be done by passing the name of the method to the appropriate delegate, as we learned when studying delegates. You can then assign this variable to the event's name using the += operator. Once this is done, you can call the event. Here is an example:

using System;

delegate void dlgSimple();

class Exercise
{
	public static event dlgSimple Simply;

	public static void Welcome()
	{
	
	}

	public static void SayHello()
	{
		Simply();
	}

	static int Main()
	{
		Simply += new dlgSimple(Welcome);

		SayHello();

		return 0;
	}
}

Instead of the += operator used when initializing the event, you can implement add and remove of the event class. Here is an example:

using System;

delegate void dlgSimple();

class Exercise
{
	public event dlgSimple Simply
	{
		add
		{
			Simply += new dlgSimple(Welcome);
		}
		remove
		{
			Simply -= new dlgSimple(Welcome);
		}
	}

	public void Welcome()
	{
	
	}
}
 

Events and Windows Controls

 

Introduction

An application is made of various objects or controls. During the lifetime of an application, its controls regularly send messages to the operating system to do something on their behalf. These messages are similar to human messages and must be processed appropriately. Since most of the time more than one application is running on the computer, the controls of such an application also send messages to the operating system. As the operating system is constantly asked to perform these assignments, because there can be so many requests presented unpredictably, the operating system leaves it up to the controls to specify what they want, when they want it, and what behavior or result they expect. These scenarios work by the controls sending events.

Events in the .NET Framework are implements through the concepts of delegates and events as reviewed above. The most common events have already been created for the objects of the .NET Framework controls so much that you will hardly need to define new events, at least not in the beginning of your GUI programming adventure. Most of what you will do consists of implementing the desired behavior when a particular event fires. To start, you should know what events are available, when they, how they work, and what they produce.

To process a message, it (the message) must provide at least two pieces of information: What caused the message and what type of message is it? Both values are passed as the arguments to the event. Since all controls used in the .NET Framework are based on the Object class, the first argument must be an object type and represents the control that sent the message. 

As mentioned already, each control sends its own messages when necessary. Based on this, some messages are unique to some controls according to their roles. Some other messages are common to various controls, as they tend to provide similar actions. To manage such various configurations, the .NET Framework considers the messages in two broad categories.

As it happens, in order to perform their intended action(s), some messages do not require much information. For example, suppose your heart sends a message to the arm and states, “Raise your hand”. In this case, suppose everything is alright, the arm does not ask, “how do I raise my hand?”. It simply does because it knows how to, without any assistance. This type of message would be sent without much detailed information.

In the .NET Framework, a message that does not need particular information is carried by a class named EventArgs. In the event implementation, an EventArgs argument passed as the second parameter.

Consider another message where the arm carries some water and says to the mouth, “Swallow the following water”. The mouth would need the water that needs to be swallowed. Therefore, the message must be accompanied by additional information. Consider one more message where the heart says to the tongue, “Taste the following food but do not swallow it.” In order to process this message, the tongue would need the food and something to indicate that the food must not be swallowed. In this case, the message must be accompanied by detailed pieces of information.

When a message must carry additional information, the control that sent the message specifies that information by the name of the second argument. Because there are various types of messages like that, there are also different types of classes used to carry such messages. We will introduce each class when appropriate.

Event Implementation

Although there are different means of implementing an event, there are two main ways you can initiate its coding. If the control has a default event and if you double-click it, the studio would initiate the default event and open the Code Editor. The cursor would be positioned in the body of the event, ready to receive your instructions. Another technique you can use consists of displaying the first and clicking either the form or the control that will fire the event. Then, in the Properties window, click the Events button Events, and double-click the name of the event you want to use.

Overview of Events

 

Control Painting

While an application is opening on the screen or it needs to be shown, the operating system must display its controls. To do this, the controls colors and other visual aspects must be retrieved and restored. This is done by painting the control. If the form that hosts the controls was hidden somewhere such as behind another window or was minimized, when it comes up, the operating system needs to paint it (again).

When a control gets painted, it fires the Paint() event. The syntax of the Paint() event is:

public event PaintEventHandler Paint;

This event is carried by a PaintEventHandler delegate declared as follows:

public delegate void PaintEventHandler(object sender, PaintEventArgs e);

The PaintEventArgs parameter provides information about the area to be painted and the graphics object to paint.

Control Resizing

When using an application, one of the actions a user can perform on a form or a control is to change its size, provided the object allows it. Also, some time to time, if possible, the user can minimize, maximize, or restore a window. Whenever any of these actions occur, the operating system must keep track of the location and size of a control. For example, if a previously minimized or maximized window is being restored, the operating system must remember where the object was previously positioned and what its dimensions were.

When the size of a control has been changed, it fires the Resize() event, which is a EventArgs type.

Keyboard Messages

 

Introduction

A keyboard is a hardware object attached to the computer. By default, it is used to enter recognizable symbols, letters, and other characters on a control. Each key on the keyboard displays a symbol, a letter, or a combination of those, to give an indication of what the key could be used for.

The user typically presses a key, which sends a signal to a program. The signal is analyzed to find its meaning. If the program or control that has focus is equipped to deal with the signal, it may produce the expected result. If the program or control cannot figure out what to do, it ignores the action.

Each key has a code that the operating system can recognize.

The Key Down Message

When a keyboard key is pressed, a message called KeyDown is sent. KeyDown is a KeyEventArgs type interpreted through the KeyEventHandler class. This event is defined as follows:

private void Control_KeyDown(object sender, KeyEventArgs e)
{
		
}

This event is carried by the KeyEventArgs class defined in the System.Windows.Forms namespace. When you initiate this event, its KeyEventArgs argument provides as much information as possible to implement an appropriate behavior.

The Key Up Message

As opposed to the key down message that is sent when a key is down, the KeyUp message is sent when the user releases the key. The event is initiated as follows:

private void Control_KeyUp(object sender, KeyEventArgs e)
{
		
}

Like KeyDown, KeyUp is a KeyEventArgs type.

The Key Press Message

When the user presses a key, the KeyPress message is sent. Unlike the other two keyboard messages, the key pressed for this event should (must) be a character key. The event is initiated as follows:

private void Control_KeyPress(object sender, KeyPressEventArgs e)
{
		
}

The KeyPress event is carried by a KeyPressEventArgs type. The Handled property identifies whether this event was handled. The KeyChar property identifies the key that was pressed. It must be a letter or a recognizable symbol. Lowercase alphabetic characters, digits, and the lower base characters such as ; , ‘ [ ] - = / are recognized as they are. For an uppercase letter or an upper base symbols, the user must press Shift + the key. The character would be identified as one entity. This means that the symbol % typed with Shift + 5 is considered as one character.

Mouse Messages

 

Introduction

The mouse is another object that is attached to the computer allowing the user to interact with the machine. The mouse and the keyboard can each accomplish some tasks that are not normally available on the other or both can accomplish some tasks the same way.

The mouse is equipped with two, three, or more buttons. When a mouse has two buttons, one is usually located on the left and the other is located on the right. When a mouse has three buttons, one usually is in the middle of the other two. A mouse can also have a round object referred to as a wheel.

The mouse is used to select a point or position on the screen. Once the user has located an item, which could also be an empty space, a letter or a word, he or she would position the mouse pointer on it.

To actually use the mouse, the user would press either the left, the middle (if any), or the right button. If the user presses the left button once, this action is called Click. If the user presses the right mouse button, the action is referred to as Right-Click. If the user presses the left button twice and very fast, the action is called Double-Click.

If the mouse is equipped with a wheel, the user can position the mouse pointer somewhere on the screen and roll the wheel. This usually causes the document or page to scroll up or down, slow or fast, depending on how it was configured.

The Mouse Enter Message

Before using a control using the mouse, the user must first position the mouse on it. When this happens, the control fires a MouseEnter event. This event is initiated as follows:

private void Control_MouseEnter(object sender, EventArgs e)
{
		
}

This event is carried by an EventArgs argument but doesn't provide much information, only to let you know that the mouse was positioned on a control.

The Mouse Move Message

Whenever the mouse is being moved on top of a control, a mouse event is sent. This event is called MouseMove and is of type MouseEventArgs. It is initiated as follows:

private void Control_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
		
}

To implement this event, a MouseEventArgs argument is passed to the MouseEventHandler event implementer. The MouseEventArgs argument provides the necessary information about the event such as what button was clicked, how many times the button was clicked, and the location of the mouse.

The Mouse Hover Message

If the user positions the mouse on a control and hovers over it, a MouseHover event is fired. This event is initiated as follows:

private void Control_MouseHover(object sender, EventArgs e)
{
		
}

This event is carried by an EventArgs argument that doesn't provide further information than the mouse is hovering over the control.

The Mouse Down Message

Imagine the user has located a position or an item on a document and presses one of the mouse buttons. While the button is pressed and is down, a button-down message is sent. This event is called MouseDown and is of type MouseEventArgs and it is initiated as follows:

private void Control_MouseDown(object sender, MouseEventArgs e)
{
		
}

Like the other above mouse move event, the MouseDown event is carried by a MouseEventArgs argument.

The Mouse Up Message

After pressing a mouse button, the user usually releases it. While the button is being released, a button-up message is sent and it depends on the button, left or right, that was down. The event produced is MouseUp and it is initiated as follows:

private void Control_MouseUp(object sender, MouseEventArgs e)
{
		
}

Like the MouseDown message, the MouseUp event is of type MouseEventArgs which is passed to the MouseEventHandler for processing.

The Mouse Leave Message

When the user moves the mouse pointer away from a control, the control fires a MouseLeave event. This event is initiated as follows:

private void Form1_MouseLeave(object sender, EventArgs e)
{
		
}

Custom Message Implementation

 

Introduction

It is possible, but unlikely, that none of the available events featured in the controls of the .NET Framework suits your scenario. If this happens, you can implement your own event. To do this, you should first consult the Win32 documentation to identify the type of message you want to send.

There are two main techniques you can use to create or send a message that is not available in a control. You may also want to provide your own implementation of a message.

Sending a Custom Windows Message

In order to send a customized version of a Windows message from your control, you must first be familiar with the message. A message in the .NET Framework is based on the Message structure that is defined as follows:

public struct Message
{
    public IntPtr HWnd {get; set;}
    public IntPtr LParam {get; set;}
    public int Msg {get; set;}
    public IntPtr Result {get; set;}
    public IntPtr WParam {get; set;}
    public static Message Create(IntPtr hWnd,
                                                   int msg,
                                                   IntPtr wparam,
                                                   IntPtr lparam);
    public override bool Equals(object o);
    public override int GetHashCode();
    public object GetLParam(Type cls);
    public override string ToString();
}

One of the properties of this structure is Msg. This property holds a constant integer that is the message to send. The constant properties of messages are defined in the Win32 library. To send a message, you can declare a variable of type Message and define it. Once the variable is ready, you can pass it to the DefWndProc() method. Its syntax is:

protected virtual void DefWndProc(ref Message m);

To know the various messages available, you can consult the Win32 documentation but you need a way to get the constant value of that message. Imagine you want to send a message to close a form when the user clicks a certain button named Button1. If you have Microsoft Visual Studio (any version) installed in your computer, you can open the Drive:\Program Files\Microsoft Visual Studio\VC98\Include\WINUSER.H file. In this file, the WM_CLOSE message that carries a close action is defined with the hexadecimal constant 0x0010

WinUser

You can then define a constant integer in your code and initialize it with this same value. Here is an example:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        private const int WM_CLOSE = 0x0010;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Message msg = new Message();

            msg.HWnd = this.Handle;
            msg.Msg = WM_CLOSE;
            DefWndProc(ref msg);
        }
    }
}

Creating a Custom Event

To process a Windows message that is not available for a control you want to use in your application, you can implement its WndProc() method. Its syntax is:

protected virtual void WndProc(ref Message m);

In order to use this method, you must override it in your own class. Once again, you must know the message you want to send. This can be done by consulting the Win32 documentation. Here is an example that fires an OnMove event whenever the user tries to move a window (this prevents the user from performing the action):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        private const int WM_MOVE = 0x0003;

        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("User32.dll")]
        public static extern bool ReleaseCapture();

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_MOVE:
                    ReleaseCapture();
                    break;
            }

            base.WndProc(ref m);
        }
    }
}
 
 

Previous Copyright © 2008-2009, yevol.com Next