Click here to Skip to main content
15,886,812 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 274.7K   6.5K   340  
Create fast, flexible, and extensible IDE applications easily with Storm - it takes nearly no code at all!
using System;
using System.Drawing;
using System.Windows.Forms;

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

namespace Storm.TextEditor.Drawing.GDI
{
	public class GDISurface
		: GDIObject
	{
		#region Fields

		protected int width   = 0;
		protected int height  = 0;
		protected int tabSize = 4;

		protected IntPtr oldFont  = IntPtr.Zero;
		protected IntPtr oldPen   = IntPtr.Zero;
		protected IntPtr oldBrush = IntPtr.Zero;
		protected IntPtr oldBmp   = IntPtr.Zero;

		protected IntPtr hDC  = IntPtr.Zero;
		protected IntPtr hBMP = IntPtr.Zero;

		private WeakReference control = null;

		#endregion

		#region Properties

		private Control Control
		{
			get
			{
				if (control != null)
					return (Control)control.Target;
				else
					return null;
			}
			set { control = new WeakReference(value); }
		}

		public GDIFont Font
		{
			get
			{
				GDITextMetric tm = new GDITextMetric();
				string fontname = "                                                ";

				NativeGdi32Api.GetTextMetrics(hDC, ref tm);
				NativeGdi32Api.GetTextFace(hDC, 79, fontname);

				GDIFont gf = new GDIFont();
				gf.fontname = fontname;
				gf.bold = (tm.tmWeight > 400);
				gf.italic = (tm.tmItalic != 0);
				gf.underline = (tm.tmUnderlined != 0);
				gf.strikethrough = (tm.tmStruckOut != 0);

				gf.size = (int)(((double)(tm.tmMemoryHeight) / (double)tm.tmDigitizedAspectY) * 72);
				return gf;
			}
			set
			{
				IntPtr res = NativeGdi32Api.SelectObject(hDC, value.hFont);
				if (oldFont == IntPtr.Zero)
					oldFont = res;
			}
		}

		public IntPtr HDC
		{
			get { return hDC; }
		}

		public IntPtr HBMP
		{
			get { return hBMP; }
		}

		public Color TextForeColor
		{
			get { return NativeUser32Api.IntToColor(NativeGdi32Api.GetTextColor(hDC)); }
			set { NativeGdi32Api.SetTextColor(hDC, NativeUser32Api.ColorToInt(value)); }
		}

		public Color TextBackColor
		{
			get { return NativeUser32Api.IntToColor(NativeGdi32Api.GetBkColor(hDC)); }
			set { NativeGdi32Api.SetBkColor(hDC, NativeUser32Api.ColorToInt(value)); }
		}

		public bool FontTransparent
		{
			get { return NativeGdi32Api.GetBkMode(hDC) < 2; }
			set { NativeGdi32Api.SetBkMode(hDC, value ? 1 : 2); }
		}

		#endregion

		#region Methods

		#region Protected

		protected void Init(int width, int height, IntPtr hdc)
		{
			this.width = width;
			this.height = height;

			hDC = NativeGdi32Api.CreateCompatibleDC(hdc);
			hBMP = NativeGdi32Api.CreateCompatibleBitmap(hdc, width, height);

			IntPtr ret = NativeGdi32Api.SelectObject(hDC, hBMP);
			oldBmp = ret;

			if (hDC == (IntPtr)0)
				throw new Exception("Creation of hDC failed.");

			if (hDC == (IntPtr)0)
				throw new Exception("Creation of hBMP failed.");
		}

		protected override void Destroy()
		{
			if (oldBmp != IntPtr.Zero)
				NativeGdi32Api.SelectObject(hDC, oldBmp);

			if (oldFont != IntPtr.Zero)
				NativeGdi32Api.SelectObject(hDC, oldFont);

			if (oldPen != IntPtr.Zero)
				NativeGdi32Api.SelectObject(hDC, oldPen);

			if (oldBrush != IntPtr.Zero)
				NativeGdi32Api.SelectObject(hDC, oldBrush);

			if (hBMP != (IntPtr)0)
				NativeGdi32Api.DeleteObject(hBMP);

			if (hDC != (IntPtr)0)
				NativeGdi32Api.DeleteDC(hDC);

			hBMP = (IntPtr)0;
			hDC = (IntPtr)0;

			base.Destroy();
		}

		#endregion

		#region Public

		public Size MeasureTabbedString(string text, int tabSize)
		{
			uint ret = NativeUser32Api.GetTabbedTextExtent(hDC, text, text.Length, 1, ref tabSize);
			return new Size((int)(ret & 0xFFFF), (int)((ret >> 16) & 0xFFFF));
		}

		public Size DrawTabbedString(string text, int x, int y, int tabOrigin, int tabSize)
		{
			int ret = NativeUser32Api.TabbedTextOut(hDC, x, y, text, text.Length, 2, ref tabSize, tabOrigin);
			return new Size(ret & 0xFFFF, (ret >> 16) & 0xFFFF);
		}

		public void RenderTo(IntPtr hdc, int x, int y)
		{
			NativeGdi32Api.BitBlt(hdc, x, y, width, height, hDC, 0, 0, (int)GDIRop.SrcCopy);
		}

		public void RenderTo(GDISurface target, int x, int y)
		{
			this.RenderTo(target.hDC, x, y);
		}

		public void RenderTo(GDISurface target, int sourceX, int sourceY, int width, int height, int destX, int destY)
		{
			NativeGdi32Api.BitBlt(target.hDC, destX, destY, width, height, hDC, sourceX, sourceY, (int)GDIRop.SrcCopy);
		}

		public void RenderToControl(int x, int y)
		{
			IntPtr hdc = NativeUser32Api.ControlDC(this.Control);

			this.RenderTo(hdc, x, y);
			NativeUser32Api.ReleaseDC(this.Control.Handle, hdc);
		}

		public Graphics CreateGraphics()
		{
			return Graphics.FromHdc(hDC);
		}

		public void FillRect(GDIBrush brush, int x, int y, int width, int height)
		{
			RECTAPI gr;
			gr.Top = y;
			gr.Left = x;
			gr.Right = width + x;
			gr.Bottom = height + y;

			NativeUser32Api.FillRect(hDC, ref gr, brush.brush);
		}

		public void DrawFocusRect(int x, int y, int width, int height)
		{
			RECTAPI gr;
			gr.Top = y;
			gr.Left = x;
			gr.Right = width + x;
			gr.Bottom = height + y;

			NativeUser32Api.DrawFocusRect(hDC, ref gr);
		}

		public void FillRect(Color color, int x, int y, int width, int height)
		{
			GDIBrush b = new GDIBrush(color);
			this.FillRect(b, x, y, width, height);
			b.Dispose();
		}

		public void InvertRect(int x, int y, int width, int height)
		{
			RECTAPI gr;
			gr.Top = y;
			gr.Left = x;
			gr.Right = width + x;
			gr.Bottom = height + y;

			NativeUser32Api.InvertRect(hDC, ref gr);
		}

		public void DrawLine(GDIPen pen, Point p1, Point p2)
		{
			IntPtr oldpen = NativeGdi32Api.SelectObject(hDC, pen.hPen);

			POINTAPI gp;
			gp.X = 0;
			gp.Y = 0;

			NativeGdi32Api.MoveToEx(hDC, p1.X, p1.Y, ref gp);
			NativeGdi32Api.LineTo(hDC, p2.X, p2.Y);

			IntPtr crap = NativeGdi32Api.SelectObject(hDC, oldpen);
		}

		public void DrawLine(Color color, Point p1, Point p2)
		{
			GDIPen p = new GDIPen(color, 1);
			this.DrawLine(p, p1, p2);

			p.Dispose();
		}

		public void DrawRect(Color color, int left, int top, int width, int height)
		{
			GDIPen p = new GDIPen(color, 1);
			this.DrawRect(p, left, top, width, height);

			p.Dispose();
		}

		public void DrawRect(GDIPen pen, int left, int top, int width, int height)
		{
			this.DrawLine(pen, new Point(left, top), new Point(left + width, top));
			this.DrawLine(pen, new Point(left, top + height), new Point(left + width, top + height));
			this.DrawLine(pen, new Point(left, top), new Point(left, top + height));
			this.DrawLine(pen, new Point(left + width, top), new Point(left + width, top + height + 1));
		}

		public void Clear(Color color)
		{
			GDIBrush b = new GDIBrush(color);
			this.Clear(b);

			b.Dispose();
		}

		public void Clear(GDIBrush brush)
		{
			this.FillRect(brush, 0, 0, width, height);
		}

		public void Flush()
		{
			NativeGdi32Api.GdiFlush();
		}

		public void SetBrushOrg(int x, int y)
		{
			POINTAPI p;
			p.X = 0;
			p.Y = 0;

			NativeGdi32Api.SetBrushOrgEx(hDC, x, y, ref p);
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of GDISurface.
		/// </summary>
		public GDISurface(IntPtr hDC)
		{
			this.hDC = hDC;
		}

		/// <summary>
		/// Initializes a new instance of GDISurface.
		/// </summary>
		public GDISurface(int width, int height)
		{
			IntPtr deskDC = NativeUser32Api.GetDC(new IntPtr(0));
			this.Init(width, height, deskDC);
			this.Create();
		}

		/// <summary>
		/// Initializes a new instance of GDISurface.
		/// </summary>
		public GDISurface(int width, int height, IntPtr hdc)
		{
			this.Init(width, height, hdc);
			this.Create();
		}

		/// <summary>
		/// Initializes a new instance of GDISurface.
		/// </summary>
		public GDISurface(int width, int height, GDISurface surface)
		{
			this.Init(width, height, surface.hDC);
			this.Create();
		}

		/// <summary>
		/// Initializes a new instance of GDISurface.
		/// </summary>
		public GDISurface(int width, int height, Control compatibleControl, bool bindControl)
		{
			IntPtr hDCControk = NativeUser32Api.ControlDC(compatibleControl);
			this.Init(width, height, hDCControk);
			NativeUser32Api.ReleaseDC(compatibleControl.Handle, hDCControk);

			if (bindControl)
				this.Control = compatibleControl;

			this.Create();
		}
	}
}

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