博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言嵌入式系统编程修炼之道——键盘操作篇
阅读量:6829 次
发布时间:2019-06-26

本文共 2815 字,大约阅读时间需要 9 分钟。

语言嵌入式系统编程修炼之道——键盘操作篇

作者:
宋宝华  e-mail:[email]21cnbao@21cn.com[/email]

处理功能键

功能键的问题在于,用户界面并非固定的,用户功能键的选择将使屏幕画面处于不同的显示状态下。例如,主画面如图
1
主画面
当用户在设置
XX
上按下
Enter
键之后,画面就切换到了设置
XX
的界面,如图
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) )
   {
   i++;
   }
  /* 
“消息映射”
 */
   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
),很显然,如果你“精通”了这三种语言,其它语言你应该是可以很快“熟悉”的,否则你就没有“精通”它们。
 本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/120787
,如需转载请自行联系原作者
你可能感兴趣的文章
Linux 软件包管理之RPM
查看>>
Linux bash入门
查看>>
网络协议
查看>>
SecureCRT右键粘贴的设置
查看>>
TurboMail邮件系统定制同步某地产集团微软活动目录服务(AD)用户数据
查看>>
华章9-10月份新书简介(2016年)
查看>>
【Tomcat】面向初级 Web 开发人员的 Tomcat
查看>>
浏览器屏幕宽度相关值得获取
查看>>
vue.js模拟后端请求
查看>>
我的友情链接
查看>>
45 个非常有用的 Oracle 查询语句
查看>>
C#控制台应用程序下 string[] args参数用处
查看>>
linux下vi编辑器命令大全
查看>>
程序员的爱情
查看>>
MySQL 备份和恢复策略
查看>>
简单网络管理协议snmp
查看>>
语言和封装那些事
查看>>
postgres 数据备份与恢复
查看>>
Spring学习总结(2)——Spring的常用注解
查看>>
Java基础学习总结(16)——Java制作证书的工具keytool用法总结
查看>>