快速鍵資料表

應用程式通常會定義鍵盤快速鍵,例如 [檔案開啟] 命令的 CTRL+O。 您可以藉由處理個別 WM_KEYDOWN 訊息來實作鍵盤快速鍵,但快速鍵資料表可提供更好的解決方案:

  • 需要較少的程式碼撰寫。
  • 將所有快捷方式合併成一個資料檔案。
  • 支援將當地語系化為其他語言。
  • 可讓快捷方式和功能表命令使用相同的應用程式邏輯。

快速鍵資料表是一種資料資源,會將鍵盤組合,例如 CTRL+O 對應至應用程式命令。 在看到如何使用快速鍵資料表之前,我們需要資源的快速簡介。 資源是內建在應用程式二進位 (EXE 或 DLL) 中的資料 Blob。 資源會儲存應用程式所需的資料,例如功能表、游標、圖示、影像、文字字串或任何自訂應用程式資料。 應用程式會在執行時間從二進位檔載入資源資料。 若要在二進位檔中包含資源,請執行下列動作:

  1. 建立資源定義 (.rc) 檔案。 此檔案會定義資源類型和其識別碼。 資源定義檔可能包含其他檔案的參考。 例如,圖示資源會在 .rc 檔案中宣告,但圖示影像會儲存在不同的檔案中。
  2. 使用 Microsoft Windows 資源編譯器 (RC) ,將資源定義檔編譯成編譯的資源 (.res) 檔案。 RC 編譯器隨附于 Visual Studio 和 Windows SDK。
  3. 將編譯的資源檔連結至二進位檔案。

這些步驟大致相當於程式碼檔案的編譯/連結程式。 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_COMMANDwParam參數包含命令的數值識別碼。 例如,使用先前顯示的資料表,按鍵筆劃 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 會傳回零。 在此情況下,請如常將視窗訊息傳遞至 TranslateMessageDispatchMessage

以下是繪圖程式如何處理 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 是應用程式所定義的函式,以在兩種模式之間切換。 您處理每個命令的詳細資料顯然取決於您的程式。

下一個

設定游標影像