官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
https://www.cnblogs.com/bfyx/p/11364884.html
用处及效果
1 HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息 LEFT", AnchorTipsLocation.LEFT); 2 HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息 RIGHT", AnchorTipsLocation.RIGHT); 3 HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息 TOP", AnchorTipsLocation.TOP); 4 HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息 BOTTOM", AnchorTipsLocation.BOTTOM);
准备工作
依然是GDI+画图,不懂可以自行百度一下
开始
思路是:根据参数画图,根据图显示不规则窗体
添加一个窗体FrmAnchorTips
重写一些函数
1 #region Override 2 3 protected override void OnClosing(CancelEventArgs e) 4 { 5 e.Cancel = true; 6 base.OnClosing(e); 7 haveHandle = false; 8 this.Dispose(); 9 } 10 11 protected override void OnHandleCreated(EventArgs e) 12 { 13 InitializeStyles(); 14 base.OnHandleCreated(e); 15 haveHandle = true; 16 } 17 18 protected override CreateParams CreateParams 19 { 20 get 21 { 22 CreateParams cParms = base.CreateParams; 23 cParms.ExStyle |= 0x00080000; // WS_EX_LAYERED 24 return cParms; 25 } 26 } 27 28 #endregion
1 private void InitializeStyles() 2 { 3 SetStyle(ControlStyles.AllPaintingInWmPaint, true); 4 SetStyle(ControlStyles.UserPaint, true); 5 UpdateStyles(); 6 }
根据图片显示窗体,这个是网上copy的
1 #region 根据图片显示窗体 English:Display Forms Based on Pictures 2 /// <summary> 3 /// 功能描述:根据图片显示窗体 English:Display Forms Based on Pictures 4 /// 作 者:HZH 5 /// 创建日期:2019-08-29 15:31:16 6 /// 任务编号: 7 /// </summary> 8 /// <param name="bitmap">bitmap</param> 9 private void SetBits(Bitmap bitmap) 10 { 11 if (!haveHandle) return; 12 13 if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) 14 throw new ApplicationException("The picture must be 32bit picture with alpha channel."); 15 16 IntPtr oldBits = IntPtr.Zero; 17 IntPtr screenDC = Win32.GetDC(IntPtr.Zero); 18 IntPtr hBitmap = IntPtr.Zero; 19 IntPtr memDc = Win32.CreateCompatibleDC(screenDC); 20 21 try 22 { 23 Win32.Point topLoc = new Win32.Point(Left, Top); 24 Win32.Size bitMapSize = new Win32.Size(bitmap.Width, bitmap.Height); 25 Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION(); 26 Win32.Point srcLoc = new Win32.Point(0, 0); 27 28 hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); 29 oldBits = Win32.SelectObject(memDc, hBitmap); 30 31 blendFunc.BlendOp = Win32.AC_SRC_OVER; 32 blendFunc.SourceConstantAlpha = 255; 33 blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA; 34 blendFunc.BlendFlags = 0; 35 36 Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA); 37 } 38 finally 39 { 40 if (hBitmap != IntPtr.Zero) 41 { 42 Win32.SelectObject(memDc, oldBits); 43 Win32.DeleteObject(hBitmap); 44 } 45 Win32.ReleaseDC(IntPtr.Zero, screenDC); 46 Win32.DeleteDC(memDc); 47 } 48 } 49 #endregion
然后是win32类
1 class Win32 2 { 3 [StructLayout(LayoutKind.Sequential)] 4 public struct Size 5 { 6 public Int32 cx; 7 public Int32 cy; 8 9 public Size(Int32 x, Int32 y) 10 { 11 cx = x; 12 cy = y; 13 } 14 } 15 16 [StructLayout(LayoutKind.Sequential, Pack = 1)] 17 public struct BLENDFUNCTION 18 { 19 public byte BlendOp; 20 public byte BlendFlags; 21 public byte SourceConstantAlpha; 22 public byte AlphaFormat; 23 } 24 25 [StructLayout(LayoutKind.Sequential)] 26 public struct Point 27 { 28 public Int32 x; 29 public Int32 y; 30 31 public Point(Int32 x, Int32 y) 32 { 33 this.x = x; 34 this.y = y; 35 } 36 } 37 38 public const byte AC_SRC_OVER = 0; 39 public const Int32 ULW_ALPHA = 2; 40 public const byte AC_SRC_ALPHA = 1; 41 42 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 43 public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 44 45 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 46 public static extern IntPtr GetDC(IntPtr hWnd); 47 48 [DllImport("gdi32.dll", ExactSpelling = true)] 49 public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj); 50 51 [DllImport("user32.dll", ExactSpelling = true)] 52 public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 53 54 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 55 public static extern int DeleteDC(IntPtr hDC); 56 57 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 58 public static extern int DeleteObject(IntPtr hObj); 59 60 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 61 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); 62 63 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 64 public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount, IntPtr rgnData); 65 }
然后就是构造函数了,根据传入参数,画出图片并设置窗体
1 #region 构造函数 English:Constructor 2 /// <summary> 3 /// 功能描述:构造函数 English:Constructor 4 /// 作 者:HZH 5 /// 创建日期:2019-08-29 15:27:51 6 /// 任务编号: 7 /// </summary> 8 /// <param name="rectControl">停靠区域</param> 9 /// <param name="strMsg">消息</param> 10 /// <param name="location">显示方位</param> 11 /// <param name="background">背景色</param> 12 /// <param name="foreColor">文字颜色</param> 13 /// <param name="fontSize">文字大小</param> 14 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 15 private FrmAnchorTips( 16 Rectangle rectControl, 17 string strMsg, 18 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 19 Color? background = null, 20 Color? foreColor = null, 21 int fontSize = 10, 22 int autoCloseTime = 5000) 23 { 24 InitializeComponent(); 25 Graphics g = this.CreateGraphics(); 26 Font _font = new Font("微软雅黑", fontSize); 27 Color _background = background == null ? Color.FromArgb(255, 77, 58) : background.Value; 28 Color _foreColor = foreColor == null ? Color.White : foreColor.Value; 29 System.Drawing.SizeF sizeText = g.MeasureString(strMsg, _font); 30 g.Dispose(); 31 var formSize = new Size((int)sizeText.Width + 20, (int)sizeText.Height + 20); 32 if (formSize.Width < 20) 33 formSize.Width = 20; 34 if (formSize.Height < 20) 35 formSize.Height = 20; 36 if (location == AnchorTipsLocation.LEFT || location == AnchorTipsLocation.RIGHT) 37 { 38 formSize.Width += 20; 39 } 40 else 41 { 42 formSize.Height += 20; 43 } 44 45 #region 获取窗体path English:Get the form path 46 GraphicsPath path = new GraphicsPath(); 47 Rectangle rect; 48 switch (location) 49 { 50 case AnchorTipsLocation.TOP: 51 rect = new Rectangle(1, 1, formSize.Width - 2, formSize.Height - 20 - 1); 52 this.Location = new Point(rectControl.X + (rectControl.Width - rect.Width) / 2, rectControl.Y - rect.Height - 20); 53 break; 54 case AnchorTipsLocation.RIGHT: 55 rect = new Rectangle(20, 1, formSize.Width - 20 - 1, formSize.Height - 2); 56 this.Location = new Point(rectControl.Right, rectControl.Y + (rectControl.Height - rect.Height) / 2); 57 break; 58 case AnchorTipsLocation.BOTTOM: 59 rect = new Rectangle(1, 20, formSize.Width - 2, formSize.Height - 20 - 1); 60 this.Location = new Point(rectControl.X + (rectControl.Width - rect.Width) / 2, rectControl.Bottom); 61 break; 62 default: 63 rect = new Rectangle(1, 1, formSize.Width - 20 - 1, formSize.Height - 2); 64 this.Location = new Point(rectControl.X - rect.Width - 20, rectControl.Y + (rectControl.Height - rect.Height) / 2); 65 break; 66 } 67 int cornerRadius = 2; 68 69 path.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);//左上角 70 #region 上边 71 if (location == AnchorTipsLocation.BOTTOM) 72 { 73 path.AddLine(rect.X + cornerRadius, rect.Y, rect.Left + rect.Width / 2 - 10, rect.Y);//上 74 path.AddLine(rect.Left + rect.Width / 2 - 10, rect.Y, rect.Left + rect.Width / 2, rect.Y - 19);//上 75 path.AddLine(rect.Left + rect.Width / 2, rect.Y - 19, rect.Left + rect.Width / 2 + 10, rect.Y);//上 76 path.AddLine(rect.Left + rect.Width / 2 + 10, rect.Y, rect.Right - cornerRadius * 2, rect.Y);//上 77 } 78 else 79 { 80 path.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);//上 81 } 82 #endregion 83 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);//右上角 84 #region 右边 85 if (location == AnchorTipsLocation.LEFT) 86 { 87 path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height / 2 - 10);//右 88 path.AddLine(rect.Right, rect.Y + rect.Height / 2 - 10, rect.Right + 19, rect.Y + rect.Height / 2);//右 89 path.AddLine(rect.Right + 19, rect.Y + rect.Height / 2, rect.Right, rect.Y + rect.Height / 2 + 10);//右 90 path.AddLine(rect.Right, rect.Y + rect.Height / 2 + 10, rect.Right, rect.Y + rect.Height - cornerRadius * 2);//右 91 } 92 else 93 { 94 path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);//右 95 } 96 #endregion 97 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);//右下角 98 #region 下边 99 if (location == AnchorTipsLocation.TOP) 100 { 101 path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.Left + rect.Width / 2 + 10, rect.Bottom); 102 path.AddLine(rect.Left + rect.Width / 2 + 10, rect.Bottom, rect.Left + rect.Width / 2, rect.Bottom + 19); 103 path.AddLine(rect.Left + rect.Width / 2, rect.Bottom + 19, rect.Left + rect.Width / 2 - 10, rect.Bottom); 104 path.AddLine(rect.Left + rect.Width / 2 - 10, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); 105 } 106 else 107 { 108 path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); 109 } 110 #endregion 111 path.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);//左下角 112 #region 左边 113 if (location == AnchorTipsLocation.RIGHT) 114 { 115 path.AddLine(rect.Left, rect.Y + cornerRadius * 2, rect.Left, rect.Y + rect.Height / 2 - 10);//左 116 path.AddLine(rect.Left, rect.Y + rect.Height / 2 - 10, rect.Left - 19, rect.Y + rect.Height / 2);//左 117 path.AddLine(rect.Left - 19, rect.Y + rect.Height / 2, rect.Left, rect.Y + rect.Height / 2 + 10);//左 118 path.AddLine(rect.Left, rect.Y + rect.Height / 2 + 10, rect.Left, rect.Y + rect.Height - cornerRadius * 2);//左 119 } 120 else 121 { 122 path.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);//左 123 } 124 #endregion 125 path.CloseFigure(); 126 #endregion 127 128 Bitmap bit = new Bitmap(formSize.Width, formSize.Height); 129 this.Size = formSize; 130 131 #region 画图 English:Drawing 132 Graphics gBit = Graphics.FromImage(bit); 133 gBit.SetGDIHigh(); 134 gBit.FillPath(new SolidBrush(_background), path); 135 gBit.DrawString(strMsg, _font, new SolidBrush(_foreColor), rect.Location + new Size(10, 10)); 136 gBit.Dispose(); 137 #endregion 138 139 SetBits(bit); 140 if (autoCloseTime > 0) 141 { 142 Timer t = new Timer(); 143 t.Interval = autoCloseTime; 144 t.Tick += (a, b) => 145 { 146 this.Close(); 147 }; 148 t.Enabled = true; 149 } 150 } 151 #endregion
再来2个静态函数以供调用
1 #region 显示一个提示 English:Show a hint 2 /// <summary> 3 /// 功能描述:显示一个提示 English:Show a hint 4 /// 作 者:HZH 5 /// 创建日期:2019-08-29 15:28:58 6 /// 任务编号: 7 /// </summary> 8 /// <param name="parentControl">停靠控件</param> 9 /// <param name="strMsg">消息</param> 10 /// <param name="location">显示方位</param> 11 /// <param name="background">背景色</param> 12 /// <param name="foreColor">文字颜色</param> 13 /// <param name="deviation">偏移量</param> 14 /// <param name="fontSize">文字大小</param> 15 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 16 public static FrmAnchorTips ShowTips( 17 Control parentControl, 18 string strMsg, 19 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 20 Color? background = null, 21 Color? foreColor = null, 22 Size? deviation = null, 23 int fontSize = 10, 24 int autoCloseTime = 5000) 25 { 26 Point p; 27 if (parentControl is Form) 28 { 29 p = parentControl.Location; 30 } 31 else 32 { 33 p = parentControl.Parent.PointToScreen(parentControl.Location); 34 } 35 if (deviation != null) 36 { 37 p = p + deviation.Value; 38 } 39 return ShowTips(parentControl.FindForm(), new Rectangle(p, parentControl.Size), strMsg, location, background, foreColor, fontSize, autoCloseTime); 40 } 41 #endregion 42 43 #region 显示一个提示 English:Show a hint 44 /// <summary> 45 /// 功能描述:显示一个提示 English:Show a hint 46 /// 作 者:HZH 47 /// 创建日期:2019-08-29 15:29:07 48 /// 任务编号: 49 /// </summary> 50 /// <param name="parentForm">父窗体</param> 51 /// <param name="rectControl">停靠区域</param> 52 /// <param name="strMsg">消息</param> 53 /// <param name="location">显示方位</param> 54 /// <param name="background">背景色</param> 55 /// <param name="foreColor">文字颜色</param> 56 /// <param name="fontSize">文字大小</param> 57 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 58 /// <returns>返回值</returns> 59 public static FrmAnchorTips ShowTips( 60 Form parentForm, 61 Rectangle rectControl, 62 string strMsg, 63 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 64 Color? background = null, 65 Color? foreColor = null, 66 int fontSize = 10, 67 int autoCloseTime = 5000) 68 { 69 FrmAnchorTips frm = new FrmAnchorTips(rectControl, strMsg, location, background, foreColor, fontSize, autoCloseTime); 70 frm.TopMost = true; 71 frm.Show(parentForm); 72 return frm; 73 } 74 #endregion
全部代码
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Drawing.Drawing2D; 7 using System.Linq; 8 using System.Runtime.InteropServices; 9 using System.Text; 10 using System.Windows.Forms; 11 12 namespace HZH_Controls.Forms 13 { 14 public partial class FrmAnchorTips : Form 15 { 16 bool haveHandle = false; 17 #region 构造函数 English:Constructor 18 /// <summary> 19 /// 功能描述:构造函数 English:Constructor 20 /// 作 者:HZH 21 /// 创建日期:2019-08-29 15:27:51 22 /// 任务编号: 23 /// </summary> 24 /// <param name="rectControl">停靠区域</param> 25 /// <param name="strMsg">消息</param> 26 /// <param name="location">显示方位</param> 27 /// <param name="background">背景色</param> 28 /// <param name="foreColor">文字颜色</param> 29 /// <param name="fontSize">文字大小</param> 30 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 31 private FrmAnchorTips( 32 Rectangle rectControl, 33 string strMsg, 34 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 35 Color? background = null, 36 Color? foreColor = null, 37 int fontSize = 10, 38 int autoCloseTime = 5000) 39 { 40 InitializeComponent(); 41 Graphics g = this.CreateGraphics(); 42 Font _font = new Font("微软雅黑", fontSize); 43 Color _background = background == null ? Color.FromArgb(255, 77, 58) : background.Value; 44 Color _foreColor = foreColor == null ? Color.White : foreColor.Value; 45 System.Drawing.SizeF sizeText = g.MeasureString(strMsg, _font); 46 g.Dispose(); 47 var formSize = new Size((int)sizeText.Width + 20, (int)sizeText.Height + 20); 48 if (formSize.Width < 20) 49 formSize.Width = 20; 50 if (formSize.Height < 20) 51 formSize.Height = 20; 52 if (location == AnchorTipsLocation.LEFT || location == AnchorTipsLocation.RIGHT) 53 { 54 formSize.Width += 20; 55 } 56 else 57 { 58 formSize.Height += 20; 59 } 60 61 #region 获取窗体path English:Get the form path 62 GraphicsPath path = new GraphicsPath(); 63 Rectangle rect; 64 switch (location) 65 { 66 case AnchorTipsLocation.TOP: 67 rect = new Rectangle(1, 1, formSize.Width - 2, formSize.Height - 20 - 1); 68 this.Location = new Point(rectControl.X + (rectControl.Width - rect.Width) / 2, rectControl.Y - rect.Height - 20); 69 break; 70 case AnchorTipsLocation.RIGHT: 71 rect = new Rectangle(20, 1, formSize.Width - 20 - 1, formSize.Height - 2); 72 this.Location = new Point(rectControl.Right, rectControl.Y + (rectControl.Height - rect.Height) / 2); 73 break; 74 case AnchorTipsLocation.BOTTOM: 75 rect = new Rectangle(1, 20, formSize.Width - 2, formSize.Height - 20 - 1); 76 this.Location = new Point(rectControl.X + (rectControl.Width - rect.Width) / 2, rectControl.Bottom); 77 break; 78 default: 79 rect = new Rectangle(1, 1, formSize.Width - 20 - 1, formSize.Height - 2); 80 this.Location = new Point(rectControl.X - rect.Width - 20, rectControl.Y + (rectControl.Height - rect.Height) / 2); 81 break; 82 } 83 int cornerRadius = 2; 84 85 path.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);//左上角 86 #region 上边 87 if (location == AnchorTipsLocation.BOTTOM) 88 { 89 path.AddLine(rect.X + cornerRadius, rect.Y, rect.Left + rect.Width / 2 - 10, rect.Y);//上 90 path.AddLine(rect.Left + rect.Width / 2 - 10, rect.Y, rect.Left + rect.Width / 2, rect.Y - 19);//上 91 path.AddLine(rect.Left + rect.Width / 2, rect.Y - 19, rect.Left + rect.Width / 2 + 10, rect.Y);//上 92 path.AddLine(rect.Left + rect.Width / 2 + 10, rect.Y, rect.Right - cornerRadius * 2, rect.Y);//上 93 } 94 else 95 { 96 path.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);//上 97 } 98 #endregion 99 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);//右上角 100 #region 右边 101 if (location == AnchorTipsLocation.LEFT) 102 { 103 path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height / 2 - 10);//右 104 path.AddLine(rect.Right, rect.Y + rect.Height / 2 - 10, rect.Right + 19, rect.Y + rect.Height / 2);//右 105 path.AddLine(rect.Right + 19, rect.Y + rect.Height / 2, rect.Right, rect.Y + rect.Height / 2 + 10);//右 106 path.AddLine(rect.Right, rect.Y + rect.Height / 2 + 10, rect.Right, rect.Y + rect.Height - cornerRadius * 2);//右 107 } 108 else 109 { 110 path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);//右 111 } 112 #endregion 113 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);//右下角 114 #region 下边 115 if (location == AnchorTipsLocation.TOP) 116 { 117 path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.Left + rect.Width / 2 + 10, rect.Bottom); 118 path.AddLine(rect.Left + rect.Width / 2 + 10, rect.Bottom, rect.Left + rect.Width / 2, rect.Bottom + 19); 119 path.AddLine(rect.Left + rect.Width / 2, rect.Bottom + 19, rect.Left + rect.Width / 2 - 10, rect.Bottom); 120 path.AddLine(rect.Left + rect.Width / 2 - 10, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); 121 } 122 else 123 { 124 path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom); 125 } 126 #endregion 127 path.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);//左下角 128 #region 左边 129 if (location == AnchorTipsLocation.RIGHT) 130 { 131 path.AddLine(rect.Left, rect.Y + cornerRadius * 2, rect.Left, rect.Y + rect.Height / 2 - 10);//左 132 path.AddLine(rect.Left, rect.Y + rect.Height / 2 - 10, rect.Left - 19, rect.Y + rect.Height / 2);//左 133 path.AddLine(rect.Left - 19, rect.Y + rect.Height / 2, rect.Left, rect.Y + rect.Height / 2 + 10);//左 134 path.AddLine(rect.Left, rect.Y + rect.Height / 2 + 10, rect.Left, rect.Y + rect.Height - cornerRadius * 2);//左 135 } 136 else 137 { 138 path.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);//左 139 } 140 #endregion 141 path.CloseFigure(); 142 #endregion 143 144 Bitmap bit = new Bitmap(formSize.Width, formSize.Height); 145 this.Size = formSize; 146 147 #region 画图 English:Drawing 148 Graphics gBit = Graphics.FromImage(bit); 149 gBit.SetGDIHigh(); 150 gBit.FillPath(new SolidBrush(_background), path); 151 gBit.DrawString(strMsg, _font, new SolidBrush(_foreColor), rect.Location + new Size(10, 10)); 152 gBit.Dispose(); 153 #endregion 154 155 SetBits(bit); 156 if (autoCloseTime > 0) 157 { 158 Timer t = new Timer(); 159 t.Interval = autoCloseTime; 160 t.Tick += (a, b) => 161 { 162 this.Close(); 163 }; 164 t.Enabled = true; 165 } 166 } 167 #endregion 168 169 #region 显示一个提示 English:Show a hint 170 /// <summary> 171 /// 功能描述:显示一个提示 English:Show a hint 172 /// 作 者:HZH 173 /// 创建日期:2019-08-29 15:28:58 174 /// 任务编号: 175 /// </summary> 176 /// <param name="parentControl">停靠控件</param> 177 /// <param name="strMsg">消息</param> 178 /// <param name="location">显示方位</param> 179 /// <param name="background">背景色</param> 180 /// <param name="foreColor">文字颜色</param> 181 /// <param name="deviation">偏移量</param> 182 /// <param name="fontSize">文字大小</param> 183 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 184 public static FrmAnchorTips ShowTips( 185 Control parentControl, 186 string strMsg, 187 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 188 Color? background = null, 189 Color? foreColor = null, 190 Size? deviation = null, 191 int fontSize = 10, 192 int autoCloseTime = 5000) 193 { 194 Point p; 195 if (parentControl is Form) 196 { 197 p = parentControl.Location; 198 } 199 else 200 { 201 p = parentControl.Parent.PointToScreen(parentControl.Location); 202 } 203 if (deviation != null) 204 { 205 p = p + deviation.Value; 206 } 207 return ShowTips(parentControl.FindForm(), new Rectangle(p, parentControl.Size), strMsg, location, background, foreColor, fontSize, autoCloseTime); 208 } 209 #endregion 210 211 #region 显示一个提示 English:Show a hint 212 /// <summary> 213 /// 功能描述:显示一个提示 English:Show a hint 214 /// 作 者:HZH 215 /// 创建日期:2019-08-29 15:29:07 216 /// 任务编号: 217 /// </summary> 218 /// <param name="parentForm">父窗体</param> 219 /// <param name="rectControl">停靠区域</param> 220 /// <param name="strMsg">消息</param> 221 /// <param name="location">显示方位</param> 222 /// <param name="background">背景色</param> 223 /// <param name="foreColor">文字颜色</param> 224 /// <param name="fontSize">文字大小</param> 225 /// <param name="autoCloseTime">自动关闭时间,当<=0时不自动关闭</param> 226 /// <returns>返回值</returns> 227 public static FrmAnchorTips ShowTips( 228 Form parentForm, 229 Rectangle rectControl, 230 string strMsg, 231 AnchorTipsLocation location = AnchorTipsLocation.RIGHT, 232 Color? background = null, 233 Color? foreColor = null, 234 int fontSize = 10, 235 int autoCloseTime = 5000) 236 { 237 FrmAnchorTips frm = new FrmAnchorTips(rectControl, strMsg, location, background, foreColor, fontSize, autoCloseTime); 238 frm.TopMost = true; 239 frm.Show(parentForm); 240 return frm; 241 } 242 #endregion 243 244 #region Override 245 246 protected override void OnClosing(CancelEventArgs e) 247 { 248 e.Cancel = true; 249 base.OnClosing(e); 250 haveHandle = false; 251 this.Dispose(); 252 } 253 254 protected override void OnHandleCreated(EventArgs e) 255 { 256 InitializeStyles(); 257 base.OnHandleCreated(e); 258 haveHandle = true; 259 } 260 261 protected override CreateParams CreateParams 262 { 263 get 264 { 265 CreateParams cParms = base.CreateParams; 266 cParms.ExStyle |= 0x00080000; // WS_EX_LAYERED 267 return cParms; 268 } 269 } 270 271 #endregion 272 273 private void InitializeStyles() 274 { 275 SetStyle(ControlStyles.AllPaintingInWmPaint, true); 276 SetStyle(ControlStyles.UserPaint, true); 277 UpdateStyles(); 278 } 279 280 #region 根据图片显示窗体 English:Display Forms Based on Pictures 281 /// <summary> 282 /// 功能描述:根据图片显示窗体 English:Display Forms Based on Pictures 283 /// 作 者:HZH 284 /// 创建日期:2019-08-29 15:31:16 285 /// 任务编号: 286 /// </summary> 287 /// <param name="bitmap">bitmap</param> 288 private void SetBits(Bitmap bitmap) 289 { 290 if (!haveHandle) return; 291 292 if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) 293 throw new ApplicationException("The picture must be 32bit picture with alpha channel."); 294 295 IntPtr oldBits = IntPtr.Zero; 296 IntPtr screenDC = Win32.GetDC(IntPtr.Zero); 297 IntPtr hBitmap = IntPtr.Zero; 298 IntPtr memDc = Win32.CreateCompatibleDC(screenDC); 299 300 try 301 { 302 Win32.Point topLoc = new Win32.Point(Left, Top); 303 Win32.Size bitMapSize = new Win32.Size(bitmap.Width, bitmap.Height); 304 Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION(); 305 Win32.Point srcLoc = new Win32.Point(0, 0); 306 307 hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); 308 oldBits = Win32.SelectObject(memDc, hBitmap); 309 310 blendFunc.BlendOp = Win32.AC_SRC_OVER; 311 blendFunc.SourceConstantAlpha = 255; 312 blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA; 313 blendFunc.BlendFlags = 0; 314 315 Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA); 316 } 317 finally 318 { 319 if (hBitmap != IntPtr.Zero) 320 { 321 Win32.SelectObject(memDc, oldBits); 322 Win32.DeleteObject(hBitmap); 323 } 324 Win32.ReleaseDC(IntPtr.Zero, screenDC); 325 Win32.DeleteDC(memDc); 326 } 327 } 328 #endregion 329 } 330 331 public enum AnchorTipsLocation 332 { 333 LEFT, 334 TOP, 335 RIGHT, 336 BOTTOM 337 } 338 339 class Win32 340 { 341 [StructLayout(LayoutKind.Sequential)] 342 public struct Size 343 { 344 public Int32 cx; 345 public Int32 cy; 346 347 public Size(Int32 x, Int32 y) 348 { 349 cx = x; 350 cy = y; 351 } 352 } 353 354 [StructLayout(LayoutKind.Sequential, Pack = 1)] 355 public struct BLENDFUNCTION 356 { 357 public byte BlendOp; 358 public byte BlendFlags; 359 public byte SourceConstantAlpha; 360 public byte AlphaFormat; 361 } 362 363 [StructLayout(LayoutKind.Sequential)] 364 public struct Point 365 { 366 public Int32 x; 367 public Int32 y; 368 369 public Point(Int32 x, Int32 y) 370 { 371 this.x = x; 372 this.y = y; 373 } 374 } 375 376 public const byte AC_SRC_OVER = 0; 377 public const Int32 ULW_ALPHA = 2; 378 public const byte AC_SRC_ALPHA = 1; 379 380 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 381 public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 382 383 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 384 public static extern IntPtr GetDC(IntPtr hWnd); 385 386 [DllImport("gdi32.dll", ExactSpelling = true)] 387 public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj); 388 389 [DllImport("user32.dll", ExactSpelling = true)] 390 public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 391 392 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 393 public static extern int DeleteDC(IntPtr hDC); 394 395 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 396 public static extern int DeleteObject(IntPtr hObj); 397 398 [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] 399 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); 400 401 [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] 402 public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount, IntPtr rgnData); 403 } 404 }
1 namespace HZH_Controls.Forms 2 { 3 partial class FrmAnchorTips 4 { 5 /// <summary> 6 /// Required designer variable. 7 /// </summary> 8 private System.ComponentModel.IContainer components = null; 9 10 /// <summary> 11 /// Clean up any resources being used. 12 /// </summary> 13 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 14 protected override void Dispose(bool disposing) 15 { 16 if (disposing && (components != null)) 17 { 18 components.Dispose(); 19 } 20 base.Dispose(disposing); 21 } 22 23 #region Windows Form Designer generated code 24 25 /// <summary> 26 /// Required method for Designer support - do not modify 27 /// the contents of this method with the code editor. 28 /// </summary> 29 private void InitializeComponent() 30 { 31 this.SuspendLayout(); 32 // 33 // FrmAnchorTips 34 // 35 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 36 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 this.ClientSize = new System.Drawing.Size(226, 83); 38 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 39 this.Name = "FrmAnchorTips"; 40 this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; 41 this.Text = "FrmAnchorTips"; 42 this.ResumeLayout(false); 43 44 } 45 46 #endregion 47 } 48 }
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