前提

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

github:https://github.com/kwwwvagaa/netwinformcontrol

码云:

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

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

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

nuget

install-package hzh_controls

目录

用处及效果

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 }
 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 }

最后的话

如果你喜欢的话,请到  点个星星吧