Click here to Skip to main content
15,892,927 members
Articles / Multimedia / GDI+

Controls of an arbitrary shape

Rate me:
Please Sign up or sign in to vote.
3.25/5 (7 votes)
6 Jul 20064 min read 42.8K   1.4K   31  
The article describes the use and the principle of operation of control of an arbitrary shape.
///////////////////////////////////////////////////////////////////////////////
//
//  File:           skinbutton.cs
//
//  Facility:		The unit contains the SkinButton class.
//
//  Abstract:       The SkinButton control. 
//
//  Environment:    VC 7.1
//
//  Author:         KB_Soft Group Ltd.
//
///////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using KBSoft.Components.Design;
using KBSoft.Components.Common;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Threading;

namespace KBSoft.Components
{
	/// <summary>
	/// the class defining the button of an arbitrary shape.
	/// </summary>
	[ 
	ToolboxItem(true)
	]
	public class SkinButton : KBSoft.Components.SkinControl
	{
		#region Fields

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// the image for displaying the button in the normal state.
		/// </summary>
		private Bitmap normalImage = null;
		/// <summary>
		/// the image for displaying the button being pressed.
		/// </summary>
		private Bitmap pressedImage = null;

		/// <summary>
		/// the image for displaying the button in the hot state.
		/// </summary>
		private Bitmap hotImage = null;
		/// <summary>
		/// the image for displaying the button being disabled.
		/// </summary>
		private Bitmap disabledImage = null;

		/// <summary>
		/// the current image that is displayed (depending on the state).
		/// </summary>
		private Bitmap displayedImage = null;

		/// <summary>
		/// the image that is displayed on the background for correct merging with
		/// the semi-transparent fields in displayedImage.
		/// </summary>
		private Bitmap backgroundImage = null;

		#endregion

		#region Constructors

		/// <summary>
		/// the constructor setting the event handlers.
		/// </summary>
		public SkinButton()
		{
			InitializeComponent();
			this.Paint += new PaintEventHandler(SkinButton_Paint);
			this.MouseDown +=new MouseEventHandler(SkinButton_MouseDown);
			this.MouseUp += new MouseEventHandler(SkinButton_MouseUp);
			this.MouseMove +=new MouseEventHandler(SkinButton_MouseMove);
			this.MouseLeave += new EventHandler(SkinButton_MouseLeave);
		}

		#endregion

		#region Properties

		/// <summary>
		/// the image for the normal state.
		/// </summary>
		public Bitmap NormalImage
		{
			get{ return this.normalImage; }
			set
			{ 
				this.normalImage = value;
				this.displayedImage = value;
				Invalidate();
			}
		}

		/// <summary>
		/// The image for the pressed state.
		/// </summary>
		public Bitmap PressedImage
		{
			get{ return this.pressedImage; }
			set
			{ 
				this.pressedImage = value;
				Invalidate();
			}
		}

		/// <summary>
		/// The image for the hot state.
		/// </summary>
		public Bitmap HotImage
		{
			get{ return this.hotImage; }
			set
			{ 
				this.hotImage = value; 
				Invalidate();
			}
		}

		/// <summary>
		/// The image for the disabled state.
		/// </summary>
		public Bitmap DisabledImage
		{
			get{ return this.disabledImage; }
			set
			{ 
				this.disabledImage = value; 
				Invalidate();
			}
		}

		/// <summary>
		/// The property returns or sets the background image for the button.
		/// </summary>
		[
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
		Browsable(false)]

		public Bitmap BackImage
		{
			get{ return this.backgroundImage; }
			set{ this.backgroundImage = value; }
		}

		#endregion

		#region Methods

		/// <summary>
		/// Freeing resources.
		/// </summary>
		/// <param name="disposing"></param>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}


				if(normalImage != null)
					this.normalImage.Dispose();

				if(pressedImage != null)
					this.pressedImage.Dispose();

				if(disabledImage != null)
					this.disabledImage.Dispose();

				if( hotImage != null )
					this.hotImage.Dispose();

			}
			base.Dispose( disposing );
		}

		#region Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// SkinButton
			// 
			this.Name = "SkinButton";
			this.EnabledChanged += new System.EventHandler(this.SkinButton_EnabledChanged);

		}
		#endregion

		/// <summary>
		/// Drawing the button.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_Paint(object sender, PaintEventArgs e)
		{
			if( this.backgroundImage != null )
				e.Graphics.DrawImage( this.backgroundImage,0,0, this.Bounds, GraphicsUnit.Pixel );


			if( this.displayedImage != null )
			{
				e.Graphics.DrawImage( this.displayedImage,0,0 );
			}
		}

		/// <summary>
		/// The function defining the reaction on the message of clicking the button and
		/// setting it to the pressed stste..
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_MouseDown(object sender, MouseEventArgs e)
		{
			this.displayedImage = this.pressedImage;
			
			Invalidate();
			Update();
			
			if( ButtonClicked != null )
				ButtonClicked(this, new EventArgs() );

		}

		/// <summary>
		/// The function reacting the mouse button release.
		/// Sets the button to the non-pressed state.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_MouseUp(object sender, MouseEventArgs e)
		{
			if( !this.Enabled )
				return;

			this.displayedImage = this.normalImage;
			Invalidate();
			Update();
		}

		/// <summary>
		/// The function reacting the button swithcing beetween
		/// the Disable and Enable states.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_EnabledChanged( object sender, System.EventArgs e )
		{
			if( this.Enabled )
				this.displayedImage = this.normalImage;
			else
				this.displayedImage = this.disabledImage;

			Invalidate();
			Update();
		}

		/// <summary>
		/// The reaction to mouse moving over the button. Sets the button to the
		/// focused state.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_MouseMove( object sender, MouseEventArgs e )
		{
			if( !this.Enabled )
				return;

			if( e.Button != MouseButtons.Left )
			{
				this.displayedImage = this.hotImage;
				Invalidate();
				this.Update();
			}
		}

		/// <summary>
		/// The reaction to mouse cursor leaving the button area.
		/// Sets the button to the normal state.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SkinButton_MouseLeave(object sender, EventArgs e)
		{
			if( !this.Enabled )
				return;

			this.displayedImage = this.normalImage;
			Invalidate();
			this.Update();
		}

		#endregion

		#region Events

		/// <summary>
		/// The event that is called when the button area is clicked by the left mouse button.
		/// </summary>
		public event EventHandler ButtonClicked;

		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Russian Federation Russian Federation
Alexandr Golovanov is a .NET developer at KB_Soft Group, an offshore software development company located in Russia, Novosibirsk. Here he has worked
on various .NET projects.

Comments and Discussions