快速鍵資料表
應用程式通常會定義鍵盤快速鍵,例如 [檔案開啟] 命令的 CTRL+O。 您可以藉由處理個別 WM_KEYDOWN 訊息來實作鍵盤快速鍵,但快速鍵資料表可提供更好的解決方案:
- 需要較少的程式碼撰寫。
- 將所有快捷方式合併成一個資料檔案。
- 支援將當地語系化為其他語言。
- 可讓快捷方式和功能表命令使用相同的應用程式邏輯。
快速鍵資料表是一種資料資源,會將鍵盤組合,例如 CTRL+O 對應至應用程式命令。 在看到如何使用快速鍵資料表之前,我們需要資源的快速簡介。 資源是內建在應用程式二進位 (EXE 或 DLL) 中的資料 Blob。 資源會儲存應用程式所需的資料,例如功能表、游標、圖示、影像、文字字串或任何自訂應用程式資料。 應用程式會在執行時間從二進位檔載入資源資料。 若要在二進位檔中包含資源,請執行下列動作:
- 建立資源定義 (.rc) 檔案。 此檔案會定義資源類型和其識別碼。 資源定義檔可能包含其他檔案的參考。 例如,圖示資源會在 .rc 檔案中宣告,但圖示影像會儲存在不同的檔案中。
- 使用 Microsoft Windows 資源編譯器 (RC) ,將資源定義檔編譯成編譯的資源 (.res) 檔案。 RC 編譯器隨附于 Visual Studio 和 Windows SDK。
- 將編譯的資源檔連結至二進位檔案。
這些步驟大致相當於程式碼檔案的編譯/連結程式。 Visual Studio 提供一組資源編輯器,可讓您輕鬆地建立和修改資源。 (Visual Studio.) Express 版本中無法使用這些工具,但 .rc 檔案只是文字檔,而且語法記載于 MSDN 上,因此可以使用任何文字編輯器建立 .rc 檔案。 如需詳細資訊,請參閱 關於資源檔。
定義快速鍵資料表
快速鍵表格是鍵盤快速鍵的表格。 每個快捷方式都是由下列方式定義:
- 數值識別碼。 這個數位會識別快捷方式將叫用的應用程式命令。
- 快捷方式的 ASCII 字元或虛擬按鍵碼。
- 選擇性修飾詞鍵:ALT、SHIFT 或 CTRL。
快速鍵資料表本身具有數值識別碼,可識別應用程式資源清單中的資料表。 讓我們為簡單的繪圖程式建立快捷表。 此程式會有兩種模式:繪製模式和選取模式。 在繪製模式中,使用者可以繪製圖形。 在選取模式中,使用者可以選取圖形。 針對此程式,我們想要定義下列鍵盤快速鍵。
快速鍵 | 命令 |
---|---|
CTRL+M | 在模式之間切換。 |
F1 | 切換至繪製模式。 |
F2 | 切換至選取模式。 |
首先,為數據表和應用程式命令定義數值識別碼。 這些值是任意的。 您可以在標頭檔中定義識別碼的符號常數。 例如:
#define IDR_ACCEL1 101
#define ID_TOGGLE_MODE 40002
#define ID_DRAW_MODE 40003
#define ID_SELECT_MODE 40004
在此範例中,值 IDR_ACCEL1
會識別快速鍵資料表,而接下來的三個常數會定義應用程式命令。 根據慣例,定義資源常數的標頭檔通常命名為 resource.h。 下一個清單會顯示資源定義檔。
#include "resource.h"
IDR_ACCEL1 ACCELERATORS
{
0x4D, ID_TOGGLE_MODE, VIRTKEY, CONTROL // ctrl-M
0x70, ID_DRAW_MODE, VIRTKEY // F1
0x71, ID_SELECT_MODE, VIRTKEY // F2
}
快速鍵會在大括弧內定義。 每個快捷方式都包含下列專案。
- 叫用快捷方式的虛擬機器碼或 ASCII 字元。
- 應用程式命令。 請注意,範例中會使用符號常數。 資源定義檔包含 resource.h,其中定義了這些常數。
- 關鍵字 VIRTKEY 表示第一個專案是虛擬金鑰程式碼。 另一個選項是使用 ASCII 字元。
- 選擇性修飾詞:ALT、CONTROL 或 SHIFT。
如果您使用 ASCII 字元做為快捷方式,小寫字元會與大寫字元不同。 (例如,輸入 'a' 可能會叫用與輸入 'A'.) 不同的命令,這可能會混淆使用者,因此通常最好是針對快捷方式使用虛擬機器碼代碼,而不是 ASCII 字元。
載入快速鍵資料表
必須先載入快速鍵資料表的資源,程式才能使用它。 若要載入快速鍵資料表,請呼叫 LoadAccelerators 函式 。
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCEL1));
輸入訊息迴圈之前,請先呼叫此函式。 第一個參數是模組的控制碼。 (此參數會傳遞至 您的 WinMain 函式。如需詳細資訊,請參閱 WinMain:應用程式進入點.) 第二個參數是資源識別碼。 函式會傳回資源的控制碼。 回想一下,控制碼是參照系統所管理物件的不透明類型。 如果函式失敗,它會傳回 Null。
您可以呼叫 DestroyAcceleratorTable來釋放快速鍵資料表。 不過,當程式結束時,系統會自動釋放資料表,因此當您將一個資料表取代為另一個資料表時,只需要呼叫此函式。 在 建立使用者可編輯加速器主題中,有一個有趣的範例。
將按鍵筆劃轉譯成命令
快速鍵資料表的運作方式是將按鍵筆劃轉譯成 WM_COMMAND 訊息。
WM_COMMAND的wParam參數包含命令的數值識別碼。 例如,使用先前顯示的資料表,按鍵筆劃 CTRL+M 會轉譯成 具有 值的 ID_TOGGLE_MODE
WM_COMMAND訊息。 若要這樣做,請將您的訊息迴圈變更為下列各項:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(win.Window(), hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
此程式碼會在訊息迴圈內新增 TranslateAccelerator 函式的呼叫。 TranslateAccelerator 函式會檢查每個視窗訊息,並尋找向下鍵訊息。 如果使用者按下快速鍵資料表中列出的其中一個按鍵組合, TranslateAccelerator 會將 WM_COMMAND 訊息傳送至視窗。 函式會直接叫用視窗程式來傳送 WM_COMMAND 。 當 TranslateAccelerator成功轉譯按鍵筆劃時,函式會傳回非零值,這表示您應該略過訊息的正常處理。 否則, TranslateAccelerator 會傳回零。 在此情況下,請如常將視窗訊息傳遞至 TranslateMessage 和 DispatchMessage。
以下是繪圖程式如何處理 WM_COMMAND 訊息:
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_DRAW_MODE:
SetMode(DrawMode);
break;
case ID_SELECT_MODE:
SetMode(SelectMode);
break;
case ID_TOGGLE_MODE:
if (mode == DrawMode)
{
SetMode(SelectMode);
}
else
{
SetMode(DrawMode);
}
break;
}
return 0;
此程式碼假設 SetMode
是應用程式所定義的函式,以在兩種模式之間切換。 您處理每個命令的詳細資料顯然取決於您的程式。
下一個