如何在windows窗口添加一个关闭按钮

如何在windows窗口添加一个关闭按钮,第1张

实现起来要定义以下过程

1、

定义DrawCaptButton过程,这个过程的功能是在指定的位置画出按钮

在过程中要使用win32函数GetSystemMetrics得到窗口的大小和标题按钮的大小;使用delphi函数Bounds定义一个矩形,这个矩形就是新按钮的位置;再定义一个小的矩形,这个矩形是为了填写文本;最后就调用delphi中比较有用的函数drawbuttonface把按钮画出来。

2、

每次我们对窗口进行 *** 作,例如,最大化 *** 作或最小化 *** 作,新按钮就会消失,为了解决这个问题,我们对所有的消息要进行处理,给每个消息编写一个过程对按钮进行重画。

A、定义WMNCPaint(var

Msg:TWMNCPaint)过程,处理消息WM_NCPaint。

B、定义WMNCActivate(var Msg

:TWMNCActivate)过程,处理消息WM_NCACTIVATE。

C、定义WMSetText(var

Msg:TWMSetText)过程,处理消息WM_SETTEXT。

D、定义WMNCHitTest(var Msg

:TWMNCHitTest)过程,处理消息WM_NCHITTEST。

E、定义WMNCLButtonDown(var Msg :

TWMNCLButtonDown)过程,处理消息WM_NCLBUTTONDOWN。

