Click here to Skip to main content
15,896,915 members
Articles / Programming Languages / C#

A Managed C++ Wrapper Around the Windows XP Theme API

Rate me:
Please Sign up or sign in to vote.
4.97/5 (31 votes)
27 Aug 2003CPOL5 min read 308.9K   5.5K   72  
Using the XP Theme API safely on any OS from C#
//  � Copyright 2002, Pierre ARNAUD, OPaC bright ideas, Switzerland.
//    All rights reserved.
using System.Drawing;

using System.Windows.Forms.Themes;

namespace OPaC.Themed.Forms
{
	public class CheckBox : System.Windows.Forms.CheckBox
	{
		private WindowTheme m_WindowTheme = null;

		public CheckBox()
		{
			this.BackColor = System.Drawing.Color.Transparent;
			this.FlatStyle = System.Windows.Forms.FlatStyle.Standard;

			ThemeInfo t = new ThemeInfo();
			if ( t.Count > 0 )
			{
				m_WindowTheme = t["BUTTON"];
			}
		}
		
		public bool									UseTheme
		{
			get
			{
				return UxTheme.IsAppThemed () && !this.DesignMode;
			}
		}

		protected string							ModeName
		{
			get
			{
				if (this.Enabled)
				{
					if (this.is_pressed && this.is_hot)
					{
						switch (this.CheckState)
						{
							case System.Windows.Forms.CheckState.Checked:
								return "CHECKEDPRESSED";
							case System.Windows.Forms.CheckState.Unchecked:
								return "UNCHECKEDPRESSED";
							default:
								return "MIXEDPRESSED";
						}
					}
					else if (this.is_hot || this.is_pressed)
					{
						switch (this.CheckState)
						{
							case System.Windows.Forms.CheckState.Checked:
								return "CHECKEDHOT";
							case System.Windows.Forms.CheckState.Unchecked:
								return "UNCHECKEDHOT";
							default:
								return "MIXEDHOT";
						}
					}
					else
					{
						switch (this.CheckState)
						{
							case System.Windows.Forms.CheckState.Checked:
								return "CHECKEDNORMAL";
							case System.Windows.Forms.CheckState.Unchecked:
								return "UNCHECKEDNORMAL";
							default:
								return "MIXEDNORMAL";
						}
					}
				}
				else
				{
					switch (this.CheckState)
					{
						case System.Windows.Forms.CheckState.Checked:
							return "CHECKEDDISABLED";
						case System.Windows.Forms.CheckState.Unchecked:
							return "UNCHECKEDDISABLED";
						default:
							return "MIXEDDISABLED";
					}
				}
			}
		}
		
		public System.Drawing.Color					TextColor
		{
			get
			{
//				int r, g, b;
//
//				UxTheme theme = UxTheme.OpenTheme( this, "CHECKBOX" );
//				ThemeInfo
//
//				if (GetTextColor ("BUTTON", "CHECKBOX", this.ModeName, out r, out g, out b))
//				{
//					return System.Drawing.Color.FromArgb (r, g, b);
//				}
			
				return System.Drawing.Color.Black;
			}
		}
		
		protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
		{
			if (this.UseTheme)
			{
				int ox = (int) e.Graphics.VisibleClipBounds.Left;
				int oy = (int) e.Graphics.VisibleClipBounds.Top;
				int dx = (int) e.Graphics.VisibleClipBounds.Width;
				int dy = (int) e.Graphics.VisibleClipBounds.Height;
				
				if (((ox != 0) || (oy != 0) || (dx != this.Width) || (dy != this.Height)) &&
					(this.PaintChildrenBackground (e.Graphics, this, new System.Drawing.Rectangle (ox, oy, dx, dy))))
				{
				}
				else
				{
					this.ThemedPaintBackground (e.Graphics, 0, 0, this.Width, this.Height);
				}
			}
			else
			{
				base.OnPaint (e);
			}
		}

		protected override void OnTextChanged(System.EventArgs e)
		{
			base.OnTextChanged (e);
			this.string_width = -1;
		}

