edit_note帖子
189
stars积分
850
event加入
2013-07-17
电脑网络
C语言嵌入式系统编程修炼之键盘操作
schedule发表于 2013-09-25 12:39:00
visibility查看 944
chat_bubble回复 22
#1 楼主
处理功能键
功能键的问题在于,用户界面并非
固定的,用户功能键的选择将使屏
幕画面处于不同的显示状态下。例
如,主画面如图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),很显
然,如果你“精通“了这三种语
言,其它语言你应该是可以很
快“熟悉“的,否则你就没有“精
通“它们。
功能键的问题在于,用户界面并非
固定的,用户功能键的选择将使屏
幕画面处于不同的显示状态下。例
如,主画面如图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),很显
然,如果你“精通“了这三种语
言,其它语言你应该是可以很
快“熟悉“的,否则你就没有“精
通“它们。
全部回复 (22)
2013-09-25 12:45:00
沙发
吐天冷了?就来了!
2013-09-25 12:46:00
板凳
看看
2013-09-25 12:46:00
地板
啥
2013-09-25 12:49:00
#5
0.0
2013-09-25 12:51:00
#6
............
2013-09-25 12:54:00
#7
java撸过
2013-09-25 12:55:00
#8
。
2013-09-25 12:56:00
#9
旅途具体了
2013-09-25 13:00:00
#10
。。,
2013-09-25 13:39:00
#11
安卓ZANTI工具包
2013-09-28 07:57:00
#12
我们就是学嵌入式的
2013-09-30 00:11:00
#13
还是他仍然让他本人不是
2013-12-11 16:33:00
#14
发送短信KTQQSY到10001 订购立即生效 5元即可获得 1G省内专属定向流量江苏成功其他等地自测 +
2013-12-12 09:35:00
#15
句子女士
2013-12-29 10:48:00
#16
来咯哦哟
2014-03-19 05:15:00
#17
ll
2014-03-19 10:24:00
#18
吐饿
2014-04-11 22:43:00
#19
鲁若晴
2014-04-15 11:56:00
#20
142
2014-05-12 14:25:00
#21
ghhb
登录 后才能回复
flag举报帖子