项目越来越紧,我也乐此不疲。自从上次C#制作高仿360安全卫士窗体(三)出来之后,就开始有一些人在说为什么还在坚持写这么落后的东西。我想说的是,我是从事企业信息化工作的,所有程序都只对内部使用。所以只要能满足需求就可以,比较高端先进的技术也没有时间去学习研究。
OK继续上次的内容。上次说到制作文本框,今天要写的是怎么实现水晶按钮的制作。下面是效果图:

下面是这个按钮所需要的图片素材,该素材也提取自360安全卫士。我自己做了一点点小的修改(另存为图片就可以使用):

一、嵌入资源
将以上素材另存为,将图片保存在解决方案中Images目录下的ButtonImages文件夹中,并设置图片属性中生成操作选择为“嵌入的资源”。

二、添加控件
资源嵌入之后再在ControlEx目录中建立一个名为GlassButton的文件夹用来存放该控件的代码。再在该目录中建立一个名为GlassButton的用户控件
三、编码
和之前的控件一样,最开始先把该控件拥有的状态定义出来,这里我定义了四种状态:

     #region 控件状态
/// <summary>
/// 控件状态
/// </summary>
public enum State
{
/// <summary>
/// 无
/// </summary>
Normal = ,
/// <summary>
/// 获得焦点
/// </summary>
Focused = ,
/// <summary>
/// 失去焦点
/// </summary>
LostFocused = ,
/// <summary>
/// 鼠标指针进入控件
/// </summary>
MouseEnter =
}
#endregion

下面是该控件的所有代码和之前基本一样:

 /// <summary>
/// Toolbar控件
/// </summary>
public class GlassButton : Control
{
#region//私有变量
private int bmp_Left;
private const int bmp_Top = ;
private const int bmp_Size = ;
private bool _focused = false;
private State state = State.Normal;
public Bitmap _BackImg = ImageObject.GetResBitmap("FANGSI.UI.Images.ButtonImages.Toolbar_Hover.png"); private Bitmap _bmp = null;
#endregion #region//构造函数
public GlassButton()
{
try
{
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.StandardDoubleClick, false);
this.SetStyle(ControlStyles.Selectable, true);
ResizeRedraw = true;
BackColor = Color.Transparent;
ForeColor = Color.White;//初始文本颜色
Size = new Size(, );//初始大小
Font = new Font("微软雅黑", , System.Drawing.FontStyle.Bold);//控件字体
}
catch { }
}
#endregion #region//属性
/// <summary>
/// 获取或设置控件显示的图片
/// </summary>
[CategoryAttribute("放肆雷特扩展属性"), Description("获取或设置控件显示的图标")]
public Bitmap Bitmap
{
get { return _bmp; }
set
{
_bmp = value;
Invalidate(false);
}
} /// <summary>
/// 重写控件焦点属性
/// </summary>
[CategoryAttribute("放肆雷特扩展属性"), Description("重写控件焦点属性")]
public new bool Focused
{
get { return _focused; }
set
{
_focused = value; if (_focused)
state = State.Focused;
else
state = State.LostFocused; Invalidate(false);
}
}
#endregion #region//重载事件
//自定义绘制
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality; switch (state)
{
case State.Focused:
{
DrawSelected(g);
break;
}
case State.MouseEnter:
{
if (!Focused)
//g.DrawImage(Properties.Resources.enter, ClientRectangle);
ImageDrawRect.DrawRect(g, _BackImg, ClientRectangle, , );
else
DrawSelected(g);
break;
}
} DrawImage(g);
DrawText(g);
} //焦点进入
protected override void OnEnter(EventArgs e)
{
base.OnEnter(e);
Focused = true;
} //失去焦点
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
Focused = false;
} //禁止调整大小
protected override void OnResize(EventArgs e)
{
Width = ;
Height = ;
} protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
state = State.MouseEnter;
Invalidate(false);
} protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (!Focused)
{
state = State.LostFocused;
Invalidate(false);
}
} //只响应单击鼠标左键事件
protected override void OnClick(EventArgs e)
{
MouseEventArgs m = (MouseEventArgs)e;
if (m.Button == MouseButtons.Left)
{
base.OnClick(e);
Focus();
}
}
#endregion #region//方法 #region//Draw
void DrawSelected(Graphics g)
{
ImageDrawRect.DrawRect(g, _BackImg, ClientRectangle, , );
} void DrawImage(Graphics g)
{
if (_bmp != null)
{
Bitmap bmp = ScaleZoom(_bmp);
bmp_Left = (Width - bmp.Width) / ;
g.DrawImage(bmp, new Rectangle(bmp_Left, bmp_Top, bmp.Width, bmp.Height));
}
} void DrawText(Graphics g)
{
SizeF size = g.MeasureString(Text, Font);
g.DrawString(Text, Font, new SolidBrush(ForeColor), (Width - size.Width) / , );
}
#endregion #region//按比例缩放图片
public Bitmap ScaleZoom(Bitmap bmp)
{
if (bmp != null)
{
double zoomScale;
if (bmp.Width > bmp_Size || bmp.Height > bmp_Size)
{
double imageScale = (double)bmp.Width / (double)bmp.Height;
double thisScale = ; if (imageScale > thisScale)
{
zoomScale = (double)bmp_Size / (double)bmp.Width;
return BitMapZoom(bmp, bmp_Size, (int)(bmp.Height * zoomScale));
}
else
{
zoomScale = (double)bmp_Size / (double)bmp.Height;
return BitMapZoom(bmp, (int)(bmp.Width * zoomScale), bmp_Size);
}
}
}
return bmp;
}
#endregion #region//缩放BitMap
/// <summary>
/// 图片缩放
/// </summary>
/// <param name="bmpSource">源图片</param>
/// <param name="bmpSize">缩放图片的大小</param>
/// <returns>缩放的图片</returns>
public Bitmap BitMapZoom(Bitmap bmpSource, int bmpWidth, int bmpHeight)
{
Bitmap bmp, zoomBmp;
try
{
bmp = new Bitmap(bmpSource);
zoomBmp = new Bitmap(bmpWidth, bmpHeight);
Graphics gh = Graphics.FromImage(zoomBmp);
gh.InterpolationMode = InterpolationMode.HighQualityBicubic;
gh.DrawImage(bmp, new Rectangle(, , bmpWidth, bmpHeight), new Rectangle(, , bmp.Width, bmp.Height), GraphicsUnit.Pixel); gh.Dispose();
return zoomBmp;
}
catch
{ }
finally
{
bmp = null;
zoomBmp = null;
GC.Collect();
}
return null;
}
#endregion #endregion
}

