keybd_event 使用方法

Windows 提供了一個模擬鍵盤 API 函數 Keybd_event(),使用該函數可以相應的屏蔽鍵盤的動作。Keybd_event()函數能觸發一個按鍵事件,也就是說會產生一個 WM_KEYDOWN 或 WM_KEYUP 消息。

 

該函數原型如下:

VOID keybd_event(
  BYTE bVk, // virtual-key code
  BYTE bScan, // hardware scan code
  DWORD dwFlags, // flags specifying various function options
  DWORD dwExtraInfo // additional data associated with keystroke
  );

  從原型可以看出,Keybd_event()共有四個參數:

      第一個爲按鍵的虛擬鍵值,如回車鍵爲 vk_return, tab 鍵爲 vk_tab(其他具體的參見附錄:常用模擬鍵的鍵值對照表);

      第二個參數爲掃描碼,一般不用設置,用 0 代替就行;

      第三個參數爲選項標誌,如果爲 keydown 則置 0 即可,如果爲 keyup 則設成

"KEYEVENTF_KEYUP";

      第四個參數一般也是置 0 即可。

 

例子 1:模擬按下 'A' 鍵
  

keybd_event(65,0,0,0);
keybd_event(65,0,KEYEVENTF_KEYUP,0);

例子 2:模擬按下 'ALT+F4' 鍵

keybd_event(18,0,0,0);
keybd_event(115,0,0,0);
keybd_event(115,0,KEYEVENTF_KEYUP,0);
keybd_event(18,0,KEYEVENTF_KEYUP,0);

附:常用模擬鍵的鍵值對照表(也可參考https://docs.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes

                                                         鍵盤鍵與虛擬鍵碼對照表

      字母和數字鍵      數字小鍵盤的鍵            功能鍵                   其它鍵 
      鍵   鍵碼    鍵   鍵碼    鍵   鍵碼     鍵    鍵碼 
      A   65     0   96     F1   112   Backspace    8 
      B   66     1   97     F2   113   Tab       9 
      C   67     2   98       F3   114    Clear      12 
      D   68     3   99     F4   115    Enter      13 
      E   69     4   100      F5   116    Shift      16 
      F   70     5   101    F6   117    Control     17 
      G   71     6   102      F7   118   Alt       18 
      H   72     7   103      F8   119   Caps Lock    20 
      I   73    8   104    F9   120  Esc       27 
      J   74    9   105      F10  121    Spacebar    32 
      K   75    *   106     F11  122  Page Up     33 
      L   76    +   107     F12  123  Page Down    34 
      M   77    Enter 108    --   --    End       35 
      N   78    -   109    --   --    Home      36 
      O   79    .   110    --   --     Left Arrow   37 
      P   80    /   111    --   --     Up Arrow    38 
      Q   81    --   --     --   --     Right Arrow   39 
      R   82    --   --    --   --      Down Arrow    40 
      S   83    --   --     --   --     Insert      45 
      T   84    --   --     --   --     Delete      46 
      U   85    --   --     --   --     Help       47 
      V   86    --   --    --   --     Num Lock     144 
      W   87          
      X   88      
      Y   89      
      Z   90      
      0   48      
      1   49      
      2   50       
      3   51       
      4   52       
      5   53       
      6   54       
      7   55       
      8   56       
      9   57  

模擬鍵盤平時不是很常用,但是當調用某些快捷鍵執行某項功能時,它真的是那麼的方便呀.  你不信?  看看下面的實現,你就會大呼:爲什麼不早點告訴我?  呵呵,  原來沒有 blog 呀,  都靠這些掙分呢.

1) 顯示桌面:

         很多軟件有顯示桌面的功能,並且大家的方法都是遍歷窗口,  然後讓它們最小化,其實 win 系統給咱們了一個非常方便的 WIN 鍵 (就是鍵盤上在 CTRL 鍵和 ALT 鍵之間的那個帶 win 標誌的按鍵), 利用它,可以輕鬆的完成顯示桌面的功能.

keybd_event(VK_LWIN, 0, 0 ,0);
keybd_event('M', 0, 0 ,0);
keybd_event('M', 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

其他的操作也類似,比如直接顯示開始的運行,就把上面的 'M' 換成 'R' 即可。

keybd_event (VK_LWIN, 0, 0 ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

直接顯示 “開始” 對話框了。

2) 實現快速的全選

        很多的時候,比如 listctrl 實現全選,你可以用 listctrl 循環設置每一項的狀態爲選中,多羅索的事情呀。用快捷鍵試一試 CTRL+A,其他的快捷鍵一樣的用法,呵呵,你知道怎麼辦了吧?

keybd_event(VK_CONTROL, (BYTE)0, 0 ,0);
keybd_event ('A',(BYTE) 0, 0 ,0); // 此處可以用  'A', (BYTE) 65, 用 'a' 不起作用.
keybd_event('A', (BYTE)0, KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL, (BYTE)0, KEYEVENTF_KEYUP,0);

3) 執行某些特殊的鍵,比如數字鍵,大小寫,下面是數字鍵的例子

