IrregularFormSkin.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using Y.Utils.WindowsUtils.APIUtils;
  11. namespace Y.Skin.YoForm.Irregular
  12. {
  13. partial class IrregularFormSkin : Form
  14. {
  15. private IrregularForm Main;
  16. public IrregularFormSkin(IrregularForm main)
  17. {
  18. InitializeComponent();
  19. SetStyles();//减少闪烁
  20. Main = main;//获取控件层对象
  21. Text = main.Text;//设置标题栏文本
  22. Icon = main.Icon;//设置图标
  23. TopMost = main.TopMost;
  24. FormBorderStyle = FormBorderStyle.None;//设置无边框的窗口样式
  25. ShowInTaskbar = main.InTaskbar;//使控件层显示到任务栏
  26. BackgroundImage = Main.BackgroundImage;//将控件层背景图应用到皮肤层
  27. BackgroundImageLayout = ImageLayout.Stretch;//自动拉伸背景图以适应窗口
  28. Size = Main.Size;//统一大小
  29. Main.Owner = this;//设置控件层的拥有皮肤层
  30. FormMovableEvent();//激活皮肤层窗体移动
  31. SetBits();//绘制半透明不规则皮肤
  32. Location = new Point(Main.Location.X, Main.Location.Y);//统一控件层和皮肤层的位置
  33. }
  34. #region 减少闪烁
  35. private void SetStyles()
  36. {
  37. SetStyle(
  38. ControlStyles.UserPaint |
  39. ControlStyles.AllPaintingInWmPaint |
  40. ControlStyles.OptimizedDoubleBuffer |
  41. ControlStyles.ResizeRedraw |
  42. ControlStyles.DoubleBuffer, true);
  43. //强制分配样式重新应用到控件上
  44. UpdateStyles();
  45. base.AutoScaleMode = AutoScaleMode.None;
  46. }
  47. #endregion
  48. #region 不规则无毛边方法
  49. protected override CreateParams CreateParams
  50. {
  51. get
  52. {
  53. CreateParams cParms = base.CreateParams;
  54. cParms.ExStyle |= 0x00080000; // WS_EX_LAYERED
  55. return cParms;
  56. }
  57. }
  58. public void SetBits()
  59. {
  60. if (BackgroundImage != null)
  61. {
  62. //绘制绘图层背景
  63. Bitmap bitmap = new Bitmap(BackgroundImage, base.Width, base.Height);
  64. if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))
  65. throw new ApplicationException("图片必须是32位带Alhpa通道的图片。");
  66. IntPtr oldBits = IntPtr.Zero;
  67. IntPtr screenDC = FormStyleAPI.GetDC(IntPtr.Zero);
  68. IntPtr hBitmap = IntPtr.Zero;
  69. IntPtr memDc = FormStyleAPI.CreateCompatibleDC(screenDC);
  70. try
  71. {
  72. FormStyleAPI.Point topLoc = new FormStyleAPI.Point(Left, Top);
  73. FormStyleAPI.Size bitMapSize = new FormStyleAPI.Size(Width, Height);
  74. FormStyleAPI.BLENDFUNCTION blendFunc = new FormStyleAPI.BLENDFUNCTION();
  75. FormStyleAPI.Point srcLoc = new FormStyleAPI.Point(0, 0);
  76. hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
  77. oldBits = FormStyleAPI.SelectObject(memDc, hBitmap);
  78. blendFunc.BlendOp = FormStyleAPI.AC_SRC_OVER;
  79. blendFunc.SourceConstantAlpha = Byte.Parse(((int)(Main.Opacity * 255)).ToString());
  80. blendFunc.AlphaFormat = FormStyleAPI.AC_SRC_ALPHA;
  81. blendFunc.BlendFlags = 0;
  82. FormStyleAPI.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, FormStyleAPI.ULW_ALPHA);
  83. }
  84. finally
  85. {
  86. if (hBitmap != IntPtr.Zero)
  87. {
  88. FormStyleAPI.SelectObject(memDc, oldBits);
  89. FormStyleAPI.DeleteObject(hBitmap);
  90. }
  91. FormStyleAPI.ReleaseDC(IntPtr.Zero, screenDC);
  92. FormStyleAPI.DeleteDC(memDc);
  93. bitmap.Dispose();
  94. }
  95. }
  96. }
  97. #endregion
  98. #region 无标题栏的窗口移动
  99. private Point mouseOffset; //记录鼠标指针的坐标
  100. private bool isMouseDown = false; //记录鼠标按键是否按下
  101. /// <summary>
  102. /// 窗体移动监听绑定
  103. /// </summary>
  104. private void FormMovableEvent()
  105. {
  106. //绘制层窗体移动
  107. //this.MouseDown += new MouseEventHandler(Frm_MouseDown);
  108. //this.MouseMove += new MouseEventHandler(Frm_MouseMove);
  109. //this.MouseUp += new MouseEventHandler(Frm_MouseUp);
  110. this.LocationChanged += new EventHandler(Frm_LocationChanged);
  111. //控制层层窗体移动
  112. //Main.MouseDown += new MouseEventHandler(Frm_MouseDown);
  113. //Main.MouseMove += new MouseEventHandler(Frm_MouseMove);
  114. //Main.MouseUp += new MouseEventHandler(Frm_MouseUp);
  115. //Main.LocationChanged += new EventHandler(Frm_LocationChanged);
  116. }
  117. /// <summary>
  118. /// 窗体按下时
  119. /// </summary>
  120. /// <param name="sender"></param>
  121. /// <param name="e"></param>
  122. private void Frm_MouseDown(object sender, MouseEventArgs e)
  123. {
  124. if (Main.Movable)
  125. {
  126. int xOffset;
  127. int yOffset;
  128. //点击窗体时,记录鼠标位置,启动移动
  129. if (e.Button == MouseButtons.Left)
  130. {
  131. xOffset = -e.X;
  132. yOffset = -e.Y;
  133. mouseOffset = new Point(xOffset, yOffset);
  134. isMouseDown = true;
  135. }
  136. }
  137. }
  138. /// <summary>
  139. /// 窗体移动时
  140. /// </summary>
  141. /// <param name="sender"></param>
  142. /// <param name="e"></param>
  143. private void Frm_MouseMove(object sender, MouseEventArgs e)
  144. {
  145. if (Main.Movable)
  146. {
  147. //将调用此事件的窗口保存下
  148. Form frm = (Form)sender;
  149. //确定开启了移动模式后
  150. if (isMouseDown)
  151. {
  152. //移动的位置计算
  153. Point mousePos = Control.MousePosition;
  154. mousePos.Offset(mouseOffset.X, mouseOffset.Y);
  155. //判断是绘图层还是控件层调用了移动事件,并作出相应回馈
  156. if (frm == this)
  157. {
  158. Location = mousePos;
  159. }
  160. else
  161. {
  162. Main.Location = mousePos;
  163. }
  164. }
  165. }
  166. }
  167. /// <summary>
  168. /// 窗体按下并释放按钮时
  169. /// </summary>
  170. /// <param name="sender"></param>
  171. /// <param name="e"></param>
  172. private void Frm_MouseUp(object sender, MouseEventArgs e)
  173. {
  174. if (Main.Movable)
  175. {
  176. // 修改鼠标状态isMouseDown的值
  177. // 确保只有鼠标左键按下并移动时,才移动窗体
  178. if (e.Button == MouseButtons.Left)
  179. {
  180. //松开鼠标时,停止移动
  181. isMouseDown = false;
  182. //Top高度小于0的时候,等于0
  183. if (this.Top < 0)
  184. {
  185. this.Top = 0;
  186. Main.Top = 0;
  187. }
  188. }
  189. }
  190. }
  191. /// <summary>
  192. /// 窗口移动时
  193. /// </summary>
  194. /// <param name="sender"></param>
  195. /// <param name="e"></param>
  196. void Frm_LocationChanged(object sender, EventArgs e)
  197. {
  198. //将调用此事件的窗口保存下
  199. Form frm = (Form)sender;
  200. if (frm == this)
  201. {
  202. Main.Location = new Point(this.Left, this.Top);
  203. }
  204. else
  205. {
  206. Location = new Point(Main.Left, Main.Top);
  207. }
  208. }
  209. #endregion
  210. protected override void OnMouseMove(MouseEventArgs e)
  211. {
  212. base.OnMouseMove(e);
  213. if (e.Button == MouseButtons.Left)
  214. {
  215. FormStyleAPI.ReleaseCapture();
  216. FormStyleAPI.SendMessage(Handle, FormStyleAPI.WM_NCLBUTTONDOWN, FormStyleAPI.HTCAPTION, 0);
  217. }
  218. }
  219. private void IrregularFormSkin_Load(object sender, EventArgs e)
  220. {
  221. }
  222. }
  223. }