功能键的问题在于,用户界面并非固定的,用户功能键的选择将使屏幕画面处于不同的显示状态下。

处理功能键

功能键的问题在于,用户界面并非固定的,用户功能键的选择将使屏幕画面处于不同的显示状态下。例如,主画面如图1:

图1 主画面

当用户在设置XX上按下Enter键之后,画面就切换到了设置XX的界面,如图2:

图2 切换到设置XX画面

程序如何判断用户处于哪一画面,并在该画面的程序状态下调用对应的功能键处理函数,而且保证良好的结构,是一个值得思考的问题。

让我们来看看WIN32编程中用到的"窗口"概念,当消息(message)被发送给不同窗口的时候,该窗口的消息处理函数(是一个callback函数)最终被调用,而在该窗口的消息处理函数中,又根据消息的类型调用了该窗口中的对应处理函数。通过这种方式,WIN32有效的组织了不同的窗口,并处理不同窗口情况下的消息。

我们从中学习到的就是:

(1)将不同的画面类比为WIN32中不同的窗口,将窗口中的各种元素(菜单、按钮等)包含在窗口之中;

(2)给各个画面提供一个功能键"消息"处理函数,该函数接收按键信息为参数;

(3)在各画面的功能键"消息"处理函数中,判断按键类型和当前焦点元素,并调用对应元素的按键处理函数。

/* 将窗口元素、消息处理函数封装在窗口中 */

struct windows

{

BYTE currentFocus;

ELEMENT element[ELEMENT_NUM];

void (*messageFun) (BYTE keyValue);

};

/* 消息处理函数 */

void messageFunction(BYTE keyValue)

{

BYTE i = 0;

/* 获得焦点元素 */

while ( (element [i].ID!= currentFocus)&& (i < ELEMENT_NUM) )

/* "消息映射" */

if(i < ELEMENT_NUM)

{

switch(keyValue)

{

case OK:

element[i].OnOk();

break;

}

}

}

在窗口的消息处理函数中调用相应元素按键函数的过程类似于"消息映射",这是我们从WIN32编程中学习到的。编程到了一个境界,很多东西都是相通的了。其它地方的思想可以拿过来为我所用,是为编程中的"拿来主"。

在这个例子中,如果我们还想玩得更大一点,我们可以借鉴MFC中处理MESSAGE_MAP的方法,我们也可以学习MFC定义几个精妙的宏来实现"消息映射"。

处理数字键

用户输入数字时是一位一位输入的,每一位的输入都对应着屏幕上的一个显示位置(x坐标,y坐标)。此外,程序还需要记录该位置输入的值,所以有效组织用户数字输入的最佳方式是定义一个结构体,将坐标和数值捆绑在一起:

/* 用户数字输入结构体 */

typedef struct tagInputNum

{

BYTE byNum; /* 接收用户输入赋值 */

BYTE xPos; /* 数字输入在屏幕上的显示位置x坐标 */

BYTE yPos; /* 数字输入在屏幕上的显示位置y坐标 */

}InputNum, *LPInputNum;

那么接收用户输入就可以定义一个结构体数组,用数组中的各位组成一个完整的数字:

InputNum inputElement[NUM_LENGTH]; /* 接收用户数字输入的数组 */

/* 数字按键处理函数 */

extern void onNumKey(BYTE num)

{

if(num==0|| num==1) /* 只接收二进制输入 */

{

/* 在屏幕上显示用户输入 */

DrawText(inputElement[currentElementInputPlace].xPos, inputElement[currentElementInputPlace].yPos, "%1d", num);

/* 将输入赋值给数组元素 */

inputElement[currentElementInputPlace].byNum = num;

/* 焦点及光标右移 */

moveToRight();

}

}

将数字每一位输入的坐标和输入值捆绑后,在数字键处理函数中就可以较有结构的组织程序,使程序显得很紧凑。

整理用户输入

继续第2节的例子,在第2节的onNumKey函数中,只是获取了数字的每一位,因而我们需要将其转为有效数据,譬如要转为有效的XXX数据,其方法是:

/* 从2进制数据位转为有效数据:XXX */

void convertToXXX()

{

BYTE i;

XXX = 0;

for (i = 0; i < NUM_LENGTH; i++)

{

XXX += inputElement[i].byNum*power(2, NUM_LENGTH - i - 1);

}

}

反之,我们也可能需要在屏幕上显示那些有效的数据位,因为我们也需要能够反向转:

/* 从有效数据转为2进制数据位:XXX */

void convertFromXXX()

{

BYTE i;

XXX = 0;

for (i = 0; i < NUM_LENGTH; i++)

{

inputElement[i].byNum = XXX / power(2, NUM_LENGTH - i - 1) % 2;

}

}

当然在上面的例子中,因为数据是2进制的,用power函数不是很好的选择,直接用"<< >>"移位操作效率更高,我们仅是为了说明问题的方便。试想,如果用户输入是十进制的,power函数或许是唯一的选择了。

总结