ImageButton是aspnet中的控件。如果说是winform,可以用普通的button 设置背景图和按钮的显示格式。也可以用imagebox控件。 \x0d\\x0d\using System;\x0d\using SystemCollections;\x0d\using SystemComponentModel;\x0d\using SystemDrawing;\x0d\using SystemData;\x0d\using SystemWindowsForms;\x0d\using SystemDrawingDrawing2D;\x0d\using SystemDrawingImaging;\x0d\using SystemText;\x0d\\x0d\namespace 自定义水晶按钮\x0d\{\x0d\/// \x0d\/// UserControl1 的摘要说明。\x0d\/// \x0d\public class TestButton : Button\x0d\{\x0d\/// \x0d\/// 必需的设计器变量。\x0d\/// \x0d\private SystemComponentModelContainer components = null;\x0d\\x0d\private enum MouseActionType//定义鼠标的点击类型 \x0d\{\x0d\None,\x0d\Hover,\x0d\Click\x0d\}\x0d\\x0d\private MouseActionType mouseAction;\x0d\private ImageAttributes imgAttr = new ImageAttributes();\x0d\private Bitmap buttonBitmap;\x0d\private Rectangle buttonBitmapRectangle;\x0d\\x0d\ public TestButton()\x0d\{\x0d\// 该调用是 WindowsForms 窗体设计器所必需的。\x0d\InitializeComponent();\x0d\\x0d\// TODO: 在 InitComponent 调用后添加任何初始化\x0d\\x0d\mouseAction = MouseActionTypeNone;\x0d\\x0d\//应用双缓冲技术是画面不闪烁\x0d\thisSetStyle(ControlStylesAllPaintingInWmPaint |\x0d\ControlStylesDoubleBuffer |\x0d\ControlStylesUserPaint, true);\x0d\\x0d\//修改默认的字体,背景色,大小\x0d\thisFont = new Font("宋体", 12, FontStyleBold);\x0d\thisBackColor = ColorDarkTurquoise;\x0d\thisSize = new Size(100, 40);\x0d\\x0d\}\x0d\\x0d\/// \x0d\/// 清理所有正在使用的资源。\x0d\/// \x0d\protected override void Dispose( bool disposing )\x0d\{\x0d\if( disposing )\x0d\{\x0d\if( components != null )\x0d\componentsDispose();\x0d\}\x0d\baseDispose( disposing );\x0d\}\x0d\\x0d\#region 组件设计器生成的代码\x0d\/// \x0d\/// 设计器支持所需的方法 - 不要使用代码编辑器 \x0d\/// 修改此方法的内容。\x0d\/// \x0d\private void InitializeComponent()\x0d\{\x0d\components = new SystemComponentModelContainer();\x0d\}\x0d\#endregion\x0d\\x0d\private GraphicsPath GetGraphicsPath(Rectangle rc, int r)\x0d\{\x0d\int x = rcX, y = rcY, w = rcWidth, h = rcHeight;\x0d\GraphicsPath path = new GraphicsPath();\x0d\pathAddArc(x, y, r, r, 180, 90); //左上角的椭圆\x0d\pathAddArc(x + w - r, y, r, r, 270, 90);//右上角的椭圆\x0d\pathAddArc(x + w - r, y + h - r, r, r, 0, 90);//左下角的椭圆\x0d\pathAddArc(x, y + h - r, r, r, 90, 90);//右下角的椭圆\x0d\pathCloseFigure();\x0d\return path;\x0d\}\x0d\\x0d\protected override void OnPaint(PaintEventArgs e)\x0d\{\x0d\Graphics g = eGraphics;\x0d\//gClear(ColorWhite);\x0d\gClear(SystemColorsControl);//清空画布的三维颜色\x0d\Color clr = thisBackColor;\x0d\int shadowOffset = 8;\x0d\int btnOffset = 0;\x0d\switch (mouseAction)\x0d\{\x0d\case MouseActionTypeClick:\x0d\shadowOffset = 4;\x0d\ clr = ColorDeepSkyBlue;\x0d\btnOffset = 2;\x0d\break;\x0d\case MouseActionTypeHover:\x0d\ clr = ColorDeepSkyBlue;\x0d\break;\x0d\}\x0d\gSmoothingMode = SmoothingModeAntiAlias;\x0d\\x0d\///\x0d\/// 创建按钮本身的图形\x0d\/// \x0d\Rectangle rc = new Rectangle(btnOffset, btnOffset, thisClientSizeWidth - 8 - btnOffset, thisClientSizeHeight - 8 - btnOffset);\x0d\GraphicsPath path1 = thisGetGraphicsPath(rc, 20);\x0d\\x0d\//一个起始点和一个终点 用渐变的颜色来填充\x0d\LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rcHeight + 6), clr, ColorWhite);\x0d\\x0d\///\x0d\/// 创建按钮阴影\x0d\/// \x0d\Rectangle rc2 = rc;\x0d\rc2Offset(shadowOffset, shadowOffset);\x0d\GraphicsPath path2 = thisGetGraphicsPath(rc2, 20);\x0d\PathGradientBrush br2 = new PathGradientBrush(path2);\x0d\br2CenterColor = ColorBlack;\x0d\br2SurroundColors = new Color[] {SystemColorsControl};\x0d\//为了更逼真,我们将渐变结束颜色设定为窗体前景颜色,可以根据窗口的前景颜色适当调整\x0d\ \x0d\///\x0d\/// 创建按钮顶部白色渐变\x0d\/// \x0d\Rectangle rc3 = rc;\x0d\rc3Inflate(-5, -5);\x0d\rc3Height = 15;\x0d\GraphicsPath path3 = GetGraphicsPath(rc3, 20);\x0d\\x0d\LinearGradientBrush br3 = new LinearGradientBrush(rc3, ColorFromArgb(255, ColorWhite), ColorFromArgb(0, ColorWhite), LinearGradientModeVertical);\x0d\\x0d\///\x0d\/// 绘制图形\x0d\///\x0d\gFillPath(br2, path2);//绘制阴影\x0d\gFillPath(br1, path1); //绘制按钮\x0d\gFillPath(br3, path3); //绘制顶部白色泡泡\x0d\\x0d\///\x0d\///设定内存位图对象,进行二级缓存绘图 *** 作 双缓冲\x0d\///\x0d\buttonBitmapRectangle = new Rectangle(rcLocation, rcSize);\x0d\buttonBitmap = new Bitmap(buttonBitmapRectangleWidth, buttonBitmapRectangleHeight);\x0d\Graphics g_bmp = GraphicsFromImage(buttonBitmap);\x0d\g_bmpSmoothingMode = SmoothingModeAntiAlias;\x0d\g_bmpFillPath(br1, path1);\x0d\g_bmpFillPath(br3, path3);\x0d\\x0d\///\x0d\///将region赋值给button\x0d\Region rgn = new Region(path1);\x0d\rgnUnion(path2);\x0d\thisRegion = rgn;\x0d\\x0d\///\x0d\/// 绘制按钮的文本\x0d\/// \x0d\GraphicsPath path4 = new GraphicsPath();\x0d\\x0d\RectangleF path1bounds = path1GetBounds();\x0d\ \x0d\Rectangle rcText = new Rectangle((int)path1boundsX + btnOffset, (int)path1boundsY + btnOffset, (int)path1boundsWidth, (int)path1boundsHeight);\x0d\\x0d\StringFormat strformat = new StringFormat();\x0d\strformatAlignment = StringAlignmentCenter;\x0d\strformatLineAlignment = StringAlignmentCenter;\x0d\path4AddString(thisText, thisFontFontFamily, (int)thisFontStyle, thisFontSize, rcText, strformat);\x0d\\x0d\Pen txtPen = new Pen(thisForeColor , 1);\x0d\gDrawPath(txtPen, path4);\x0d\g_bmpDrawPath(txtPen, path4);\x0d\}\x0d\\x0d\//重写一系列事件\x0d\protected override void OnMouseDown(MouseEventArgs e)\x0d\{\x0d\if (eButton == MouseButtonsLeft)\x0d\{\x0d\thismouseAction = MouseActionTypeClick;\x0d\thisInvalidate();\x0d\}\x0d\baseOnMouseDown(e);\x0d\}\x0d\\x0d\protected override void OnMouseUp(MouseEventArgs e)\x0d\{\x0d\thismouseAction = MouseActionTypeHover;\x0d\thisInvalidate();\x0d\baseOnMouseUp(e);\x0d\}\x0d\\x0d\protected override void OnMouseHover(EventArgs e)\x0d\{\x0d\thismouseAction = MouseActionTypeHover;\x0d\thisInvalidate();\x0d\baseOnMouseHover(e);\x0d\}\x0d\\x0d\protected override void OnMouseEnter(EventArgs e)\x0d\{\x0d\thismouseAction = MouseActionTypeHover;\x0d\thisInvalidate();\x0d\baseOnMouseEnter(e);\x0d\}\x0d\\x0d\protected override void OnMouseLeave(EventArgs e)\x0d\{\x0d\thismouseAction = MouseActionTypeNone;\x0d\thisInvalidate();\x0d\baseOnMouseLeave(e);\x0d\}\x0d\}\x0d\}

介绍一个带加载功能的按钮控件的实现原理,加载动画来自于 CircularProgressDrawable

圆环加载就是用setCompoundDrawables放到TextView的drawablewStart中,将文字的Gravity设置Center

结果效果是这个亚子的:

看来实际的效果与我们想象中的不太一样,原来Drawable在一开始我们并没有设置它的位置

那么我们应该如何将drawable居中显示文字的旁边?

用一张草图表示大概是这个样子的:

中间那部分就是我们想要的位移,通过下面的计算就可以得到所要的位移,

而getWidth()这些参数需要在Layout之后才可以得到,

所以我们干脆在onDraw中对drawable进行位移

需要特别注意的一点是,我们需要事先将Drawable的Bounds(尺寸和位置)保存起来作为参考,原因是如果在原来Drawable的Bounds基础上偏移,在每次onDraw()时会不断向右偏移。

例如第一次onDraw()偏移是5,第二次onDraw()是在原来的5再次偏移5。

似乎看起来还是有一点点别扭,从效果上看出文字和drawable是一起居中的,

看了一下TextView的源码发现setCompoundDrawables后会先划分出TextView左侧及右侧drawable需要的空间,

然后再按照剩余的空间来居中显示,

所以最后得到通过位移得到的效果是文字和drawable一起居中显示的。

为了让文字在整个布局的中间,我们可以通过平移画布来实现文字的居中效果

主要也是通过 getLayoutParams()width和 getLayoutParams()height来改变布局的尺寸,

在开始收缩时先将文本设置为空字符、drawablePadding设为0,然后再开始收缩动画,具体的方式可以自行尝试

本文介绍了带加载效果的按钮实现整体思路,然鹅如果想要真正使用并没有文中介绍的那么简单,还需要考虑各种细节和因素。(头发又变少了呢~)

最后可以看下完整实现的效果,已经上传到github上了( LoadingButton ),加了一些功能(本来只是想简单实现一个按钮旁边有一个Loading,结果功能越写越多就变成这样,苦笑~)

有兴趣朋友可以给个星星,提提issue喝喝茶,我是新来的第一次写这种文章请多多包涵呀。

以上就是关于如何在windows窗口添加一个关闭按钮全部的内容,包括:如何在windows窗口添加一个关闭按钮、C#如何改button形状、带你撸一个带加载功能的按钮 (LoadingButton Android)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9815276.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存