编译通过后即可在工具箱中使用,图标需要自己去找。至此360高仿安全卫士系列文章已经基本完了。没有写什么,就主要记录一下自己的开发历程。过几天整理源码上传上来,给大家下载使用。


本文来自 放肆雷特 | 胖子的技术博客

C#制作高仿360安全卫士窗体(四)- 水晶按钮的更多相关文章

  1. C#制作高仿360安全卫士窗体<二>

    继上次C#制作高仿360安全卫士窗体<一>发布之后响应还不错,我的博客放肆雷特也来了不少的新朋友,在这里先谢谢大家的支持!我自己也反复看了一下觉得对不起大家,写的非常乱而且很少文字介绍.在 ...

  2. C#制作高仿360安全卫士窗体(三)

    距上篇C#制作高仿360安全卫士窗体(二)也将近一个多月了,这个月事情还是像往常一样的多.不多我也乐在其中,毕竟我做的是我喜欢做的东西.今天特地抽空把怎么制作文本框写一下.同时也希望有爱好这些玩意的同 ...

  3. C#制作高仿360安全卫士窗体3

    C#制作高仿360安全卫士窗体(三)   距上篇C#制作高仿360安全卫士窗体(二)也将近一个多月了,这个月事情还是像往常一样的多.不多我也乐在其中,毕竟我做的是我喜欢做的东西.今天特地抽空把怎么制作 ...

  4. C#制作高仿360安全卫士窗体2

    C#制作高仿360安全卫士窗体 继上次C#制作高仿360安全卫士窗体<一>发布之后响应还不错,我的博客放肆雷特也来了不少的新朋友,在这里先谢谢大家的支持!我自己也反复看了一下觉得对不起大家 ...

  5. C#制作高仿360安全卫士窗体<一>

    开始写这一系列博客之前先要向大家说声抱歉,放肆雷特建立很久却很少有更新.当然博客人气也不旺,大部分都是看的人多评论收藏的人少.一直想要改变这种状态,正好赶上了最近工作上做了一个高仿360安全卫士窗体. ...

  6. 高仿360界面的实现(用纯XML和脚本实现)

    源码下载:360UI 本项目XML的桌面渲染依赖GQT开源项目(请感兴趣的朋友加入QQ讨论群:101189702,在群共享文件里下载GQT源码),以下是360界面实现的全部XML代码,所有的代码都在3 ...

  7. C# WPF仿360安全卫士11

    首先上效果图: 这是我的第一篇随笔,最近因为写一个播放器,开始学习WPF相关技术,随着不断入坑,播放器倒是做出来了,掉坑里了... 本着闲着也是闲着的精神,拿360开刀了: 主界面主要使用DMSkin ...

  8. (原创)高仿360云盘android端的UI实现

    前些日子几大互联网巨头展开了一轮网盘空间大战.一下子从G级别提高到了T级别.以后谁的空间没有1T估计都不好意思开口了~~~ 试用了一下360云盘的客户端,比较小清新(不是给360打广告~~~).刚好U ...

  9. 制作高仿QQ的聊天系统(上)—— 布局文件 & 减少过度绘制

    由于没有自己的服务器,我就找了个能实现双方通信的SDK,这个SDK是友盟的用户反馈SDK.本系列的博文关注的不是网络通信,而是如何在网络通信机制已经做好的情况下,做出一个可用的聊天系统.其实,刚开始做 ...