		protected override void OnFontChanged(System.EventArgs e)
		{
			base.OnFontChanged (e);
			this.string_width = -1;
		}
		
		protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseDown (e);
			this.is_pressed = true;
			this.Invalidate ();
		}

		protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseUp (e);
			this.is_pressed = false;
			this.Invalidate ();
		}

		protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseMove (e);
			
			int x = e.X;
			int y = e.Y;
			
			bool hot;
			
			if ((x >= 0) && (x < this.Width) && (y >= 0) && (y < this.Height))
			{
				hot = true;
			}
			else
			{
				hot = false;
			}
			
			if (this.is_hot != hot)
			{
				this.is_hot = hot;
				this.Invalidate ();
			}
		}
		
		protected override void OnMouseEnter(System.EventArgs e)
		{
			base.OnMouseEnter (e);
			this.is_hot = true;
			this.Invalidate ();
		}

		protected override void OnMouseLeave(System.EventArgs e)
		{
			base.OnMouseLeave (e);
			this.is_hot = false;
			this.Invalidate ();
		}
		
		private bool PaintChildrenBackground(System.Drawing.Graphics graphics, System.Windows.Forms.Control control, System.Drawing.Rectangle rect)
		{
			foreach (System.Windows.Forms.Control child in control.Controls)
			{
				System.Drawing.Rectangle find = new System.Drawing.Rectangle (child.Location, child.Size);
						
				if (find.Contains (rect))
				{
					System.Drawing.Rectangle child_rect = rect;
					child_rect.Offset (- child.Left, - child.Top);
					if (this.PaintChildrenBackground (graphics, child, child_rect))
					{
						return true;
					}
					
					this.ThemedPaintBackground (graphics, child.Left, child.Top, child.Width, child.Height);
					return true;
				}
			}
			
			return false;
		}
		
		private void ThemedPaintBackground(System.Drawing.Graphics graphics, int ox, int oy, int dx, int dy)
		{
			int h = this.Font.Height;
			int w = this.GetCaptionWidth (graphics);
			
			//System.IntPtr hdc = graphics.GetHdc ();
			
			try
			{
				Rectangle rect = new Rectangle( ox, oy, dx, dy );
				UxTheme.DrawThemeParentBackground( this, graphics, rect );
				ThemePart p = m_WindowTheme.Parts["CHECKBOX"];
				ThemePartState s = p.States[ModeName];

				Rectangle rect1 = new Rectangle( 0, 0, 14, this.Height );
				s.DrawBackground( graphics, rect1, rect );
//				OPaC.uxTheme.Wrapper.DrawThemeParentBackground (this.Handle, hdc, ox, oy, dx, dy);
//				OPaC.uxTheme.Wrapper.DrawBackground ("BUTTON", "CHECKBOX", this.ModeName, hdc, 0, 0, 14, this.Height, ox, oy, dx, dy);
			}
			catch
			{
			}
//			finally
//			{
//				//graphics.ReleaseHdc (hdc);
//			}
			
			graphics.DrawString (this.Text, this.Font, new System.Drawing.SolidBrush (this.TextColor), 14.0f, 0.0f);
			if (this.Focused)
			{
				System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle (15, 0, w, h+2);
				System.Windows.Forms.ControlPaint.DrawFocusRectangle (graphics, rectangle);
			}
		}
		
		private int GetCaptionWidth(System.Drawing.Graphics graphics)
		{
			if (this.string_width == -1)
			{
				this.string_width = OPaC.Themed.Forms.HelperTools.MeasureDisplayStringWidth (graphics, this.Text, this.Font);
			}
			
			return this.string_width;
		}
		
		private int	string_width = -1;
		private bool is_hot = false;
		private bool is_pressed = false;
	}
}

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 Code Project Open License (CPOL)


Written By
Team Leader Starkey Laboratories
United States United States
The first computer program I ever wrote was in BASIC on a TRS-80 Model I and it looked something like:
10 PRINT "Don is cool"
20 GOTO 10

It only went downhill from there.

Hey look, I've got a blog

Comments and Discussions