C语言实现的简易可移植GUI控件库

从大一开始接触到单片机(MCU),一直都觉得挺好玩的。从8位的51单片机到16位的TI MSP系列的单片机都尝试学过。感觉还不错,不过,以前一直都觉得32位的ARM处理器距离自己很遥远。幸运的是,如今我确实有机会接触一款32位的处理器了。当然使用的是Cortext M4内核,TI Stellaris系列处理器之一。
      在这几天的学习中,发现高端的处理器确实很强大,不管是内存,FLash存储空间,还是内部的各种硬件资源都极为丰富。也让我一时间不知所措了。此外,还学习了下TFT彩屏的操作。要知道,以前接触的显示器都只是数码管或者是只能显示ASCII码的1602液晶屏(而且还要动态刷新)。既然接触到了彩屏,就要玩个痛快。
      在实验室的时候,看到队友们每次需要借助于显示器来编写一些小程序时,如为了绘制出一个“按钮”或者一个进度条都大费周折。虽说最终他们也做了出来,可是我总觉得那样不是特别好。有两个原因,第一,代码的可移植性不够高;第二,代码结构不够清晰。这两点我是相当忌讳的。如果要是看到main.c里面用了那么多的代码只是为了绘制几个“按钮”,看起来会相当难受。所以,我在使用的过程中就想到,为什么我不像在Windows下编写程序那样,把那些“按钮”, “进度条”什么的封装起来呢?这样我们在以后的使用中就可以轻松再创建这些对象了。
      于是,就决定创建一个简易的GUI控件库,供这些小彩屏使用。
      说一下大体的思路吧。高人看来自然觉得我的做法确实很笨拙,而且并不总是特别理想的。但不管怎么说,这也是我第一次尝试用C语言封装的一个库,我想还是能学到不少东西的。年轻人总会犯错误的嘛!

好了,先看下我的guilib库文件的目录结构吧:

为了方便后期的移植,大体上给分了3个层:

1、与底层相关的接口部分:

在这一层中,主要是和显示器驱动打交道的。与这一层有关的文件夹主要是"lcddriverlibs",提供了直接操作显示屏的底层驱动程序。可以看到在文件"grahic.h"中有如下几个函数:

1 void LcdInitialize(void);
2 void LcdPixelDraw(int32_t x, int32_t y, uint32_t color);
3 void LcdPixelDrawMultiple(int32_t x, int32_t y, int32_t x0, int32_t count,
4         int32_t bpp, const uint8_t *pui8Data, const uint8_t *pui8Palette);
5 void LcdLineDrawH(int32_t xStart, int32_t xStop, int32_t y, uint32_t color);
6 void LcdLineDrawV(int32_t x, int32_t yStart, int32_t yStop, uint32_t color);
7 void LcdRectFill(int32_t xStart, int32_t yStart, int32_t xStop, int32_t yStop,
8         uint32_t color);
9 uint32_t LcdColorTranslate(uint32_t color);

这些函数接口在移植时需要重新实现他们,可以在文件"grahic.c"中重新定义。通常,需要更换文件夹"lcddriverlibs"中的驱动程序,然后再根据驱动程序,重写"grahic.c"中的几个接口。这几个接口函数的命名其实是模仿了TI stellaris图形库的命名。他们提供了基础的绘点,绘线,填充等操作。此外,这些函数在重新实现时,不能够更改他们的接口,如参数,函数名称。否则上层的控件将不能正常绘制。这是必须要遵守的规则。

对了,最后那个函数主要是用来将24位的真彩色转换为显示器支持的色彩。由于并非所有的TFT彩屏都支持24位色彩,所以必须要做适当地转换。

2、基础绘图层:

在这一层中,由于目前时间有限,只是实现了几个简单的基础绘图函数。比如常用的画点,画线,画矩形,填充矩形等等。这一层是与硬件层隔离的,他们实际上调用了来自上一层中定义的那些个函数。所以,必须要保证与硬件有关的那一层的几个函数接口工作正常才可以。总的来说,如果程序中只需要绘一些简单的图形,只需要使用这里面提供的函数接口就可以了。

3、“控件”层:

这一层便是最顶层了,提供了一些常用的控件:矩形按钮,选择框,进度条,滑动条,标签等等(待时间充裕了可能还会继续完善,因为目前只需要这些就够用了,我们没有做太复杂的程序)。对于这些控件对象,都有相应的结构体类型定义,比如tRectangle等。

为了能够管理这些控件,我使用了一个顺序表来存储每一个被绘制到屏幕上的控件对象的指针。当然,也可以使用链表来实现,不过不想太麻烦,暂时使用顺序表代替,虽说占用的控件稍微多了点,但还可以接收的。然后,当我从屏幕中移除一个控件对象时,便从那个列表中删除掉这个对象的指针。为了安全起见,我为每一种控件对象都提供了单独的顺序表来存储。即每一个表只存储单一种类的控件对象。

这样做的原因有两点,第一,可以在实现文件中将表定义成为static的,这样,用户在使用库时,并不能访问我用来管理控件对象的表,也就是说不会修改掉这个表。此外,用户也不需要知道我是如何管理这些显示在屏幕上显示的对象。对他们来说就是透明的。第二,由于每个表只管理一种控件对象,我们在使用表时就无需判断控件类型了。比如,在进行触摸检测时,我们并不需要使用类型识别标志来判断到底是按钮被按下了还是选项框被按下了。因为我们每次只是对一种类型的控件进行检测。另外,我们在整体刷新所有控件时,可以轻松地调用正确的刷新函数来实现(当然,如果是用C++的话,也不用这么麻烦了)。

