WinForm 无毛边异形窗体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace CCWin
{//绘图层partial class SkinForm : Form{//控件层private SkinMain Main;//带参构造public SkinForm(SkinMain main){InitializeComponent();//将控制层传值过来this.Main = main;//减少闪烁SetStyles();//初始化Init();}#region 初始化private void Init(){//最顶层TopMost = Main.TopMost;//是否在任务栏显示ShowInTaskbar = Main.SkinShowInTaskbar;//无边框模式FormBorderStyle = FormBorderStyle.None;//自动拉伸背景图以适应窗口BackgroundImageLayout = ImageLayout.Stretch;//还原任务栏右键菜单CommonClass.SetTaskMenu(this);//设置绘图层显示位置this.Location = new Point(Main.Location.X - Main.MainPosition.X, Main.Location.Y - Main.MainPosition.Y);//设置ICOIcon = Main.Icon;//是否显示ICOShowIcon = Main.ShowIcon;//设置大小Size = Main.SkinSize;//设置标题名Text = Main.Text;//设置背景Bitmap bitmaps = new Bitmap(Main.SkinBack, Size);if (Main.SkinTrankColor != Color.Transparent){bitmaps.MakeTransparent(Main.SkinTrankColor);}BackgroundImage = bitmaps;//控制层与绘图层合为一体Main.TransparencyKey = Main.SkinWhetherTank ? Color.Empty : Main.BackColor;Main.Owner = this;//绘制层窗体移动this.MouseDown += new MouseEventHandler(Frm_MouseDown);this.MouseMove += new MouseEventHandler(Frm_MouseMove);this.MouseUp += new MouseEventHandler(Frm_MouseUp);this.LocationChanged += new EventHandler(Frm_LocationChanged);//控制层层窗体移动Main.MouseDown += new MouseEventHandler(Frm_MouseDown);Main.MouseMove += new MouseEventHandler(Frm_MouseMove);Main.MouseUp += new MouseEventHandler(Frm_MouseUp);Main.LocationChanged += new EventHandler(Frm_LocationChanged);}#endregion#region 减少闪烁private void SetStyles(){SetStyle(ControlStyles.UserPaint |ControlStyles.AllPaintingInWmPaint |ControlStyles.OptimizedDoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.DoubleBuffer, true);//强制分配样式重新应用到控件上UpdateStyles();base.AutoScaleMode = AutoScaleMode.None;}#endregion#region 无标题栏的窗口移动private Point mouseOffset; //记录鼠标指针的坐标private bool isMouseDown = false; //记录鼠标按键是否按下//窗体按下时private void Frm_MouseDown(object sender, MouseEventArgs e){if (Main.SkinMobile){int xOffset;int yOffset;//点击窗体时,记录鼠标位置,启动移动if (e.Button == MouseButtons.Left){xOffset = -e.X;yOffset = -e.Y;mouseOffset = new Point(xOffset, yOffset);isMouseDown = true;}}}//窗体移动时private void Frm_MouseMove(object sender, MouseEventArgs e){if (Main.SkinMobile){//将调用此事件的窗口保存下Form frm = (Form)sender;//确定开启了移动模式后if (isMouseDown){//移动的位置计算Point mousePos = Control.MousePosition;mousePos.Offset(mouseOffset.X, mouseOffset.Y);//判断是绘图层还是控件层调用了移动事件,并作出相应回馈if (frm == this){Location = mousePos;}else{Main.Location = mousePos;}}}}//窗体按下并释放按钮时private void Frm_MouseUp(object sender, MouseEventArgs e){if (Main.SkinMobile){// 修改鼠标状态isMouseDown的值// 确保只有鼠标左键按下并移动时,才移动窗体if (e.Button == MouseButtons.Left){//松开鼠标时,停止移动isMouseDown = false;//Top高度小于0的时候,等于0if (this.Top < 0){this.Top = 0;Main.Top = 0 + Main.MainPosition.Y;}}}}//窗口移动时void Frm_LocationChanged(object sender, EventArgs e){//将调用此事件的窗口保存下Form frm = (Form)sender;if (frm == this){Main.Location = new Point(this.Left + Main.MainPosition.X, this.Top + Main.MainPosition.Y);}else{Location = new Point(Main.Left - Main.MainPosition.X, Main.Top - Main.MainPosition.Y);}}#endregion#region 还原任务栏右键菜单protected override CreateParams CreateParams{get{CreateParams cParms = base.CreateParams;cParms.ExStyle |= 0x00080000; // WS_EX_LAYEREDreturn cParms;}}public class CommonClass{[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]static extern int GetWindowLong(HandleRef hWnd, int nIndex);[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);public const int WS_SYSMENU = 0x00080000;public const int WS_MINIMIZEBOX = 0x20000;public static void SetTaskMenu(Form form){int windowLong = (GetWindowLong(new HandleRef(form, form.Handle), -16));SetWindowLong(new HandleRef(form, form.Handle), -16, windowLong | WS_SYSMENU | WS_MINIMIZEBOX);}}#endregion#region 不规则无毛边方法public void SetBits(){if (BackgroundImage != null){//绘制绘图层背景Bitmap bitmap = new Bitmap(BackgroundImage, base.Width, base.Height);if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))throw new ApplicationException("图片必须是32位带Alhpa通道的图片。");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(Width, 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 = Byte.Parse(Main.SkinOpacity.ToString());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 重载背景与拉伸更改时事件protected override void OnBackgroundImageChanged(EventArgs e){base.OnBackgroundImageChanged(e);SetBits();}protected override void OnResize(EventArgs e){base.OnResize(e);SetBits();}#endregion}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;namespace CCWin
{//控件层public partial class SkinMain : Form{//绘制层private SkinForm skin;public SkinMain(){InitializeComponent();//减少闪烁SetStyles();//初始化Init();}#region 初始化private void Init(){//不显示在Windows任务栏中ShowInTaskbar = false;}#endregion#region 减少闪烁private void SetStyles(){SetStyle(ControlStyles.UserPaint |ControlStyles.AllPaintingInWmPaint |ControlStyles.OptimizedDoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.DoubleBuffer, true);//强制分配样式重新应用到控件上UpdateStyles();base.AutoScaleMode = AutoScaleMode.None;}#endregion#region 全部显示public void AllShow(){this.Show();if (skin != null){skin.Show();}}#endregion#region 全部隐藏public void AllHide(){skin.Hide();this.Hide();}#endregion#region 变量属性private int _gradienttime = 200;[Category("Skin")][DefaultValue(200)][Description("控件层渐变特效时长(越小越快)")]public int GradientTime{get { return _gradienttime; }set{if (_gradienttime != value){_gradienttime = value < 0 ? 0 : value;}}}private Size _skinsize;[Category("Skin")][Description("绘图层窗口大小")]public Size SkinSize{get { return _skinsize; }set{if (_skinsize != value){_skinsize = value;if (skin != null){skin.Size = _skinsize;}//验证下宽高BindSize();//重新应用下绘图层背景BindBack();}}}//不显示FormBorderStyle属性[Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)][DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]public new FormBorderStyle FormBorderStyle{get { return base.FormBorderStyle; }set { base.FormBorderStyle = FormBorderStyle.None; }}private Bitmap _skinback;[Category("Skin")][Description("绘图层窗口背景")]public Bitmap SkinBack{get { return _skinback; }set{if (_skinback != value){_skinback = value;//重新应用下绘图层背景BindBack();if (skin != null){Bitmap bitmap = new Bitmap(SkinBack, SkinSize);if (SkinTrankColor != Color.Transparent){bitmap.MakeTransparent(SkinTrankColor);}skin.BackgroundImage = bitmap;}}}}private int _skinopacity = 255;[Browsable(true)][Category("Skin")][Description("绘图层窗口透明度(0-255)")][DefaultValue(255)]public int SkinOpacity{get { return _skinopacity; }set{if (_skinopacity != value){//如果赋值大与255,就等于255_skinopacity = value > 255 ? 255 : value;if (skin != null){skin.SetBits();}}}}private Point _mainposition;[Category("Skin")][Description("窗口在绘图层位置")]public Point MainPosition{get { return _mainposition; }set{if (_mainposition != value){_mainposition = value;//验证下宽高BindSize();//重新应用下绘图层背景BindBack();if (skin != null){Location = new Point(skin.Left + MainPosition.X, skin.Top + MainPosition.Y);}}}}private Color _skintrankcolor = Color.Transparent;[Category("Skin")][Description("绘图层需要透明的颜色")][DefaultValue(typeof(Color), "Color.Transparent")]public Color SkinTrankColor{get { return _skintrankcolor; }set{if (_skintrankcolor != value){_skintrankcolor = value;if (BackgroundImage != null){backs();}if (skin != null){Bitmap bitmap = new Bitmap(SkinBack, SkinSize);if (SkinTrankColor != Color.Transparent){bitmap.MakeTransparent(SkinTrankColor);}skin.BackgroundImage = bitmap;}}}}private bool _skinwhethertank = true;[Category("Skin")][Description("绘图层是否开启位图仿透明\r\n注意(SkinOpacity < 255时,此属性为False可达到背景透明,控件不透明的效果。)")][DefaultValue(typeof(bool), "true")]public bool SkinWhetherTank{get { return _skinwhethertank; }set{if (_skinwhethertank != value){_skinwhethertank = value;if (skin != null){BindBack();}}}}private bool _skinshowintaskbar = true;[Category("Skin")][Description("绘图层是否出现在Windows任务栏中。")][DefaultValue(typeof(bool), "true")]public bool SkinShowInTaskbar{get { return _skinshowintaskbar; }set{if (_skinshowintaskbar != value){_skinshowintaskbar = value;}}}private bool _skinmobile = true;[Category("Skin")][Description("窗体是否可以移动")][DefaultValue(typeof(bool), "true")]public bool SkinMobile{get { return _skinmobile; }set{if (_skinmobile != value){_skinmobile = value;}}}#endregion#region 绑定背景public void BindBack(){//绘图层背景属性不等于空,绘图层宽高不等于0,控件层宽高不等于0时才绑定背景if (_skinback != null && SkinSize != new Size(0, 0) && this.Size != new Size(0, 0)){//在设计器时,始终显示裁剪背景if (DesignMode){backs();}else{if (SkinWhetherTank){backs();}else{BackgroundImage = null;}}}}//裁剪透明做背景public void backs(){//裁剪下图片Bitmap back = new Bitmap(SkinBack, _skinsize);Rectangle cloneRect = new Rectangle(_mainposition.X, _mainposition.Y, Width, Height);PixelFormat format = back.PixelFormat;Bitmap cloneBitmap = back.Clone(cloneRect, format);if (SkinTrankColor != Color.Transparent){cloneBitmap.MakeTransparent(_skintrankcolor);}//将裁剪好的图片给控件层赋值this.BackgroundImage = cloneBitmap;}#endregion#region 验证大小private void BindSize(){//判断控件层和绘图层宽高都不等于0时if (Width != 0 && Height != 0 && SkinSize != new Size(0, 0)){//控件层宽度 大于 (绘图层宽度 - 控件层所在绘图层X值)时if (Width > SkinSize.Width - MainPosition.X){//等于最大限制的宽度Width = SkinSize.Width - MainPosition.X;}//控件层宽度 大于 (绘图层宽度 - 控件层所在绘图层Y值)时if (Height > SkinSize.Height - MainPosition.Y){//等于最大限制的高度Height = SkinSize.Height - MainPosition.Y;}}}#endregion#region 重载事件//窗体加载时protected override void OnLoad(EventArgs e){if (!DesignMode){skin = new SkinForm(this);skin.Show();//淡入特效Win32.AnimateWindow(this.Handle, GradientTime, Win32.AW_BLEND | Win32.AW_ACTIVATE);}base.OnLoad(e);}//窗体关闭时protected override void OnClosing(CancelEventArgs e){this.Owner.Close();base.OnClosing(e);}//大小改变时protected override void OnResize(EventArgs e){base.OnResize(e);//控制层宽高 大于或等于 (绘制层宽高 - 控制层在绘图层的位置XY)时重新绑定背景 if (Width <= (SkinSize.Width - MainPosition.X) && Height <= (SkinSize.Height - MainPosition.Y)){BindBack();}else{//否则重新验证宽高大小,并给出回馈BindSize();}}#endregion}
}

下载链接

WinForm 无毛边异形窗体相关推荐

  1. 完美实现无毛边异形窗体

    实现效果图1: 实现效果图2: 实现效果图3: 异形窗体的实现思路 (一).采用UpdateLayeredWindow这个api函数基于Png图alpha通道绘制异形窗口            优点: ...

  2. 再谈winform无边框窗体的鼠标托动与缩放

    在winform经常用到无边框的窗体,原因就是想使自己的程序界面完全的自定义,网上也有过不少的相关资料 今天我发了一下的午的时间整理了一下.觉得还不错,贴出来看看. 为了提高托动的缩放的效率,减少系统 ...

  3. C#WinForm制作异形窗体/控件

    制作异形窗体或控件的思路一般都是想办法生成一个region,然后设置给指定的窗口或控件.生成region的方法有很多,最常用的就是从一幅图片生成,把该图片中的透明色部分"抠"掉,剩 ...

  4. 使用duilib开发半透明异形窗体程序(附源码和demo)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/43532791 半透明异形窗体的功能在之前维护的老版本的duilib里面已 ...

  5. duilib设置透明窗口_使用duilib开发半透明异形窗体程序(补充)

    距离上一篇半透明窗体的博客,已经过去一年,现在这几天又对Duilib进行了一些优化和修复.这次我把CRenderEngine的渲染函数都改成了基于Gdi+的.根据我的测试,因为Duilib所需的都是最 ...

  6. delphi(XE2)实现图片异形窗体,支持摆放控件

    网上有较多使用UpdateLayeredWindow函数实现美化的图片异形窗体的代码,一般使用此场景时,对软件界面要求较高.但是实现了图片窗体后,在窗体中摆放不了其他控件,导致这个功能很鸡肋.为解决此 ...

  7. 异形窗体WinFrom

    第一步:创建WinFrom窗体 第二部:属性:AutoScaleMode:Dpi 第三步:BackColor:White 第四步:FormBorderStyle:None 第五步:Transparen ...

  8. python界面设计实例qt_python GUI库图形界面开发之PyQt5美化窗体与控件(异形窗体)实例...

    在默认情况下,我们使用PyQt5创建出来的窗口和部件都是默认的样式,虽然谈不上很丑,但是也毫无美感可言.其实,在PyQt5中,我们可以有较高的自由度来自定义窗口和各种小部件的样式,通过自定义这些样式, ...

  9. linux qt绘框,Qt绘制异形窗体

    异形窗体即不规则窗体,一般采用png图片,一般绘制异形窗体分两步: 1.设置遮罩区 2.绘制图片 使用png图片的透明部分作为遮罩区,然后绘制图片,这样我们就看到一个只绘制了非透明部分的图形,废话少说 ...

最新文章

  1. springboot 自动装配_Java互联网架构-SpringBoot自动装配核心源码剖析
  2. SQL server根据值搜表名和字段
  3. 2019ug最新版本是多少_NX1847:2019年最新版本,从某种意义上来说,也将是终极版本...
  4. msm8953+android8.1接听电话时声音由默认听筒输出改为外放输出
  5. 看Volley源码,对HTTP缓存机制分析
  6. python约瑟夫环_Python实现约瑟夫环问题的方法
  7. 将应用程序安装为Windows服务
  8. td外边加div为啥不隐藏_过年炸油饼注意了,秘制配方比例教给你,柔软不吸油,放凉了不硬...
  9. mysql批量删除进程_小程序批量删除云数据库里的数据
  10. Empire C:Basic 4
  11. hello bokeyuan
  12. html 数据库 编写学生表,【数据库】用sql语句创建学生表如何做
  13. GB28181 密解播放器
  14. 线上收单和线下收单的区别
  15. 激动!!!他用脚拆开研究生录取通知书
  16. 微信原生组件|基于小程序实现音视频通话
  17. DBA系列-推荐书籍(中文版本)
  18. 微软虐我千百遍——记一次比较漫长的TFS数据库迁移
  19. php date class,DateFormat PHP Class (php 处置日期)
  20. 腾讯云tcp考试资料

热门文章

  1. 去掉button边框样式,背景完全透明,显示出背景颜色或背景图
  2. 上架各个应用商店所需资料
  3. Xposed模块之抢红包
  4. python之蜘蛛侠
  5. by which, in which, from which...
  6. PixoArena 一款基于区块链的收集类游戏
  7. 分享一个撩妹神器,各种聊天话术技巧
  8. Backtrader:实现一个简单的通达信的交易策略
  9. java.lang.OutOfMemoryError: Java heap space内存溢出解决方案
  10. 2022年12月编程语言排行榜,最新数据来了!