Windows 編程[23] – 快速鍵資源

來源:互聯網
上載者:User
提示:

1、因為加入快速鍵, 本例的基礎代碼和以前不同了; 因為表單初始化時要先載入快速鍵資源, 還要攔截快速鍵訊息另作處理.

2、關於快速鍵的話題, 以前接觸過不少了, 但那些都不是本質:
    註冊系統級熱鍵
    所有可選的快速鍵列表
    快速鍵設定控制項
    快速鍵的記錄方式

3、我曾經以為快速鍵不過就是攔截鍵盤訊息, 現在看來那是想得太簡單了; 很容易就可以說明: 鍵盤訊息是需要焦點的, 而快速鍵是只對主視窗.

4、使用快速鍵前應該先建立一個快速鍵表或建立快速鍵資源, 本例使用了後者.
快速鍵一般是執行菜單的功能, 那它是怎麼和菜單掛接的呢? 很簡單: 給每一項快速鍵和每一個功能表項目指定相同的標識即可!

5、在本例中, 視窗建立後, 先用 LoadAccelerators 載入快速鍵資源並返回快速鍵資源控制代碼 hAcc;
GetMessage 從訊息佇列中取出訊息後, 先用 TranslateAccelerator 檢查是否是快速鍵訊息. 如果是, TranslateAccelerator 會把此快速鍵訊息轉換成菜單訊息(WM_COMMAND, 也可能是系統功能表訊息: WM_SYSCOMMAND), 然後直接發送給視窗; 如果不是, 再繼續以前的訊息傳遞.
其實快速鍵訊息的本質也是鍵盤訊息, 不過 TranslateAccelerator 會檢查鍵盤訊息的組合是否是我們定義的快速鍵. 但我們在執行快速鍵時, 焦點未必就在主視窗, 它是怎麼吧其他視窗的鍵盤訊息轉給主視窗的呢?
如果 GetMessage 函數的第二個參數為 0 時, 它會檢索程式中所有視窗的訊息, TranslateAccelerator 接過來後, 不管訊息來自那個視窗, 都把訊息包中的視窗控制代碼換成主視窗控制代碼再傳遞.

關於快速鍵資源檔還是解釋在資源檔下面吧...

本例:


本例使用的資源檔(TestRes.rc):

MyMenu1 MENUEXBEGIN  POPUP "菜單"  BEGIN    MENUITEM "菜單_1\t Shift+1"           ,101    MENUITEM "菜單_2\t Ctrl+2"            ,102    MENUITEM "菜單_3\t Alt+3"             ,103    MENUITEM "菜單_4\t Shift+Ctrl+Alt+4"  ,104    MENUITEM "菜單_5\t 5"                 ,105    MENUITEM "菜單_6\t F5"                ,106    MENUITEM "菜單_7\t Ctrl+A"            ,107    MENUITEM "菜單_8\t Alt+A"             ,108   ENDENDMyAccel ACCELERATORSBEGIN  "1",   101,  VIRTKEY, SHIFT,               NOINVERT  "2",   102,  VIRTKEY, CONTROL,             NOINVERT  "3",   103,  VIRTKEY, ALT,                 NOINVERT  "4",   104,  VIRTKEY, SHIFT, CONTROL, ALT, NOINVERT  "5",   105,  VIRTKEY, NOINVERT,            NOINVERT  VK_F5, 106,  VIRTKEY, NOINVERT,            NOINVERT  "A",   107,  VIRTKEY, CONTROL  "a",   108,  ASCII,   ALT END

注釋:

1、快速鍵資源檔關鍵字: ACCELERATORS, 需要取個名給程式中的 LoadAccelerators 使用, 這裡是: MyAccel.

2、快速鍵資源檔可以有五組參數, 從後面說: NOINVERT 是讓被啟用的菜單的頂層菜單不閃爍(但我去掉也沒看出來).
它前面是修飾鍵: SHIFT、CONTROL、ALT.
再前面有兩個選擇: VIRTKEY、ASCII, VIRTKEY 指示快速鍵要用 虛擬鍵碼 說明; ASCII 指示用 ASCII 碼說明快速鍵. 譬如例子中的 VK_F5 就是典型的虛擬鍵碼. 但常規數字鍵和字母鍵沒有對應的虛擬鍵碼, 對數字(非小鍵盤數字)來講, 這兩者沒有區別; 特別注意: VIRTKEY 時指示的字母須大寫、ASCII 指示的字母須小寫.

3、這其中最重要的就是第二個參數了, 它必須和菜單的標識相對應.

4、另外, 菜單資源也和以前有點區別: 在 \t (Tab 的意思) 後面用文本說明了對應的快速鍵, 不過這隻是顯示效果而已, 有沒有都不影響功能.

本例代碼檔案:
program Project1;{$R 'TestRes.res' 'TestRes.rc'}uses  Windows, Messages;{收到 WM_COMMAND 訊息時需要做的工作}procedure OnCommand(h: HWND; wParam: Integer);var  W: Word;  arr: array[Byte] of Char;begin  W := LoWord(wParam);  case W of    101..108: begin      GetMenuString(GetMenu(h), W, arr, Length(arr), MF_BYCOMMAND);      SetWindowText(h, arr);    end;  end;end;function WndProc(wnd: HWND; msg: UINT; wParam: Integer; lParam: Integer): Integer; stdcall;begin  Result := 0;  case msg of    WM_COMMAND : OnCommand(wnd, wParam); {收到 WM_COMMAND 訊息後調用 OnCommand 過程}    WM_DESTROY : PostQuitMessage(0);  else    Result := DefWindowProc(wnd, msg, wParam, lParam);  end;end;function RegMyWndClass: Boolean;var  cls: TWndClass;begin  cls.style         := CS_HREDRAW or CS_VREDRAW;  cls.lpfnWndProc   := @WndProc;  cls.cbClsExtra    := 0;  cls.cbWndExtra    := 0;  cls.hInstance     := HInstance;  cls.hIcon         := 0;  cls.hCursor       := LoadCursor(0, IDC_ARROW);  cls.hbrBackground := HBRUSH(COLOR_WINDOW + 1);  cls.lpszMenuName  := 'MyMenu1';  cls.lpszClassName := 'MyWnd';  Result := RegisterClass(cls)  0;end;{程式入口}const  tit = 'New Form';  ws = WS_OVERLAPPEDWINDOW;  x = 100; y = 100; w = 300; h = 180;var  hWnd: THandle;  Msg : TMsg;  hAcc: HACCEL; {定義快速鍵資源控制代碼}begin  RegMyWndClass;  hWnd := CreateWindow('MyWnd', tit, ws, x, y, w, h, 0, 0, HInstance, nil);  ShowWindow(hWnd, SW_SHOWNORMAL);  UpdateWindow(hWnd);  hAcc := LoadAccelerators(HInstance, 'MyAccel'); {載入快速鍵資源}  while(GetMessage(Msg, 0, 0, 0)) do  begin    if (TranslateAccelerator(hwnd, hAcc, Msg) = 0) then {攔截並處理快速鍵訊息}    begin      TranslateMessage(Msg);      DispatchMessage(Msg);    end;  end;end.
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.