當前位置: 華文世界 > 數位

【新書推薦】5.1 鍵盤基礎

2024-01-13數位

本章我們講述Windows作業系統關於鍵盤的基礎知識。Windows使用了 8種不同的訊息來表示各種鍵盤事件,通常我們只需要處理鍵盤訊息和字元訊息的處理。

本章學習知識概要:

鍵盤基礎

擊鍵訊息

字元訊息

鍵盤訊息和字元集

插入符號

5.1 鍵盤基礎

本節我們講述關於鍵盤的一些基礎知識。當我們按下一個鍵盤按鍵時,會產生一個鍵盤按鍵訊息。這一點你能確定嗎?假如是一個選單快捷鍵訊息,或者是一個子視窗控制項訊息呢?這就超出了本節討論的範圍,我們將在選單和子視窗控制項詳細講述。假設的確是一個按鍵訊息,它將被送入視窗訊息佇列,做同步處理。在訊息迴圈中,GetMessage函式獲取到按鍵訊息後,如果是一個字元按鍵訊息,TranslateMessage函式會將其轉化為字元訊息WM_CHAR並將其送入訊息佇列,然後再由DispatchMessage函式繼續將按鍵訊息分發給Windows系統。如果是一個非字元按鍵訊息,則直接由DispatchMessage函式將其分發給Windows系統。

本節必須掌握的知識點:

忽略鍵盤

鍵盤焦點

佇列和同步

擊鍵和字元

5.1.1 忽略鍵盤

當我們按下鍵盤按鍵的時候會產生鍵盤按鍵訊息,或者我們呼叫PostMessage或SendMessage函式發送鍵盤訊息,也可能是Windows系統產生的按鍵訊息。所有這些按鍵訊息並不是都需要我們主動去處理的。我們只需要處理真正需要關註的一些按鍵訊息,把一些不需要我們處理的按鍵訊息統統交給Windows系統預設的視窗過程去處理。這些常常忽略的按鍵訊息有以下幾類:

系統按鍵訊息

通常可以忽略一些屬於系統功能的按鍵操作。這些按鍵一般都包含Alt鍵。程式不必去監控這些按鍵訊息,因為Windows會將按鍵的效果通報給程式,在預設情況下,它們會被交付給DefWindowProc函式處理。有時候我們處於某種目的也可能會攔截系統按鍵訊息,在後面的章節中遇到了我們再詳細講述。

鍵盤快捷鍵訊息

許多Windows程式用鍵盤快捷鍵來呼叫常用選單項。快捷鍵經常是Ctrl鍵同功能鍵或 者字母鍵的組合(例如,Ctrl+S鍵用於保存一個檔)。這些鍵盤快捷鍵和程式選單一起在程 序的資源指令碼中定義,這些我們將在第十章中看到。Windows會把這些鍵盤快捷鍵轉換為 選單命令訊息。你不必自己去做轉換,視窗過程只需要處理選單訊息就可以了。

控制項訊息

對話方塊也有鍵盤介面,但是程式不必在對話方塊活躍的時候去監視鍵盤。Windows會處理 鍵盤介面,接著Windows把擊鍵效果的訊息傳送給程式。對話方塊包含了用於文本輸入的編 輯控制項。它們一般是一些小方框,使用者可以輸入字串。Windows處理所有的編輯控制項邏輯,並在使用者輸入完成後,將最終的內容傳送給程式。關於對話方塊,將在第十一章詳細介紹。

編輯控制項不必局限於只有單獨的一行,它的位置也不必局限在對話方塊中。程式主視窗中的多行編輯控制項可以用作一個簡單的文字編輯器。(參見第八章的POPPAD程式。)另外,Windows也有專業的富文本編輯控制項,可以允許你編輯和顯示格式化的文本(第九章我們會詳細講解富文本控制項) 。

當你設計Windows程式時,將會發現可以使用子視窗控制項來處理鍵盤和滑鼠的輸入以 便把更高層的訊息傳回父視窗。只要積累了足夠多的這樣的控制項,你就不會再為處理鍵盤訊息而煩惱了。

5.1.2 鍵盤焦點

假如我們現在按下了一個鍵盤按鍵,但是桌面當前有多個視窗同時存在,那麽就產生了一個問題,這個按鍵訊息會送入到哪個視窗的訊息佇列呢?

我們在第二章2.3節訊息機制中講述過,當使用者按下一個按鍵時,產生的按鍵訊息會被送入到Windows系統總的訊息佇列,然後根據按鍵訊息所屬的視窗將其送入到對應的視窗訊息佇列。是否還記得MSG訊息結構的第一個欄位就是訊息所屬的視窗控制代碼。意思是當我們按下按鍵的那一刻就已經確定了訊息所屬的視窗,而不是等到送入總訊息佇列後再確定所屬視窗的。那麽,確定訊息所屬視窗的依據是什麽呢?就是當前具有鍵盤輸入焦點的視窗。

接收到這個鍵盤事件的視窗稱為有輸入焦點的視窗。輸入焦點的概念和活動視窗的概 念是緊密相連的。具有輸入焦點的視窗要麽是活動視窗,要麽是活動視窗的子孫視窗——也就是說,活動視窗的子視窗,或者是活動視窗的子視窗的子視窗,等等。

活動視窗通常是很好鑒別的。它總是最上層的視窗——也就是說,它的父視窗控制代碼是 NULL。如果一個活動視窗有標題列,Windows會加亮顯示其標題列。如果活動視窗有會話邊框(常見的對話方塊的外形)而不是標題列,Windows會加亮顯示其邊框。如果活動視窗目前處於最小化狀態,Windows將突出顯示它在工作列中的條目,就像一個按下的按鈕似的。

