(五十一)c#Winform自定义控件-文字提示
程序员文章站
2022-07-02 13:13:01
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_contr ......
前提
入行已经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 }
最后的话
如果你喜欢的话,请到 点个星星吧