2026年10月29日 · 今日 0 帖 · 会员 6.1万 · 主题 17.4万
登录 · 注册 · 游客,欢迎随便逛逛
返回版块
JK-0139725
Lv5甘首五朝臣等级图标
勋章
帖子
86
回复
1,216
积分
850
注册
2013-07-17
[计算机网络]

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

[复制链接]
查看 945 回复 22
楼主 发表于 | 只看该作者
3 人收藏

处理功能键

功能键的问题在于,用户界面并非

固定的,用户功能键的选择将使屏

幕画面处于不同的显示状态下。例

如,主画面如图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) )

  {    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屏幕与 窗

口进行类比,提出了较新颖地解决

屏幕、键盘繁杂交互问题的方案。    计算机学的许多知识都具有

相通性,因而,不断追赶时髦技术

而忽略基本功的做法是徒劳无意

的。我们最多需要“精通“三种语

言(精通,一个在如今的求职简历

里泛滥成灾的词语),最佳拍档是 汇编、C、C++(或JAVA),很显

然,如果你“精通“了这三种语

言,其它语言你应该是可以很

快“熟悉“的,否则你就没有“精

通“它们

Windows    计算机学的许多知识都具有

相通性,因而,不断追赶时髦技术

而忽略基本功的做法是徒劳无意

的。我们最多需要“精通“三种语

言(精通,一个在如今的求职简历

里泛滥成灾的词语),最佳拍档是 汇编、C、C++(或JAVA),很显

然,如果你“精通“了这三种语

言,其它语言你应该是可以很

快“熟悉“的,否则你就没有“精

通“它们。

登录回复
JK-0114486
Lv2独赏二月雪等级图标
帖子
0
回复
234
积分
3,185
注册
2012-07-05
21 楼

揭开

JK-0164651
Lv2独赏二月雪等级图标
帖子
7
回复
110
积分
5,428
注册
2014-07-18
22 楼

就咯啦咯啦咯

登录后可以回复这个帖子。旧账号可使用原密码登录。

登录 注册新号
← 返回版块