本篇给出了键盘操作所涉及的各个方面:功能键处理、数字键处理及用户输入整理,基本上提供了一个全套的按键处理方案。对于功能键处理方法,将LCD屏幕与Windows窗口进行类比,提出了较新颖地解决屏幕、键盘繁杂交互问题的方案。

计算机学的许多知识都具有相通性,因而,不断追赶时髦技术而忽略基本功的做法是徒劳无意的。我们最多需要"精通"三种语言(精通,一个在如今的求职简历里泛滥成灾的词语),最佳拍档是汇编、C、C++(或JAVA),很显然,如果你"精通"了这三种语言,其它语言你应该是可以很快"熟悉"的,否则你就没有"精通"它们。

c语言嵌入式开发键盘,C语言嵌入式系统编程修炼之键盘操作篇相关推荐

  1. C语言嵌入式系统编程修炼之道——背景篇

    C语言嵌入式系统编程修炼之道--背景篇 作者:宋宝华  e-mail:[email]21cnbao@21cn.com[/email] 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势 ...

  2. java切入式编程显示屏_C语言嵌入式系统编程修炼之四:屏幕操作

    C语言嵌入式系统编程修炼之四:屏幕操作 作者:宋宝华   更新日期:2005-07-22 汉字处理 现在要解决的问题是,嵌入式系统中经常要使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要 ...

  3. 【转载】C语言嵌入式系统编程修炼之二:软件架构篇

    C语言嵌入式系统编程之软件架构篇 模块划分 模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求.C语言作为一种结构化的程序设 ...

  4. C语言嵌入式系统编程修炼之内存操作

    数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力.在嵌入式系统的实际调试中,多借助C语言指针所具 ...

  5. C语言嵌入式系统编程修炼

    C语言嵌入式系统编程修炼之内存操作篇 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力.在嵌入式 ...

  6. C语言嵌入式系统编程修炼(经典中的经典)

    C语言嵌入式系统编程修炼      http://blog.chinaunix.net/u/25764/showart_326589.html转载自这里,真是太经典了. C语言嵌入式系统编程修炼   ...

  7. C语言嵌入式系统编程修炼之(四)屏幕操作

    C语言嵌入式系统编程修炼之屏幕操作 汉字处理 现在要解决的问题是,嵌入式系统中经常要使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能.例如,一个微波炉的LCD上没有必要提供显示 ...

  8. 编写书籍《C语言嵌入式系统编程修炼之道》序言

    序言        目前,嵌入式系统已经无处不在,遍布于世界的每一个角落.智能家电.手机.PDA.汽车.通信电台等几乎所有的电力.电器与电子产品都包含一个或多个嵌入式系统.有人的地方就有江湖,有电的地 ...

  9. C语言嵌入式系统编程修炼之道——性能优化篇

    C语言嵌入式系统编程修炼之道--性能优化篇 作者:宋宝华  e-mail:[email]21cnbao@21cn.com[/email] 1.使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌 ...

最新文章

  1. 全面解读PyTorch内部机制
  2. SQL之 Stuff和For xml path
  3. java mysql 自动提交_Mybatis的JDBC提交设置/关闭mysql自动提交------关于mysql自动提交引发的惨剧...
  4. 用996打败员工,用“奋斗”替代生活
  5. 三步法助你快速定位网站性能问题
  6. android 联系人中,在超大字体下,加入至联系人界面(ConfirmAddDetailActivity)上有字体显示不全的问题...
  7. 我理解的Sentinel:时间窗统计
  8. x2检验(chi-square test)或称卡方检验
  9. 江恩买卖规则中的定性与定量分析方法
  10. 银行数据仓库体系实践(15)--数据应用之巴塞尔新资本协议
  11. 新西兰计算机设计专业,2020年出国新西兰学习计算机专业的要求是什么?
  12. 全国大学生英语竞赛C类
  13. TensorFlow2.0 Guide官方教程 学习笔记20 -‘Effective TensorFlow 2‘
  14. 甘教课标版小学生计算机课,测评:《第6课 制作简单的表格教案》小学信息技术甘教课标版五年级上册教案4696(2)...
  15. 如何编辑小红书种草文案?小红书怎么编写种草文案?
  16. 实测超轻量中文OCR开源项目,总模型仅17M
  17. 汉字转拼音 python_python实现将汉字转换成汉语拼音的库
  18. 分页LIMIT和OFFSET关键字
  19. sklearn入门——聚类算法KMeans
  20. python下载图片 referer_Python必应超清壁纸爬虫下载|Python爬取必应每日图片源码 - PS下...

热门文章

  1. 网络名称以太网网络2/3修改成网络
  2. pcl::MovingLeastSquares滑动最小二乘
  3. 数据挖掘实践 —— OneR 分类算法
  4. 计算10光年是多少米java_1光年是多少米,9.46×10^15米(最快的火箭需飞108000年)...
  5. Excel中使用名称定义常数
  6. 2022年——CSDN有一个充满活力的【红目香薰】
  7. 刚刚!国产大数据基础软件第一股星环科技成功上市,开盘大涨超52%
  8. android开源日志库的使用
  9. IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应
  10. 【原创整理】软件测试自我记录(目前携程+招银网络科技)