bool bState=true;   //true 爲按下 NumLock,false 反之
BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_NUMLOCK] & 1)) || (!bState && (keyState[VK_NUMLOCK] & 1)) )
{
    // Simulate a key press
    keybd_event( VK_NUMLOCK,0x45,KEYEVENTF_EXTENDEDKEY | 0,0 );
        
    // Simulate a key release
    keybd_event( VK_NUMLOCK,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
}

4) 你想 CTRL+ALT+DELETE 三鍵一起按下,    

keybd_event(VK_CONTROL, 0, 0 ,0);
keybd_event(VK_MENU,0, 0 ,0);
keybd_event(VK_DELETE,0, 0 ,0);

keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_MENU,0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_DELETE,0, KEYEVENTF_KEYUP ,0);

呵呵,這樣不會成功呀,因爲這幾個鍵直接是操作系統來截獲執行的,而模擬鍵盤只能發向應用程序,所以這種方法不行的(想顯示鎖定對話框,用    LockWorkStation ();)

5) Window2000/NT/XP 已經不提倡用這個函數了,上面的方法只是爲了讓大家開闊一下思路,怎麼替代呢,呵呵,看下面,所以上面的所有代碼都可以用這個來完成  

//2000 下用這個代替,包含 "winable.h"
INPUT input[4];
memset(input, 0, sizeof(input));
input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;
input[0].ki.wVk  = input[3].ki.wVk = VK_LWIN;
input[1].ki.wVk  = input[2].ki.wVk = 'R';

// 接下來釋放它,這一點很重要。
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
input[0].ki.time = input[1].ki.time = input[2].ki.time = input[3].ki.time = GetTickCount();
SendInput(4, input, sizeof(INPUT));

====================

附 WIN 鍵的部分快捷鍵:

WIN 鍵 + D = 快速的切到桌面,再次點擊返回

WIN 鍵 + E = 快速打開資源管理器

WIN 鍵 + R=“運行”。

WIN 鍵 + M = 全部視窗最小化。

WIN 鍵 + Shift+M = 取消全部視窗最小化。

WIN 鍵 + F1=Help。

WIN 鍵 + F=“尋找”。

WIN 鍵 + Ctrl+F = 顯示 “查找電腦”。

WIN 鍵 + Tab = 切換工作列的程式。

WIN 鍵 + Break = 顯示系統內容。

******************************************************************************************

                          關於 SendMessage keybd_event  PostMessage

******************************************************************************************

首先你會發現 keybd_event 函數中是沒有窗口句柄作爲參數的,好奇的你一定會覺得很奇怪,那是因爲,keybd_event 是全局模擬按鍵的,只對前臺窗口(即當前的活動窗口)纔可以,但是如果模擬的按鍵正好也是某個窗口的全局熱鍵消息,那該窗口也能接收到的

  而 SendMessage 、PostMessage 是對指定句柄窗口都其作用的,對於做一些一外掛是非常有用的。例如可以做成這樣的效果:即用 SendMessage/PostMessage 在某一個窗口模擬動作,而同時自己可以在其他窗口做其他事情,互不影響的!

  但是有一點要注意,很多人在模擬鍵盤消息的時候,都會忘記模擬 WM_KEYUP 的消息。。。

  還有一點就是,PostMessage 中的窗口句柄參數,可以設置爲 HWND_BROADCAST,即廣播,但不要理所當然地認爲是對所有的窗口都起作用!!!它只對系統的頂層窗口起作用,子窗口是收不到這個消息的!!!

  還要注意的是 SendMessage 是沒有 HWND_BROADCAST 參數的,那是因爲,SendMessage 總是等發送的消息在對應的窗口消息隊列中處理完畢後才返回的(這是一種負責的行爲), 細想一下就知道爲什麼 SendMessage 沒有 HWND_BROADCAST 參數了!!

 

個人認爲

  1. 當需要模擬鍵盤輸入命令時,比如 Ctrl + V,選擇 keybd_event;

  2. 當需要模擬鍵盤輸入一串字符時,選擇 PostKeybdMessage;

  3. 當需要模擬鍵盤輸入單個字符時,選擇 keybd_event。

 

SendMessage(Button.Handle,WM_LBUTTONDOWN,0,0);  鼠標左鍵按下 
SendMessage(Button.Handle,WM_LBUTTONUP,0,0);   鼠標左鍵擡起
SendMessage(Edit.Handle,WM_SETTEXT,255,Integer(PChar('abc'))); 傳遞文本
SendMessage(Edit.Handle,WM_Char,Wparam('Q'),2);  傳遞字符
SendMessage(Button.Handle,BM_SETSTYLE,BS_RADIOBUTTON,1);  改變 Button 風格
SendMessage(ComboBox.Handle,CB_SETDROPPEDWIDTH,300,0);  改變 CBDownWidth
WM_CUT、WM_COPY 和 WM_PASTE  剪切,複製,粘帖 
實現任意組合鍵
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0);
keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), 0, 0);
keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), KEYEVENTF_KEYUP, 0); 
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);
模擬鼠標按下事件
::PostMessage(hwd0,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(x,y));
::PostMessage(hwd0,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(x,y));
::PostMessage(hwd0,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(x,y));
模擬鍵盤按下事件
keybd_event(VK_TAB,0,0,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章