C語言嵌入式系統編程修鍊之五:鍵盤操作

來源:互聯網
上載者:User
處理功能鍵

  功能鍵的問題在於,使用者介面並非固定的,使用者功能鍵的選擇將使螢幕畫面處於不同的顯示狀態下。例如,主畫面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螢幕與Windows視窗進行類比,提出了較新穎地解決螢幕、鍵盤繁雜互動問題的方案。

  電腦學的許多知識都具有相通性,因而,不斷追趕時髦技術而忽略基本功的做法是徒勞無意的。我們最多需要"精通"三種語言(精通,一個在如今的求職簡曆裡泛濫成災的詞語),最佳拍檔是彙編、C、C++(或JAVA),很顯然,如果你"精通"了這三種語言,其它語言你應該是可以很快"熟悉"的,否則你就沒有"精通"它們.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.