[ZLG-ARM] C语言嵌入式系统编程修炼之键盘操作

[复制链接]
1928|2
 楼主| jumpoo 发表于 2009-5-7 13:01 | 显示全部楼层 |阅读模式
处理功能键<br /><br />  功能键的问题在于,用户界面并非固定的,用户功能键的选择将使屏幕画面处于不同的显示状态下。例如,主画面如图1:<br /><br /><br />图1&nbsp;主画面&nbsp;<br /><br />  当用户在设置XX上按下Enter键之后,画面就切换到了设置XX的界面,如图2:<br /><br /><br />图2&nbsp;切换到设置XX画面&nbsp;<br /><br />  程序如何判断用户处于哪一画面,并在该画面的程序状态下调用对应的功能键处理函数,而且保证良好的结构,是一个值得思考的问题。<br /><br />  让我们来看看WIN32编程中用到的&quot;窗口&quot;概念,当消息(message)被发送给不同窗口的时候,该窗口的消息处理函数(是一个callback函数)最终被调用,而在该窗口的消息处理函数中,又根据消息的类型调用了该窗口中的对应处理函数。通过这种方式,WIN32有效的组织了不同的窗口,并处理不同窗口情况下的消息。<br /><br />  我们从中学习到的就是:<br /><br />  (1)将不同的画面类比为WIN32中不同的窗口,将窗口中的各种元素(菜单、按钮等)包含在窗口之中;<br /><br />  (2)给各个画面提供一个功能键&quot;消息&quot;处理函数,该函数接收按键信息为参数;<br /><br />  (3)在各画面的功能键&quot;消息&quot;处理函数中,判断按键类型和当前焦点元素,并调用对应元素的按键处理函数。<br /><br />/*&nbsp;将窗口元素、消息处理函数封装在窗口中&nbsp;*/<br />struct&nbsp;windows<br />{<br /> BYTE&nbsp;currentFocus;<br /> ELEMENT&nbsp;element[ELEMENT_NUM];<br /> void&nbsp;(*messageFun)&nbsp;(BYTE&nbsp;key);<br /> …<br />};<br />/*&nbsp;消息处理函数&nbsp;*/<br />void&nbsp;message(BYTE&nbsp;key)<br />{<br /> BYTE&nbsp;i&nbsp;=&nbsp;0;<br /> /*&nbsp;获得焦点元素&nbsp;*/<br /> while&nbsp;(&nbsp;(element&nbsp;.ID!=&nbsp;currentFocus)&&&nbsp;(i&nbsp;&lt&nbsp;ELEMENT_NUM)&nbsp;)<br /> {<br />  i++;<br /> }<br /> /*&nbsp;&quot;消息映射&quot;&nbsp;*/<br /> if(i&nbsp;&lt&nbsp;ELEMENT_NUM)<br /> {<br />  switch(key)<br />  {<br />   case&nbsp;OK:<br />    element.OnOk();<br />    break;<br />   …<br />  }<br /> }<br />}&nbsp;<br /><br />  在窗口的消息处理函数中调用相应元素按键函数的过程类似于&quot;消息映射&quot;,这是我们从WIN32编程中学习到的。编程到了一个境界,很多东西都是相通的了。其它地方的思想可以拿过来为我所用,是为编程中的&quot;拿来主义&quot;。<br /><br />  在这个例子中,如果我们还想玩得更大一点,我们可以借鉴MFC中处理MESSAGE_MAP的方法,我们也可以学习MFC定义几个精妙的宏来实现&quot;消息映射&quot;。<br /><br /><br />--------------------------------------------------------------------------------<br /><br />  处理数字键<br /><br />  用户输入数字时是一位一位输入的,每一位的输入都对应着屏幕上的一个显示位置(x坐标,y坐标)。此外,程序还需要记录该位置输入的值,所以有效组织用户数字输入的最佳方式是定义一个结构体,将坐标和数值捆绑在一起:<br /><br /><br />/*&nbsp;用户数字输入结构体&nbsp;*/<br />typedef&nbsp;struct&nbsp;tagInputNum<br />{<br /> BYTE&nbsp;byNum;&nbsp;/*&nbsp;接收用户输入赋值&nbsp;*/<br /> BYTE&nbsp;xPos;&nbsp;/*&nbsp;数字输入在屏幕上的显示位置x坐标&nbsp;*/<br /> BYTE&nbsp;yPos;&nbsp;/*&nbsp;数字输入在屏幕上的显示位置y坐标&nbsp;*/<br />}InputNum,&nbsp;*LPInputNum;<br />&nbsp;<br /><br /><br />  那么接收用户输入就可以定义一个结构体数组,用数组中的各位组成一个完整的数字:<br /><br /><br />InputNum&nbsp;inputElement[NUM_LENGTH];&nbsp;/*&nbsp;接收用户数字输入的数组&nbsp;*/<br />/*&nbsp;数字按键处理函数&nbsp;*/<br />extern&nbsp;void&nbsp;onNumKey(BYTE&nbsp;num)<br />{<br />if(num==0||&nbsp;num==1)&nbsp;/*&nbsp;只接收二进制输入&nbsp;*/<br />{<br /> /*&nbsp;在屏幕上显示用户输入&nbsp;*/<br /> DrawText(inputElement[currentElementInputPlace].xPos,&nbsp;inputElement[currentElementInputPlace].yPos,&nbsp;&quot;%1d&quot;,&nbsp;num);<br /> /*&nbsp;将输入赋值给数组元素&nbsp;*/<br /> inputElement[currentElementInputPlace].byNum&nbsp;=&nbsp;num;&nbsp;<br /> /*&nbsp;焦点及光标右移&nbsp;*/<br /> moveToRight();<br />}<br />}&nbsp;&nbsp;<br /><br /><br />  将数字每一位输入的坐标和输入值捆绑后,在数字键处理函数中就可以较有结构的组织程序,使程序显得很紧凑。<br /><br />  整理用户输入<br /><br />  继续第2节的例子,在第2节的onNumKey函数中,只是获取了数字的每一位,因而我们需要将其转化为有效数据,譬如要转化为有效的XXX数据,其方法是:<br /><br /><br />/*&nbsp;从2进制数据位转化为有效数据:XXX&nbsp;*/<br />void&nbsp;convertToXXX()<br />{<br /> BYTE&nbsp;i;<br /> XXX&nbsp;=&nbsp;0;&nbsp;<br /> for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt&nbsp;NUM_LENGTH;&nbsp;i++)<br /> {&nbsp;<br />  XXX&nbsp;+=&nbsp;inputElement.byNum*power(2,&nbsp;NUM_LENGTH&nbsp;-&nbsp;i&nbsp;-&nbsp;1);<br /> }&nbsp;<br />}&nbsp;<br /><br /><br />  反之,我们也可能需要在屏幕上显示那些有效的数据位,因为我们也需要能够反向转化:<br /><br /><br />/*&nbsp;从有效数据转化为2进制数据位:XXX&nbsp;*/<br />void&nbsp;convertFromXXX()<br />{<br /> BYTE&nbsp;i;<br /> XXX&nbsp;=&nbsp;0;&nbsp;<br /> for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt&nbsp;NUM_LENGTH;&nbsp;i++)<br /> {&nbsp;<br />  inputElement.byNum&nbsp;=&nbsp;XXX&nbsp;/&nbsp;power(2,&nbsp;NUM_LENGTH&nbsp;-&nbsp;i&nbsp;-&nbsp;1)&nbsp;%&nbsp;2;<br /> }&nbsp;<br />}&nbsp;<br /><br /><br />  当然在上面的例子中,因为数据是2进制的,用power函数不是很好的选择,直接用&quot;&lt&lt&nbsp;&gt&gt&quot;移位操作效率更高,我们仅是为了说明问题的方便。试想,如果用户输入是十进制的,power函数或许是唯一的选择了。<br /><br />  总结<br /><br />  本篇给出了键盘操作所涉及的各个方面:功能键处理、数字键处理及用户输入整理,基本上提供了一个全套的按键处理方案。对于功能键处理方法,将LCD屏幕与Windows窗口进行类比,提出了较新颖地解决屏幕、键盘繁杂交互问题的方案。<br /><br />  计算机学的许多知识都具有相通性,因而,不断追赶时髦技术而忽略基本功的做法是徒劳无意的。我们最多需要&quot;精通&quot;三种语言(精通,一个在如今的求职简历里泛滥成灾的词语),最佳拍档是汇编、C、C++(或JAVA),很显然,如果你&quot;精通&quot;了这三种语言,其它语言你应该是可以很快&quot;熟悉&quot;的,否则你就没有&quot;精通&quot;它们。<br />
acertm 发表于 2009-5-7 13:19 | 显示全部楼层

感谢楼主

  
acertm 发表于 2009-5-12 13:14 | 显示全部楼层

需要深入学习啊

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

92

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部