源:一个简单Led控件

Led控件,可能是非常经典和常用的了,但是很遗憾的是,这个名称至少涵盖了三种控件:
1.是7段式的有发光二极管构成的Led,通常用来显示数字。
2.是指示灯,通常用来闪烁,指示电源,等状态。
3.是由发光二极管阵列组成的模拟显示屏,这种led屏有较高的分辨率,所以可以显示中文内容和一定容量的界面。

这篇文章里面说的是1.其中2这种在codeproject上面有很多例子,我曾经改写其中的例子成为在移动设备上使用。

今天我用c#写了这样一个Led控件。我也曾经下载过,可惜好像没有什么源码,想来这个东西应该没太复杂,所以干脆自己也写个玩玩。记得当年本科时候我就写过单片机程序,控制led数码管,实现了时间调节时闪烁,“霓虹灯”屏保等效果,大大出乎了老师的预期。我想作为一个控件,这个东西的主要功能是为了模拟现实中的用户界面,或者让它更美观,更有趣味一些。而如果只是为了显示一些信息,显然有太多其他的更方便的选择了。所以我用较短的时间实现了一个功能比较简陋的但是能用的控件。

它的运行效果如下:我想这个没什么可说的。

笔画变细以后是这样的:

这里我加载了6个控件,一个定时器,用来实时的显示系统时间。
对于这个控件我想了一下,也许可以使用图片资源来做,比较方便,但我还是把它做成了矢量型的,这样,把一个led中所有笔画(我称为section,段)采用一个六边形模拟,我需要随时能够计算出所有笔画的坐标,这样一个led具有6个点*7段=42个点,这样会占用300多bytes左右。如果显示的数字不多,还是可以不去在乎这点内存的。这就是矢量图的特点,如果你想表现的更细腻,显然会极大加大计算量,脑子也会累的。

然后我用下面的函数计算出七段的坐标:

/// <summary>
/// 重新计算段的坐标!!!(这种方法得出的图形将是矢量的,不受缩放影响)
/// </summary>
private void ComputeSections(int ledwidth,int ledheight)
{
//计算出控件中心点的坐标
int cx=ledwidth/;
int cy=ledheight/; int t1=this.m_SectionThick*/; //大斜坡长
int t2=this.m_SectionThick/; //小斜坡长
int t3=this.m_SectionThick/; //中斜坡长
//段的一半长度!
int hw=cx-this.m_SectionThick-; //half width of section 距离边缘2像素
int hh=cy-this.m_SectionThick-; //half height of section
Section[] s=this.m_Sections; //第0段(最底下一横)
s[].P[].X=cx-hw-this.m_SectionThick/;
s[].P[].Y=cy+hh+this.m_SectionThick/;
s[].P[].X=s[].P[].X-t2;
s[].P[].Y=s[].P[].Y-t2;
s[].P[].X=s[].P[].X+t1;
s[].P[].Y=s[].P[].Y-t1; //第1段(它是中间的一横,因为和其他任何段都没对称关系,只能手写!)
s[].P[].X=cx-hw+this.m_SectionThick*/;
s[].P[].Y=cy+t3;
s[].P[].X=s[].P[].X-t3;
s[].P[].Y=s[].P[].Y-t3;
s[].P[].X=s[].P[].X;
s[].P[].Y=cy-t3; //第2段(最上面一横,与第0段按y轴对称)
for(int i=;i<;i++)
{
s[].P[i].X=s[].P[-i].X;
s[].P[i].Y=ledheight-s[].P[-i].Y;
}
//循环为0,1,2三个水平段的p[3],p[4],p[5]赋值,注意这几个值可以根据钱三个点求出
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
s[i].P[j].X=ledwidth-s[i].P[-j].X;
s[i].P[j].Y=s[i].P[-j].Y;
}
}
//到这里我们已经计算好了0,1,2段的全部坐标,下面开始计算3~6段,他们具有相互对称的关系! //第3段(左上的竖)(注意本身自己也不具备对称关系,6个点都要手写)
s[].P[].X=cx-hw+this.m_SectionThick/;
s[].P[].Y=cy-this.m_SectionThick*/;
s[].P[].X=s[].P[].X-t3;
s[].P[].Y=s[].P[].Y+t3;
s[].P[].X=s[].P[].X-t3;
s[].P[].Y=s[].P[].Y-t3;
s[].P[].X=s[].P[].X;
s[].P[].Y=s[].P[].Y-hh+this.m_SectionThick;
s[].P[].X=s[].P[].X+t2;
s[].P[].Y=s[].P[].Y-t2;
s[].P[].X=s[].P[].X+t1;
s[].P[].Y=s[].P[].Y+t1; //计算4,5,6段的点坐标(4和3段x对称,5和3是y对称,6和3是原点对称)
for(int i=;i<;i++)
{
int m=(-i)%;
s[].P[i].X=ledwidth-s[].P[m].X;
s[].P[i].Y=s[].P[m].Y; s[].P[i].X=s[].P[m].X;
s[].P[i].Y=ledheight-s[].P[m].Y; s[].P[i].X=ledwidth-s[].P[i].X;
s[].P[i].Y=ledheight-s[].P[i].Y;
}
}

