建网站找兴田德润,杭州 网站建设公司排名,励志做的很好的网站,缝纫网站做洗衣机罩三、不规则窗体
概况
之前学习的 LayeredSkin 看到里面有个异形窗口#xff0c;比较感兴趣#xff0c;所以就找一下资料研究一下。不规则窗体学习有一个比较好的例子#xff0c;叫 GoldFishProject#xff0c;是一条鱼金鱼在屏幕上游。
不规则窗口示例代码 GoldFishProj…三、不规则窗体
概况
之前学习的 LayeredSkin 看到里面有个异形窗口比较感兴趣所以就找一下资料研究一下。不规则窗体学习有一个比较好的例子叫 GoldFishProject是一条鱼金鱼在屏幕上游。
不规则窗口示例代码 GoldFishProject 游动金鱼的学习代码
如果没有积分也可以关注我获取哟~
现学习了两种实现方式
UpdateLayeredWindowGraphicsPath
1.UpdateLayeredWindow
这种方式实现的不规则窗口很平滑没有锯齿可以带半透明的效果但是不在响应 paint 方法绘制不了窗体上的控件效果图
代码如下
窗体代码
public partial class UpdateLayeredWindowForm : Form
{bool haveHandle false;//窗体句柄创建完成public UpdateLayeredWindowForm(){InitializeComponent();}private void UpdateLayeredWindowForm_Load(object sender, EventArgs e){FormBorderStyle FormBorderStyle.None;//取消窗口边框SetBits(new Bitmap(BackgroundImage));//设置不规则窗体FormMovableEvent();//设置拖动窗体移动}#region 防止窗体闪屏private void InitializeStyles(){SetStyle(ControlStyles.UserPaint |ControlStyles.AllPaintingInWmPaint |ControlStyles.OptimizedDoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.SupportsTransparentBackColor, true);SetStyle(ControlStyles.Selectable, false);UpdateStyles();} #endregion#region 句柄创建事件protected override void OnHandleCreated(EventArgs e){InitializeStyles();//设置窗口样式、双缓冲等base.OnHandleCreated(e);haveHandle true;} #endregion#region 设置窗体样式protected override CreateParams CreateParams{get{CreateParams cParms base.CreateParams;cParms.ExStyle | 0x00080000; // WS_EX_LAYEREDreturn cParms;}} #endregion#region 设置不规则窗体public void SetBits(Bitmap bitmap){if (!haveHandle) return;if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))throw new ApplicationException(The picture must be 32bit picture with alpha channel.);IntPtr oldBits IntPtr.Zero;IntPtr screenDC Win32.GetDC(IntPtr.Zero);IntPtr hBitmap IntPtr.Zero;IntPtr memDc Win32.CreateCompatibleDC(screenDC);try{Win32.Point topLoc new Win32.Point(Left, Top);Win32.Size bitMapSize new Win32.Size(bitmap.Width, bitmap.Height);Win32.BLENDFUNCTION blendFunc new Win32.BLENDFUNCTION();Win32.Point srcLoc new Win32.Point(0, 0);hBitmap bitmap.GetHbitmap(Color.FromArgb(0));oldBits Win32.SelectObject(memDc, hBitmap);blendFunc.BlendOp Win32.AC_SRC_OVER;blendFunc.SourceConstantAlpha 255;//这里设置窗体绘制的透明度blendFunc.AlphaFormat Win32.AC_SRC_ALPHA;blendFunc.BlendFlags 0;Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA);}finally{if (hBitmap ! IntPtr.Zero){Win32.SelectObject(memDc, oldBits);Win32.DeleteObject(hBitmap);}Win32.ReleaseDC(IntPtr.Zero, screenDC);Win32.DeleteDC(memDc);}} #endregion#region 无标题栏的窗口移动private Point mouseOffset; //记录鼠标指针的坐标private bool isMouseDown false; //记录鼠标按键是否按下/// summary/// 窗体移动监听绑定/// /summaryprivate void FormMovableEvent(){//窗体移动this.MouseDown new MouseEventHandler(Frm_MouseDown);this.MouseMove new MouseEventHandler(Frm_MouseMove);this.MouseUp new MouseEventHandler(Frm_MouseUp);}/// summary/// 窗体按下时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseDown(object sender, MouseEventArgs e){int xOffset;int yOffset;//点击窗体时记录鼠标位置启动移动if (e.Button MouseButtons.Left){xOffset -e.X;yOffset -e.Y;mouseOffset new Point(xOffset, yOffset);isMouseDown true;}}/// summary/// 窗体移动时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseMove(object sender, MouseEventArgs e){if (isMouseDown){//移动的位置计算Point mousePos Control.MousePosition;mousePos.Offset(mouseOffset.X, mouseOffset.Y);Location mousePos;}}/// summary/// 窗体按下并释放按钮时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseUp(object sender, MouseEventArgs e){// 修改鼠标状态isMouseDown的值// 确保只有鼠标左键按下并移动时才移动窗体if (e.Button MouseButtons.Left){//松开鼠标时停止移动isMouseDown false;//Top高度小于0的时候等于0if (this.Top 0){this.Top 0;}}}#endregion
}Win32API代码从金鱼的例子中引用的代码
//##########################################################################
//★★★★★★★ http://www.cnpopsoft.com ★★★★★★★
//★★ VB C# source code and articles for free !!! ★★
//★★★★★★★ Davidwu ★★★★★★★
//##########################################################################using System;
using System.Runtime.InteropServices;/// summary
/// Wind32API
/// /summary
internal class Win32
{#region 消息public const int MF_REMOVE 0x1000;public const int SC_RESTORE 0xF120; //还原public const int SC_MOVE 0xF010; //移动public const int SC_SIZE 0xF000; //大小public const int SC_MINIMIZE 0xF020; //最小化public const int SC_MAXIMIZE 0xF030; //最大化public const int SC_CLOSE 0xF060; //关闭 public const int WM_SYSCOMMAND 0x0112;public const int WM_COMMAND 0x0111;public const int GW_HWNDFIRST 0;public const int GW_HWNDLAST 1;public const int GW_HWNDNEXT 2;public const int GW_HWNDPREV 3;public const int GW_OWNER 4;public const int GW_CHILD 5;public const int WM_NCCALCSIZE 0x83;public const int WM_WINDOWPOSCHANGING 0x46;public const int WM_PAINT 0xF;public const int WM_CREATE 0x1;public const int WM_NCCREATE 0x81;public const int WM_NCPAINT 0x85;public const int WM_PRINT 0x317;public const int WM_DESTROY 0x2;public const int WM_SHOWWINDOW 0x18;public const int WM_SHARED_MENU 0x1E2;public const int HC_ACTION 0;public const int WH_CALLWNDPROC 4;public const int GWL_WNDPROC -4;public const int WS_SYSMENU 0x80000;public const int WS_SIZEBOX 0x40000;public const int WS_MAXIMIZEBOX 0x10000;public const int WS_MINIMIZEBOX 0x20000;#endregion[StructLayout(LayoutKind.Sequential)]public struct Size{public Int32 cx;public Int32 cy;public Size(Int32 x, Int32 y){cx x;cy y;}}[StructLayout(LayoutKind.Sequential, Pack 1)]public struct BLENDFUNCTION{public byte BlendOp;public byte BlendFlags;public byte SourceConstantAlpha;public byte AlphaFormat;}[StructLayout(LayoutKind.Sequential)]public struct Point{public Int32 x;public Int32 y;public Point(Int32 x, Int32 y){this.x x;this.y y;}}public const byte AC_SRC_OVER 0;public const Int32 ULW_ALPHA 2;public const byte AC_SRC_ALPHA 1;[DllImport(gdi32.dll, ExactSpelling true, SetLastError true)]public static extern IntPtr CreateCompatibleDC(IntPtr hDC);[DllImport(user32.dll, ExactSpelling true, SetLastError true)]public static extern IntPtr GetDC(IntPtr hWnd);[DllImport(gdi32.dll, ExactSpelling true)]public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj);[DllImport(user32.dll, ExactSpelling true)]public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport(gdi32.dll, ExactSpelling true, SetLastError true)]public static extern int DeleteDC(IntPtr hDC);[DllImport(gdi32.dll, ExactSpelling true, SetLastError true)]public static extern int DeleteObject(IntPtr hObj);[DllImport(user32.dll, ExactSpelling true, SetLastError true)]public static extern int UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pptSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);[DllImport(gdi32.dll, ExactSpelling true, SetLastError true)]public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount, IntPtr rgnData);[DllImport(user32)]public static extern int SendMessage(IntPtr hwnd, int msg, int wp, int lp);
}2.GraphicsPath
这种方式不能实现半透明效果有锯齿好处是能显示出控件贴个效果图感受下 代码如下
public partial class GraphicsPathForm : Form
{public GraphicsPathForm(){InitializeComponent();}private void GraphicsPathForm_Load(object sender, EventArgs e){TopMost true;//设置为最顶层FormBorderStyle FormBorderStyle.None;//取消窗口边框this.Region new Region(GetWindowRegion(new Bitmap(BackgroundImage)));//设置不规则窗体FormMovableEvent();//设置拖动窗体移动}#region 设置不规则窗体private GraphicsPath GetWindowRegion(Bitmap bitmap){Color TempColor;GraphicsPath gp new GraphicsPath();if (bitmap null) return null;for (int nX 0; nX bitmap.Width; nX){for (int nY 0; nY bitmap.Height; nY){TempColor bitmap.GetPixel(nX, nY);//if (TempColor.A ! 0)//去掉完全透明区域if (TempColor.A 255)//保留完全不透明的区域{gp.AddRectangle(new Rectangle(nX, nY, 1, 1));}}}return gp;} #endregion#region 无标题栏的窗口移动private Point mouseOffset; //记录鼠标指针的坐标private bool isMouseDown false; //记录鼠标按键是否按下/// summary/// 窗体移动监听绑定/// /summaryprivate void FormMovableEvent(){//窗体移动this.MouseDown new MouseEventHandler(Frm_MouseDown);this.MouseMove new MouseEventHandler(Frm_MouseMove);this.MouseUp new MouseEventHandler(Frm_MouseUp);}/// summary/// 窗体按下时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseDown(object sender, MouseEventArgs e){int xOffset;int yOffset;//点击窗体时记录鼠标位置启动移动if (e.Button MouseButtons.Left){xOffset -e.X;yOffset -e.Y;mouseOffset new Point(xOffset, yOffset);isMouseDown true;}}/// summary/// 窗体移动时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseMove(object sender, MouseEventArgs e){if (isMouseDown){//移动的位置计算Point mousePos Control.MousePosition;mousePos.Offset(mouseOffset.X, mouseOffset.Y);Location mousePos;}}/// summary/// 窗体按下并释放按钮时/// /summary/// param namesender/param/// param namee/paramprivate void Frm_MouseUp(object sender, MouseEventArgs e){// 修改鼠标状态isMouseDown的值// 确保只有鼠标左键按下并移动时才移动窗体if (e.Button MouseButtons.Left){//松开鼠标时停止移动isMouseDown false;//Top高度小于0的时候等于0if (this.Top 0){this.Top 0;}}}#endregion
}像第一种不能添加控件的方法要想实现显示控件的话下一个关键词就是“双层窗体”使用两层窗体来实现一个不规则窗体的效果大致步骤如下
底层是皮肤层使用第一种方法 上层是控件层使用第二种方法。