随机推荐

  1. 一款非常简单的android音乐播放器源码分享给大家

    一款非常简单的android音乐播放器源码分享给大家,该应用虽然很小,大家常用的播放器功能基本实现了,可能有点还不够完善,大家也可以自己完善一下,源码在源码天堂那里已经有了,大家可以到那里下载学习吧. ...

  2. Stop PeopleCode Processing with Error

    A blunt, but useful method for debugging PeopleCode is to use the inbuilt "Error" function ...

  3. VS2008无法切换到视图设计器

    编写人:CC阿爸 2014-2-17 近来用于干活的笔记本电脑实在太慢了,在领导的安排下,有幸更换了一台配置好的电脑.经过一天的努力,所有之前的开发软件都安装完成了.并且OS从xp升级到win7.SQ ...

  4. arguments .length .callee caller

    如果有一个函数像下面这样: function fn(){ } 那么fn这个函数下面就有一个arguments属性(你在逗我么,后面又说对象),该属性是个对象(typeof一下就知道了),然后它下面也有 ...

  5. 如何验证 jemalloc 优化 Nginx 是否生效

    Jemalloc 源于 Jason Evans 2006年在 BSDcan conference 发表的论文:<A Scalable Concurrent malloc Implementati ...

  6. php验证手机号码

    大家都应该有这个常识,中国的手机号码都是以数字“1”开头,然后利用“0~9”10个数字组成的11位数字组合,那么我们的验证规则肯定要根据这个思路来写. 根据上面的简单思路,我们便可以写下以下的验证代码 ...

  7. C# 多线程 简单使用方法以及常用参数

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. Python学习教程(learning Python)--3.3 分支语句的条件表达式详解

    本节主要讨论分支语句的条件表达式问题. 在if或者if-else分支控制语句里由于都用到条件判断(表达式是真还是假),条件判断可以是一种关系运算也可以是布尔表达式. 本节将对if及if-else语句的 ...

  9. Python学习教程(learning Python)--2.2 Python下的变量基础

    变量的基本概念,变量可以这样去理解,变量是一个值,这个值存储在计算机的内存里.以 网购为例,您在选购傻商品的时候,是在不同页面里选不同的商品,选好一件点击“放入购物车”,选完了再点击去结帐,这些商品的 ...

  10. arm 基本

    ARMr0-r4 传递参数与返回值r7 帧指针 指向母函数被调用子函数在栈看中的交界栈帧指针(Frame Pointer).指向前一个保存的栈帧(stack frame)和链接寄存器(link reg ...