⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shape.cs

📁 Wince没有提供不规则形状窗口的函数, 这个sample可以在在Wince上实现不规则窗口,全部源代码非常易于移植.
💻 CS
字号:
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using OpenNETCF.Windows.Forms;
using OpenNETCF.Win32;
using OpenNETCF.Drawing;


namespace OpenNETCF.Windows.Graphics
{
	/// <summary>
	/// Used to create irregularly shaped regions from a bitmap. 
	/// Shape class loads a bitmap and eliminates all areas comprised with white pixels. 
	/// It can then apply the region to a given control.
	/// </summary>
	public class Shape: IDisposable
	{
		private IntPtr m_hRgn;

		/// <summary>
		/// Retuns a handle to the region
		/// </summary>
		public IntPtr Region { get { return m_hRgn; } }

		/// <summary>
		/// Constructs a Shape object out of a bitmap
		/// </summary>
		/// <param name="st">Stream containg a valid bitmap (BMP only)</param>
		public Shape(Stream st)
		{
			RebuildRegion(st);
		}
		private void RebuildRegion(Stream st)
		{
			if ( m_hRgn != IntPtr.Zero )
				Utils.DeleteObject(m_hRgn);

			int cx = 0, cy = 0;

			if ( st == null )
				throw new NullReferenceException();
			BitmapData b = Utils.GetBitmapData(st);
			st.Seek(0, SeekOrigin.Begin);
			for( int py = 0; py < b.Height; py ++ )
			{
				int px = 0;
				int clrWhite = 0xffffff & ( ~(int)(0xffffffff << b.BitCount) );
				while ( px < b.Width )
				{
					while( px < b.Width && b.GetPixel(px, py) == clrWhite )
						px ++;
					if ( px >= b.Width )
						break;
					int px0 = px;
					while( px < b.Width && b.GetPixel(px, py) != clrWhite )
						px ++;
					if ( m_hRgn == IntPtr.Zero )
					{
						m_hRgn = Utils.CreateRectRgn(cx + px0 - 1, cy + py - 1, cx + px - 1, cy + py);
						bool bRet = Utils.PtInRegion(m_hRgn, cx+px0, cy+py);
						bRet = Utils.PtInRegion(m_hRgn, cx+px0, cy+py+1);
						bRet = false;
					}
					else
					{
						IntPtr hRgn2 = Utils.CreateRectRgn(cx + px0 - 1, cy + py - 1, cx + px - 1, cy + py);
						Utils.CombineRgn(m_hRgn, m_hRgn, hRgn2, RgnMode.RGN_OR);
						Utils.DeleteObject(hRgn2);
					}
				}

			}
		}

		/// <summary>
		/// Retrieves control's HWND and sets its shape
		/// </summary>
		/// <param name="c">Control to set shape</param>
		public void Apply(Control c)
		{
			if ( c == null )
				throw new ArgumentException();
			c.Capture = true;
			IntPtr hWnd = Win32Window.GetCapture();
			if ( hWnd == IntPtr.Zero )
				throw new InvalidOperationException("Could not obtain HWND of the given control");
			c.Capture = false;
			Utils.SetWindowRgn(hWnd, this.Region, 1);
		}
		#region IDisposable Members

		public void Dispose()
		{
			Utils.DeleteObject(m_hRgn);
		}

		#endregion
	}

	public class Utils
	{
		public const int HTCAPTION    = 2;
		public static BitmapData GetBitmapData(Stream st)
		{
			BitmapData data = new BitmapData();
			BinaryReader rdr = new BinaryReader(st);
			rdr.BaseStream.Seek(0, SeekOrigin.Begin);
			// Check that the BMP file signatrure is present
			if ( rdr.ReadByte() != 0x42 || rdr.ReadByte() != 0x4D )
				throw new ArgumentException("Invalid bitmap. Only BMP files are accepted.");
			rdr.BaseStream.Seek(10, SeekOrigin.Begin);
			data.Start = rdr.ReadInt32();
			rdr.ReadInt32();
			data.Width = rdr.ReadInt32();
			data.Height = rdr.ReadInt32();
			rdr.ReadInt16();
			data.BitCount = rdr.ReadInt16();

			rdr.BaseStream.Seek(data.Start, SeekOrigin.Begin);
			data.scLine = (data.Width * (data.BitCount >> 3) + 3  >> 2) << 2;
			data.Data = rdr.ReadBytes(data.scLine * data.Height);
			return data;
			
		}


		[DllImport("coredll")]
		extern static public IntPtr DeleteObject(IntPtr hObj);
		
		[DllImport("coredll")]
		extern static public int SetWindowRgn(
			IntPtr hWnd, 
			IntPtr hRgn, 
			int bRedraw
			);


		[DllImport("coredll")]
		extern static public int CombineRgn(
			IntPtr hrgnDest, 
			IntPtr hrgnSrc1, 
			IntPtr hrgnSrc2, 
			RgnMode fnCombineMode
			);

		[DllImport("coredll")]
		extern static public IntPtr CreateRectRgn( 
			int nLeftRect, 
			int nTopRect, 
			int nRightRect, 
			int nBottomRect
			);

		[DllImport("coredll")]
		extern static public IntPtr ExtCreateRegion(
			IntPtr lpXform,
			int nCount,
			int[] lpRgnData  );

		[DllImport("coredll")]
		extern static public int GetRgnBox(
			IntPtr hrgn, 
			out RECT rc
			);

		[DllImport("coredll")]
		extern static public bool PtInRegion(
			IntPtr hrgn, 
			int X, 
			int Y
			); 

	}

	public struct RECT
	{
		public int l;
		public int t;
		public int r;
		public int b;
	}

	public struct BitmapData
	{
		public int GetPixel(int x, int y)
		{
			switch( BitCount )
			{
				case 1:
				case 2:
				case 4:
				case 16:
				case 32:
					throw new NotSupportedException("Bitmap must be 8, or 24 bpp");
				case 8:
					return Data[(Height - y - 1)*scLine+x];
				case 24:
					int p = ((Height - y - 1)*scLine+x * 3);
					return (Data[p] << 16) + (Data[p+1] << 8) + (Data[p + 2]);
				default:
					throw new NotSupportedException("Bitmap must be 8, or 24 bpp");
			}
		}
		public int Width;
		public int scLine;
		public int Height;
		public int Start;
		public int BitCount;
		public byte [] Data;
	}
	public enum RgnMode
	{
		
		RGN_AND            = 1,
		RGN_OR             = 2,
		RGN_XOR            = 3,
		RGN_DIFF           = 4,
		RGN_COPY           = 5,
		RGN_MIN            = RGN_AND,
		RGN_MAX            = RGN_COPY,
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -