要實現一個螢幕小鍵盤,需要監聽所有鍵盤事件,無論表單是否被啟用。因此需要一個全域的鉤子,也就是系統範圍的鉤子。
什麼是鉤子(Hook)
鉤子(Hook)是Windows提供的一種訊息處理機制平台,是指在程式正常運行中接受資訊之前預先啟動的函數,用來檢查和修改傳給該程式的資訊,(鉤子)實際上是一個處理訊息的程式段,通過系統調用,把它掛入系統。每當特定的訊息發出,在沒有到達目的視窗前,鉤子程式就先捕獲該訊息,亦即鉤子函數先得到控制權。這時鉤子函數即可以加工處理(改變)該訊息,也可以不作處理而繼續傳遞該訊息,還可以強制結束訊息的傳遞。注意:安裝鉤子函數將會影響系統的效能。監測“系統範圍事件”的系統鉤子特別明顯。因為系統在處理所有的相關事件時都將調用您的鉤子函數,這樣您的系統將會明顯的減慢。所以應謹慎使用,用完後立即卸載。還有,由於您可以預先截獲其它進程的訊息,所以一旦您的鉤子函數出了問題的話必將影響其它的進程。
鉤子的作用範圍
一共有兩種範圍(類型)的鉤子,局部的和遠端。局部鉤子僅鉤掛自己進程的事件。遠端鉤子還可以將鉤掛其它進程發生的事件。遠端鉤子又有兩種: 基於線程的鉤子將捕獲其它進程中某一特定線程的事件。簡言之,就是可以用來觀察其它進程中的某一特定線程將發生的事件。 系統範圍的鉤子將捕捉系統中所有進程將發生的事件訊息。
Hook 類型
Windows共有14種Hooks,每一種類型的Hook可以使應用程式能夠監視不同類型的系統訊息處理機制。下面描述所有可以利用的Hook類型的發生時機。詳細內容可以查閱MSDN,這裡只介紹我們將要用到的兩種類型的鉤子。
(1)WH_KEYBOARD_LL Hook
WH_KEYBOARD_LL Hook監視輸入到線程訊息佇列中的鍵盤訊息。
(2)WH_MOUSE_LL Hook
WH_MOUSE_LL Hook監視輸入到線程訊息佇列中的滑鼠訊息。
使用完鉤子後,要進行卸載,這個可以寫在解構函式中。
下面是鍵盤上面的按鍵對應的虛擬鍵碼錶:
VK_F1 = 0x70;
VK_F2 = 0x71;
VK_F3 = 0x72;
VK_F4 = 0x73;
VK_F5 = 0x74;
VK_F6 = 0x75;
VK_F7 = 0x76;
VK_F8 = 0x77;
VK_F9 = 0x78;
VK_F10 = 0x79;
VK_F11 = 0x7A;
VK_F12 = 0x7B;
VK_LEFT = 0x25;
VK_UP = 0x26;
VK_RIGHT = 0x27;
VK_DOWN = 0x28;
VK_NONE = 0x00;
VK_ESCAPE = 0x1B;
VK_EXECUTE = 0x2B;
VK_CANCEL = 0x03;
VK_RETURN = 0x0D;
VK_ACCEPT = 0x1E;
VK_BACK = 0x08;
VK_TAB = 0x09;
VK_DELETE = 0x2E;
VK_CAPITAL = 0x14;
VK_NUMLOCK = 0x90;
VK_SPACE = 0x20;
VK_DECIMAL = 0x6E;
VK_SUBTRACT = 0x6D;
VK_ADD = 0x6B;
VK_DIVIDE = 0x6F;
VK_MULTIPLY = 0x6A;
VK_INSERT = 0x2D;
VK_OEM_1 = 0xBA; // ';:' for US
VK_OEM_PLUS = 0xBB; // '+'
VK_OEM_MINUS = 0xBD; // '-'
VK_OEM_2 = 0xBF; // '/?' for US
VK_OEM_3 = 0xC0; // '`~' for US
VK_OEM_4 = 0xDB; // '[{' for US
VK_OEM_5 = 0xDC; // '\|' for US
VK_OEM_6 = 0xDD; // ']}' for US
VK_OEM_7 = 0xDE; // ''"' for US
VK_OEM_PERIOD = 0xBE; // '.>'
VK_OEM_COMMA = 0xBC; // ',<'
VK_SHIFT = 0x10;
VK_CONTROL = 0x11;
VK_MENU = 0x12;
VK_LWIN = 0x5B;
VK_RWIN = 0x5C;
VK_APPS = 0x5D;
VK_LSHIFT = 0xA0;
VK_RSHIFT = 0xA1;
VK_LCONTROL = 0xA2;
VK_RCONTROL = 0xA3;
VK_LMENU = 0xA4;
VK_RMENU = 0xA5;
VK_SNAPSHOT = 0x2C;
VK_SCROLL = 0x91;
VK_PAUSE = 0x13;
VK_HOME = 0x24;
VK_NEXT = 0x22;
VK_PRIOR = 0x21;
VK_END = 0x23;
VK_NUMPAD0 = 0x60;
VK_NUMPAD1 = 0x61;
VK_NUMPAD2 = 0x62;
VK_NUMPAD3 = 0x63;
VK_NUMPAD4 = 0x64;
VK_NUMPAD5 = 0x65;
VK_NUMPAD5NOTHING = 0x0C;
VK_NUMPAD6 = 0x66;
VK_NUMPAD7 = 0x67;
VK_NUMPAD8 = 0x68;
VK_NUMPAD9 = 0x69;
KEYEVENTF_EXTENDEDKEY = 0x0001;
KEYEVENTF_KEYUP = 0x0002;