上面的代码可能是这个控件里唯一复杂的工作。。。。这是一个很劳累的工作,可是我暂时没想到更好的办法让它更加简化。段的编号顺序是:0底部横,1中部横,2顶部横,3左上竖,4右上竖,5左下竖,6右下竖,7小数点(我暂时没有绘制它)。

显示时,使用一个byte来控制,其所在位为1时,相应的section被点亮,否则为熄灭。
因此,几个基本数字的编码如下:

(byte)0x7d,//
(byte)0x50,//
(byte)0x37,//
(byte)0x57,//
(byte)0x5a,//
(byte)0x4f,//
(byte)0x6f,//
(byte)0x54,//
(byte)0x7f,//
(byte)0x5f,//
(byte)0x02,//-

最后,当我们显示时:

//绘制七段,section是一个struct,包含一个point数组
for(int i=;i<this.m_Sections.Length;i++)
{
if((this.m_DisplayCode & (<<i))!=)
{
this.m_Brush.Color=this.ForeColor;
g.FillPolygon( this.m_Brush, this.m_Sections[i].P);
}
else
{
this.m_Brush.Color=this.m_OffColor;
g.FillPolygon( this.m_Brush, this.m_Sections[i].P);
}
}

对外部可以提供一个简单的属性,displaynumber来获取和设置显示的数字,允许0~9.
也允许外部设置笔画宽度,这样上面的sections坐标需要重新计算,并更新到显示。但是这个属性不能设置的过大,否则坐标值相互超越则显示会出错。

最后我想了一下,目前它的灵活性被我怀疑,加载了6个一摸一样的led控件也让我感到使得代码很笨拙。它现在的功能比较简陋,它可以继续扩展,使他将来能够同时容纳多个显示位。

在最后我提供这个控件以及示例的完整代码下载地址:(当然,它目前还不成熟,在结构和接口上有进一步的进化空间)

http://files.cnblogs.com/hoodlum1980/LedTest_ByHoodlum.rar

