使用WinAPI C ++的键盘钩子

时间:2016-10-12 04:57:42

标签: c++ windows keyboard-hook

我正在尝试创建一个全局键盘钩子,用于读取我正在创建的热键程序的击键,并且我遇到了一些问题。当用户输入关键词时,我需要显示消息框(例如"密码")。我怎么能在这段代码中做到这一点?

#include <fstream>
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>

using namespace std;

bool isCapsLockOn() {

   if ((GetKeyState(VK_CAPITAL) & 0x00001) != 0) 
      return true;
   else
      return false; 
}

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;

if (wParam == WM_KEYDOWN) {

    if (p->vkCode >= 0x30 && p->vkCode <= 0x39) // 0~9
    {
        switch (p->vkCode) {
            // 0 ~ 9 with Shift Options.
        case 0x30: if (GetAsyncKeyState(VK_SHIFT)) cout << ')';     else cout << '0';        break;
        case 0x31: if (GetAsyncKeyState(VK_SHIFT)) cout << '!';     else cout << '1';        break;
        case 0x32: if (GetAsyncKeyState(VK_SHIFT)) cout << '@';     else cout << '2';        break;
        case 0x33: if (GetAsyncKeyState(VK_SHIFT)) cout << '#';     else cout << '3';        break;
        case 0x34: if (GetAsyncKeyState(VK_SHIFT)) cout << '$';     else cout << '4';        break;
        case 0x35: if (GetAsyncKeyState(VK_SHIFT)) cout << '%';     else cout << '5';        break;
        case 0x36: if (GetAsyncKeyState(VK_SHIFT)) cout << '^';     else cout << '6';        break;
        case 0x37: if (GetAsyncKeyState(VK_SHIFT)) cout << '&';     else cout << '7';        break;
        case 0x38: if (GetAsyncKeyState(VK_SHIFT)) cout << '*';     else cout << '8';        break;
        case 0x39: if (GetAsyncKeyState(VK_SHIFT)) cout << '(';     else cout << '9';        break;
        }
    }

    else if (p->vkCode >= 0x41 && p->vkCode <= 0x5A) // a~z
    {

        if (!(GetAsyncKeyState(VK_SHIFT) ^ isCapsLockOn())) {
            cout << char(tolower(p->vkCode));

        }
        else

            cout << (char)p->vkCode;

    }

    else if (p->vkCode >= 0x70 && p->vkCode <= 0x7B) // F1 ~ F12.
    {
        cout << "[F" << p->vkCode - 111 << "]";
    }
    else if (p->vkCode >= 0x70 && p->vkCode <= 0x7B) // F1 ~ F12.
    {
        cout << "[F" << p->vkCode - 111 << "]";
    }

    else if (p->vkCode)

    {
        switch (p->vkCode)
        {
        case VK_CAPITAL:    cout << "<CAPLOCK>";        break;
        case VK_LCONTROL:   cout << "<LCTRL>";      break;
        case VK_RCONTROL:   cout << "<RCTRL>";      break;
        case VK_INSERT:     cout << "<INSERT>";     break;
        case VK_END:        cout << "<END>";            break;
        case VK_PRINT:      cout << "<PRINT>";      break;
        case VK_DELETE:     cout << "<DEL>";            break; 
        case VK_BACK:       cout << "<BK>";         break;
        case VK_LEFT:       cout << "<LEFT>";       break;
        case VK_RIGHT:      cout << "<RIGHT>";      break;
        case VK_UP:         cout << "<UP>";         break;
        case VK_DOWN:       cout << "<DOWN>";       break;
        case VK_SPACE:      cout << ' ';                break;
        case VK_ESCAPE:     cout << "<ESC>";            break;
        case VK_TAB:        cout << "<TAB>";            break;

        }
    }

}


return CallNextHookEx(NULL, nCode, wParam, lParam);
}

  int main()
{

HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
MSG msg;
while (!GetMessage(&msg, NULL, NULL, NULL)) {    
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

UnhookWindowsHookEx(keyBoard);
}

1 个答案:

答案 0 :(得分:0)

if (!(GetAsyncKeyState(VK_SHIFT) ^ isCapsLockOn()))

在C ++中,^表示按位异或操作

对于逻辑OR,您可能意味着||

要记录字符串,可以使用std::string声明字符串。添加字符,然后在用户点击Return键时显示。您必须为VK_RETURN添加处理程序,如下例所示。

如果不需要#include "stdafx.h",请不要包含它。 #include <stdio.h>是IO的C头,这里不需要,你已经有了C ++头文件<iostream>

#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>

...
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    static std::string str;
    if (wParam == WM_KEYDOWN) 
    {
        ...
        else if (p->vkCode >= 0x41 && p->vkCode <= 0x5A) // a~z
        {
            char c = char(p->vkCode);
            if (!(GetAsyncKeyState(VK_SHIFT) || isCapsLockOn()))
                c = (char)tolower(c);
            cout << c;
            str += c;
        }
        ...    
        else if (p->vkCode)
        {
            switch (p->vkCode)
            {
            ...
            case VK_UP:         cout << "<UP>";         break;
            case VK_DOWN:       cout << "<DOWN>";       break; 
            case VK_SPACE:      cout << ' ';            break;
            case VK_ESCAPE:     cout << "<ESC>";        break;
            case VK_TAB:        cout << "<TAB>";        break;
            case VK_RETURN:     
            {
                cout << "<RETURN>\n";
                if (str.length())
                {
                    std::string msg = str;
                    str = "";
                    ::MessageBoxA(0, msg.c_str(), 0, 0);
                }
                break;
            }
            ...
        }
    }
}