(五十一)c#Winform自定义控件-文字提示-HZHControls

官网

https://www.hzhcontrols.cn

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

1 HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息\nLEFT", AnchorTipsLocation.LEFT);
2             HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息\nRIGHT", AnchorTipsLocation.RIGHT);
3             HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息\nTOP", AnchorTipsLocation.TOP);
4             HZH_Controls.Forms.FrmAnchorTips.ShowTips(button1, "测试提示信息\nBOTTOM", 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 }
View Code
 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 }
View Code

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

posted @ 2019-08-29 15:44  冰封一夏  阅读(3498)  评论(0编辑  收藏  举报
HZHControls控件库官网:https://www.hzhcontrols.cn