Хук клавиатуры С++

kick

Магистр Йода
Administrator
Сообщения
5.020
Розыгрыши
3
Реакции
3.577
Баллы
6.485
В первую очередь мы подключим нужные файлы и объявим функции, которые будем использовать в дальнейшем.
Код:
#include <windows.h>
#include <stdio.h>

BOOL InitInstance(HINSTANCE hInstance, int iCmdShow);
BOOL InitApplication(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
Далее мы опишем функции
Код:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;

    if (!InitApplication(hInstance))
        return FALSE;

    if (!InitInstance(hInstance, nCmdShow))
        return FALSE;

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

BOOL InitApplication(HINSTANCE hInstance)
{
    WNDCLASS wnd;

    wnd.style = NULL;
    wnd.lpfnWndProc = WndProc;
    wnd.hInstance = hInstance;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hIcon = 0;
    wnd.hCursor = 0;
    wnd.lpszMenuName = NULL;
    wnd.hbrBackground = 0;
    wnd.lpszClassName = "LayoutSwitcher";

    return RegisterClass(&wnd);
}

BOOL InitInstance(HINSTANCE hInstance, int iCmdShow) {
    HWND hwnd;
    hwnd = CreateWindow(
        "LayoutSwitcher",           // name of window class
        "LayoutSwitcher base",          // title-bar string
        0,                  // top-level window
        0,                  // default horizontal position
        0,                  // default vertical position
        0,                  // default width
        0,                  // default height
        0,                  // no owner window
        0,                  // use class menu
        hInstance,          // handle to application instance
        LPVOID(NULL));

    if (!hwnd) return FALSE;

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CREATE: {
        HOOKPROC hHook = KeyboardProc;
        HINSTANCE hMdl = ::GetModuleHandle("LayoutSwitcher.exe");

        if (!SetWindowsHookExA(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc, hMdl, 0))
        {
            CHAR szBuf[80];
            DWORD dw = GetLastError();
            sprintf(szBuf, "failed: GetLastError returned %u\n", dw);
            MessageBox(NULL, szBuf, "Error", MB_OK);
        }
    }
    default: return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return 0;
}
А теперь сама действующая функция:

Код:
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    HHOOK hkb = 0;
    if (nCode < 0)
        return CallNextHookEx(hkb, nCode, wParam, lParam);

    char ch;
    if (HC_ACTION == nCode)
    {
        if (wParam == WM_KEYDOWN)
        {
            KBDLLHOOKSTRUCT * p = (KBDLLHOOKSTRUCT*)lParam;
    
        }
    }
    return CallNextHookEx(hkb, nCode, wParam, lParam);
}
В переменной р, содержится информация о нажатой клавише, получить ее можно с помощью обращения к полю p->vkCode, хочу обратить Ваше внимание, что внутри хранится не значение нажатой клавиши, а только ее код, следственно по коду нужно самостоятельно определять символ. Системные клавиши (которые не вводят символов, например BackSpace или Enter) можно определить, воспользовавшись встроенными определениями, таких как VK_BACK и Vk_EXECUTE соответственно.
 
Сверху Снизу