总结一下,大体的三层结构就是这样的,当然,分层并没有什么新意,只是为了方便说明和实现而已。此外实现中也借鉴了网上的一些方法。

基于控件库做的一个简易计算器,不过计算功能倒没实现。

后记:这个年代,想要原创一些东西出来太难了,但是可以借鉴别人的思想。既然我没有能力创造思想,那么就应该学习成熟的思想,在学习别人成熟的思想中进步,那样也挺好的。对了,关于每个“控件”的具体的代码实现,待有时间再来补充吧。就写这么些了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 13:35:45

C语言实现的简易可移植GUI控件库的相关文章

Java GUI控件SwingX之JXTaskPane的使用示例

JXTaskPane 类似XP 左边的导航栏,在开发Swing应用的时候很好用的. 下面两张截图反应了JXTaskPane的动画效果.可以自由的卷起和展开.     JXTaskPane的的使用步骤: 1.新建一个 JXTaskPaneContainer 2.新建{i}个JXTaskPane   (i>=1) 3.依次将 新建的JXTaskPane 添加到 JXTaskPaneContainer 中去. 4.最后将 JXTaskPaneContainer 添加到JFrame 中. 下面附上 Sw

Atitit.Gui控件and面板----数据库区-mssql 2008 权限 配置 报表查看成员

Atitit.Gui控件and面板----数据库区-mssql 2008 权限 配置 报表查看成员 1. 配置服务器连接权限 1 2. 配置数据库权限 1 3. 设置表格/视图安全性 2 1. 配置服务器连接权限 配置服务器登录--数据库级别的[安全性]-[登录名]-[新建登录名] 角色::public 作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:[email protected] 转载请注明来源: http://blog.csdn.net/attilax 2. 配置数据库权限

支持ZPLor ZPL 语言仿真程序的打印机的条码控件ThermalLabel SDK

ThermalLabel SDK for .NET 条形码控件是一个用VB.NET或C#开发的纯.NET的一个类库(DLL), 可用该组件来设计条码并在Zebra Thermal Printer(任何支持ZPL? or ZPL II? 语言/仿真程序的打印机)上打印这些条码.ThermalLabel SDK可以用于设计和打印简单到复杂的标签布局,它支持文本.条码.图形图象.表格和网格,并能插入如圆.椭圆.矩形以及线条等自选编辑图形. 具体功能: 完全使用托管C#开发. .NET Framewor

atitit.Atitit. Gui控件and面板-----服务端控件 java struts的实现最佳实践

atitit.Atitit.  Gui控件and面板-----服务端控件 java struts的实现最佳实践 1. 服务器控件的类别 1 1.1. 数据控件:该类控件可细分为两种类型:数据源控件和数据绑定控件. 1 1.2. 站点导航控件: 1 1.3. WebParts控件: 1 1.4. 登录控件: 1 1.5. Ajax 控件 1 2. jsf 2 3. Apache  ecs 2 4. Custom ui control... 2 5. Struts UI Tags display d

Atitit. Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g

Atitit.  Gui控件and面板----程序快速启动区--最佳实践Launchy ObjectDock-o0g 两个方式::: 键盘式::先用热键呼叫出QS,然后开始输入程序中的部分字母,按Enter就 是启动这个程序 鼠标式::mouse左的呼叫出面板,分组,点击启动... 作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:[email protected] 转载请注明来源: http://blog.csdn.net/attilax 1. ===Launchy Quicksil

Atitit.Gui控件and面板----web server区----- web服务器监控面板and控制台条目

Atitit.Gui控件and面板----web server区----- web服务器监控面板and控制台条目 1. Resin4.0.22 1 2. 查看http连接数::Summary>>tables 1 2.1.1. Open Connections 1 2.2. TCP ports? 1 3. 查看app::confgi?>>webapps 2 3.1. Host http://localhost:80 2 3.1.1. WebApps 2 4. 查看app2:::   

Atitit.Gui控件and面板----db数据库区----- .数据库比较同步工具 vOa

Atitit.Gui控件and面板----db数据库区----- .数据库比较同步工具 vOa 1. 咨微海信数据库应用 工具 1 2. 数据库比较工具 StarInix SQL Compare   (500K) 3 3. sql delta v5.1 特别版 (15M  推荐) 4 4. RedGate.SQL.Compare.Pro.9.0.0.79 破解版 (9M) 8 5. BXC-SQLServer数据库对象对比工具下载 V1.02免费版_ <BXC-SQL... 8 6. Godsw

GUI控件梳理

GUI控件 GUI是图形用户接口,可以说主要管着用户的输入和输入.刚毕业的时候,天真的我认为控件也就那么几个,学会了也就可以了.后来接触的东西多了才发现,控件太多啦.就想自己总结一下控件. GUI控件功能 接触的所有的gui控件的功能我觉得只有三个.第一个功能是用来显示内容的,典型的就是图片,当然所有的gui控件都有着显示的功能.比如按钮的图片和文本,他向用户传达一个显示内容的信息.第二个功能是事件,典型的就是按钮,我们经常是将一个控件绑定到一个回调函数上,或者说回调事件上,当用户操作这个控件的

GUI 控件学习一(C#)

代码片段: using UnityEngine; using System.Collections; public class SkinTest : MonoBehaviour { public Texture imgbtn; private string textContent ="Textfield"; private string passwordToEdit ="PasswordField"; private string textAreaToEdit =