如果活動視窗有子視窗,具有輸入焦點的視窗可以是活動視窗,也可以是它的子孫視窗中的一個。最常見的子視窗是出現在對話方塊中的如下控制項:按鈕、圓鈕、核取方塊、捲軸、編輯框或列表框。子視窗自己不能成為活躍視窗。僅當它是活躍視窗的子孫視窗時,該子視窗才具有輸入焦點。子視窗控制項通常透過顯示一個閃爍的插入符號或虛線指出輸入焦點。

有時沒有視窗具有輸入焦點。這種情況會發生在所有程式都最小化時。但Windows仍 將發送鍵盤訊息給活動視窗,只不過此時的訊息形式不同於活動視窗沒有最小化時發送的 鍵盤訊息。

視窗過程透過捕獲WM_SETFOCUS和WM_CILLFOCUS訊息來確定自己的視窗是否具有輸入焦點。WM_SETFOCUS表明視窗正在接受輸入焦點,而WM_KILLFOCUS表明視窗正在失去輸入焦點。這些訊息將在本章的稍後部份詳細介紹。

總結

1.活動視窗:桌面最上層視窗,其父視窗控制代碼為NULL,加亮標題列或突出顯示在工作列。

2.焦點視窗:活動視窗的子孫視窗,通常是一個閃爍的插入符或虛線框指示輸入焦點。

3.捕獲WM_SETFOCUS來確定其具有輸入焦點,WM_KILLFOCUS說明正失去焦點。

4.當所有程式都最小化時,沒有視窗具有輸入焦點,Windows仍將發送鍵盤訊息給活動視窗。這時所有擊鍵都產生WM_SYSKEYDOWN和WM_SYSKEYUP訊息。

5.1.3 佇列和同步

當使用者按下和釋放鍵盤上的一個鍵時,Windows和鍵盤裝置驅動程式將硬體掃描碼轉 換為格式化後的訊息。但是,這些訊息並不立即被放入應用程式訊息佇列,而是由Windows 把這些訊息儲存在系統總訊息佇列中。系統訊息佇列是一個單獨的訊息佇列,它被Windows 用來初步儲存使用者從鍵盤和滑鼠輸入的訊息。僅當Windows應用程式完成了對前一個使用者輸入訊息的處理後,Windows才從系統訊息佇列中取出下一條訊息,並把它放入應用程式訊息佇列。

這是一種兩步處理法,即先把訊息儲存在系統訊息佇列裏,再把它們發送到應用程式訊息佇列。采用兩步處理法的原因是需要同步。像我們剛了解的那樣,被期望接收鍵盤輸入的視窗是具有活動焦點的視窗。使用者輸入的速度可能快於應用程式能處理的擊鍵動作,而一個特殊的擊鍵可能會使焦點從一個視窗轉換到另一個視窗。後續的擊鍵也應該跟著到了另一個視窗。但如果後續的擊鍵己經被轉到了目的視窗,且被放置在了應用程式訊息佇列中,則它們不能被輸入到另一個視窗。

圖5-1 訊息佇列

總結

●兩步法處理鍵訊息:先把訊息儲存在系統訊息佇列裏,再發送到應用程式訊息佇列裏。

1.擊鍵事件:將擊鍵轉為訊息,放入系統訊息佇列(註意不立即放入應用程式訊息佇列);

2.應用程式處理完前一個輸入訊息,Windows從系統佇列取下一條訊息放入應用程式訊息佇列。

●兩步處理法的原因——同步

因為當應用程式1接收到一個特殊的、轉換視窗焦點的擊鍵動作時,後續的擊鍵訊息也應被轉移到另一個程式(如應用程式2)的佇列中去。如果鍵盤訊息不經系統佇列的緩沖,當使用者輸入太快,而應用程式1來不及沒處理完這個特殊訊息時,可能後續的擊鍵訊息又被發送到應用程式1的佇列中來了,從而導致錯誤。因此,鍵盤訊息要先放到系統佇列中,起到同步的作用。

5.1.4 擊鍵和字元

應用程式從Windows接收的關於鍵盤事件的訊息可分為擊鍵和字元兩種。

首先,你可以認為鍵盤是鍵的集合。鍵盤上僅有一個鍵標示為「A」。按下此鍵是一次擊鍵,釋放此鍵也認為是一次擊鍵。同時鍵盤也是能產生可顯示字元或者控制字元的輸入裝置。「A」鍵能產生一些不同的字元,這取決於同Ctrl、Shift、Caps Lock鍵的組合,通常地,此字元為小寫字母「a」 。如果Shift鍵被按下或者Caps Lock鍵被釘選,此字元就為大寫字母「A」。如果Ctrl鍵被按下,則此字元就是Ctrl+A(它在ASCII碼中有意義,但是在Windows裏,就可能是一個鍵盤快捷鍵)。在一些鍵盤上,可能會有死字元鍵或者 Shift、Ctrl、Alt鍵與「A」鍵的組合。這種組合能產生帶重音符號的小寫字母或大寫字母,例如,à、á、â、Ä、或 Å等。

對產生可顯示字元的擊鍵組合,Windows在發送擊鍵訊息的同時還發送字元訊息。有些鍵不產生字元,如Shift鍵、功能鍵、光標移動鍵和特殊字元鍵(如Insert鍵和Delete鍵)。 對於這些鍵,Windows只產生擊鍵訊息。

本文摘自編程達人系列教材【Windows API每日一練】Windows程式設計基礎篇。