C#数码管控件(转)的更多相关文章

  1. HslControls组件库 工业控件库 曲线控件 时间控件 管道控件 温度计控件 阀门控件 传送带控件 进度条控件 电池控件 数码管控件等等

    本篇博客主要对 HslControls 组件做一个大概的总览介绍,更详细的内容可以参照页面里的子链接,还有github上的源代码,然后进行相关的学习,和使用. Prepare 先从nuget下载到组件 ...

  2. Qt编写自定义控件3-速度仪表盘

    前言 速度仪表盘,写作之初的本意是用来展示当前测试的网速用的,三色圆环+数码管显示当前速度,Qt自带了数码管控件QLCDNumber,直接集成即可,同时还带有动画功能,其实也可以用在汽车+工业领域等, ...

  3. MFC控件的SubclassDlgItem

    MFC控件的SubclassDlgItem 要在程序中创建新设计的控件,显然不能用自动创建的办法,因为对话框模板对新控件的特性一无所知.程序可以用手工方法创建控件,在调用派生类的Create函数时,派 ...

  4. wxpython 基本的控件 (按钮)

    使用按钮工作 在wxPython 中有很多不同类型的按钮.这一节,我们将讨论文本按钮.位图按钮.开关按钮(toggle buttons )和通用(generic )按钮. 如何生成一个按钮? 在第一部 ...

  5. ios-控件的frame_center_bounds简单介绍

    frame 例如一个button按钮控件的frame frame是一个结构体,frame表示了button在它的父控件view中的位置---origin 以及---size origin也是一个结构体 ...

  6. SmartZoneOCR识别控件免费下载地址

    SmartZone™光学字符识别工具包,使开发人员能够进行带状区域光学字符识别,带状区域在表单处理应用程序中经常使用.本产品所包含的.NET控件以及ActiveX COM组件在内部使用两种单独的识别技 ...

  7. DataGridView控件

    DataGridView控件 DataGridView是用于Windows Froms 2.0的新网格控件.它可以取代先前版本中DataGrid控件,它易于使用并高度可定制,支持很多我们的用户需要的特 ...

  8. 《Programming WPF》翻译 第3章 1.什么是控件

    原文:<Programming WPF>翻译 第3章 1.什么是控件 对于一个应用程序而言,控件是搭建用户界面的积木.它们具备交互式的特征,例如文本框.按钮以及列表框.尽管如此,WPF还有 ...

  9. wxPython中基本控件学习

    wxPython工具包提供了多种不同的窗口部件,包括了本章所提到的基本控件.我们涉及静态文本.可编辑的文本.按钮.微调.滑块.复选框.单选按钮.选择器.列表框.组合框和标尺.对于每种窗口部件,我们将提 ...

随机推荐

  1. 灵感闪现 篇 (一) 2d场景 3d 效果

    中途打断一下 ,框架文档的 更新. 另开一篇主题为 灵感闪现的 板块. 在工作生活中,总有发现新事物或新东西 而让自己突然 灵感闪现的时候,那么这个时候,我必须要抓住,并尽快把 这份灵感实现下来. 之 ...

  2. 常用的JS页面跳转代码调用大全

    一.常规的JS页面跳转代码 1.在原来的窗体中直接跳转用 <script type="text/javascript"> window.location.href=&q ...

  3. UVA - 12563 Jin Ge Jin Qu hao (01背包变形)

    此题应该注意两个点,首先背包容量应该缩减为t-1,因为最长的歌不超过三分钟,而劲歌金曲有678s,所以肯定要留出这个时间来.其次注意优先级,保证唱的歌曲数目最多,在此前提下尽可能的延长时间. 处理方法 ...

  4. UVALive 2147 Push!!(队列实现DP)

    就我的理解来说这个题,本质上是一个DP题,不应该说是搜索,因为我的做法是把表格中所有的数据都找到,使用队列暴力来遍历出所有状态,因为题目中的数据范围小,所有耗时也小. 首先分析箱子是一个被动物体,人是 ...

  5. Ubuntu下安装Reids

    安装 官网  http://redis.io/    下载安装包 redis-3.0.5.tar.gz 解压 tar -zxvf redis-3.0.5.tar.gz cd redis-3.0.5 安 ...

  6. [IDL入门] 两个PPT,IDL上手

    首先看看IDL能干什么,<Solving Real Problems with Computer Graphics>ppt是英文的,很精彩. 下载地址:http://pan.baidu.c ...

  7. Java Web 错误排查

    排查404 1. 检查web.xml,有没有放在web-inf下面,再检查过滤器有没有配置 <filter> <filter-name>struts</filter-na ...

  8. DNS开源服务器BIND最小配置详解<转>

    一,简介 相对于存储和大数据领域,CDN是一个相对小的领域,但行行出状元,BIND就是CDN领域的蝉联N届的状元郎.BIND是一款非常常用的DNS开源服务器,全球有90%的DNS用BIND实现.值得一 ...

  9. 浅谈Android五大布局

    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...

  10. Repeater嵌套gridview

    前台:<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSour ...