Click here to Skip to main content
15,892,746 members
Articles / Desktop Programming / Windows Forms

Storm - the world's best IDE framework for .NET

Rate me:
Please Sign up or sign in to vote.
4.96/5 (82 votes)
4 Feb 2010LGPL311 min read 276.9K   6.5K   340  
Create fast, flexible, and extensible IDE applications easily with Storm - it takes nearly no code at all!
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

using Storm.TextEditor.Drawing;
using Storm.TextEditor.Win32;
using Storm.TextEditor.Win32.Enums;
using Storm.TextEditor.Win32.Structs;

namespace Storm.TextEditor.Core
{
	[ToolboxItem(false)]
	public class Widget
		: Control
	{
		#region Fields

		private const int WS_EX_CLIENTEDGE = unchecked((int)0x00000200);
		private const int WS_BORDER        = unchecked((int)0x00800000);

		private ControlBorderStyle borderStyle = ControlBorderStyle.FixedSingle;
		private Color              borderColor = Color.Black;

		private Container components = null;
		private bool      runOnce    = true;

		#region Events

		/// <summary>
		/// Occurs when the Widget has been loaded.
		/// </summary>
		public event EventHandler Load = null;

		#endregion

		#endregion

		#region Properties

		/// <summary>
		/// Override CreateParams to tell the OS how we want the Widget to act.
		/// </summary>
		[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
		[Description("Override CreateParams to tell the OS how we want the Widget to act.")]
		protected override CreateParams CreateParams
		{
			get
			{
				CreateParams cp = base.CreateParams;

				if (BorderStyle == ControlBorderStyle.None)
					return cp;

				cp.ExStyle &= (~WS_EX_CLIENTEDGE);
				cp.Style &= (~WS_BORDER);

				return cp;
			}
		}

		/// <summary>
		/// Gets or sets the ControlBorderStyle of the Widget.
		/// </summary>
		[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
		[Category("Appearance"), Description("Gets or sets the ControlBorderStyle of the Widget.")]
		[DefaultValue(ControlBorderStyle.None)]
		public ControlBorderStyle BorderStyle
		{
			get { return borderStyle; }
			set
			{
				if (borderStyle != value)
				{
					if (Enum.IsDefined(typeof(ControlBorderStyle), value) == false)
						throw new InvalidEnumArgumentException("value", (int)value, typeof(ControlBorderStyle));

					borderStyle = value;
					this.UpdateStyles();
					this.Refresh();
				}
			}
		}

		/// <summary>
		/// Gets or sets the background image of the Widget.
		/// </summary>
		[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Obsolete("Do not use!", true)]
		[Description("Gets or sets the background image of the Widget.")]
		public new Image BackgroundImage
		{
			get { return base.BackgroundImage; }
			set { base.BackgroundImage = value; }
		}

		/// <summary>
		/// Gets the width of the Widget client excluding borders.
		/// </summary>
		[Browsable(false)]
		[Description("Gets the width of the Widget client excluding borders.")]
		public int ClientWidth
		{
			get { return this.WindowSize.Width - (this.BorderWidth * 2); }
		}

		/// <summary>
		/// Gets the height of the Widget client excluding borders.
		/// </summary>
		[Browsable(false)]
		[Description("Gets the height of the Widget client excluding borders.")]
		public int ClientHeight
		{
			get { return WindowSize.Height - (BorderWidth * 2); }
		}

		/// <summary>
		/// Gets the width of a border depending on the ControlBorderStyle.
		/// </summary>
		[Browsable(false)]
		[Description("Gets the width of a border depending on the ControlBorderStyle.")]
		public int BorderWidth
		{
			get
			{
				switch (borderStyle)
				{
					case ControlBorderStyle.None:
						return 0;
					case ControlBorderStyle.Sunken:
						return 2;
					case ControlBorderStyle.SunkenThin:
						return 1;
					case ControlBorderStyle.Raised:
						return 2;
					case ControlBorderStyle.Etched:
						return 2;
					case ControlBorderStyle.Bump:
						return 6;
					case ControlBorderStyle.FixedSingle:
						return 1;
					case ControlBorderStyle.FixedDouble:
						return 2;
					case ControlBorderStyle.RaisedThin:
						return 1;
					case ControlBorderStyle.Dotted:
						return 1;
					case ControlBorderStyle.Dashed:
						return 1;
				}

				return -1;
			}
		}

		/// <summary>
		/// Gets the size of the Widget.
		/// </summary>
		[Browsable(false)]
		[Description("Gets the size of the Widget.")]
		public Size WindowSize
		{
			get
			{
				RECTAPI s = new RECTAPI();
				NativeUser32Api.GetWindowRect(this.Handle, ref s);

				return new Size(s.Width, s.Height);
			}
		}

		/// <summary>
		/// Gets or sets the color of the border.
		/// </summary>
		[Category("Appearance"), Description("Gets or sets the color of the border.")]
		[DefaultValue(typeof(Color), "Black")]
		public Color BorderColor
		{
			get { return borderColor; }
			set
			{
				borderColor = value;

				this.UpdateStyles();
				this.Refresh();
			}
		}

		#endregion

		#region Methods

		#region Protected

		/// <summary>
		/// Raises the Load event.
		/// </summary>
		/// <param name="e">EventArgs.</param>
		protected virtual void OnLoad(EventArgs e)
		{
			if (this.Load != null)
				this.Load(this, e);

			this.Refresh();
		}

		/// <summary>
		/// Processes Windows messages from the OS.
		/// </summary>
		/// <param name="m">Windows message to process.</param>
		protected override unsafe void WndProc(ref Message m)
		{
			if (m.Msg == (int)WindowMessage.WM_NCPAINT)
				this.RenderBorder();
			else if (m.Msg == (int)WindowMessage.WM_SHOWWINDOW)
			{
				if (runOnce == true)
				{
					runOnce = false;
					this.OnLoad(null);

					this.UpdateStyles();
				}
				else
					this.UpdateStyles();
			}
			else if (m.Msg == (int)WindowMessage.WM_NCCALCSIZE)
			{
				if (m.WParam == (IntPtr)0)
				{
					RECTAPI* pRC = (RECTAPI*)m.LParam;
				}
				else if (m.WParam == (IntPtr)1)
				{
					_NCCALCSIZE_PARAMS* pNCP = (_NCCALCSIZE_PARAMS*)m.LParam;

					int t = pNCP->NewRect.Top + BorderWidth;
					int l = pNCP->NewRect.Left + BorderWidth;
					int b = pNCP->NewRect.Bottom - BorderWidth;
					int r = pNCP->NewRect.Right - BorderWidth;

					pNCP->NewRect.Top = t;
					pNCP->NewRect.Left = l;
					pNCP->NewRect.Right = r;
					pNCP->NewRect.Bottom = b;
				}
			}

			base.WndProc(ref m);
		}


		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
				{
					components.Dispose();
				}
			}

			base.Dispose(disposing);
		}

		#endregion

		#region Private

		/// <summary>
		/// Draws the border of the Widget.
		/// </summary>
		private void RenderBorder()
		{
			IntPtr hdc = NativeUser32Api.GetWindowDC(Handle);
			RECTAPI s = new RECTAPI();
			NativeUser32Api.GetWindowRect(Handle, ref s);

			using (Graphics g = Graphics.FromHdc(hdc))
			{
				DrawingTools.DrawBorder((ControlBorderStyle)(int)BorderStyle, BorderColor, g, new Rectangle(0, 0, s.Width, s.Height));
			}

			NativeUser32Api.ReleaseDC(Handle, hdc);
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of Widget.
		/// </summary>
		public Widget()
		{
			this.InitializeComponent();
		}

		#region Component 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()
		{
			// 
			// BaseControl
			// 
			Size = new System.Drawing.Size(272, 264);
		}

		#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, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)



Comments and Discussions