1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
Скрыть объявление

Привет посетитель! У нас на форуме тебе откроются дополнительные разделы, которые скрыты от гостей! А так же ты найдёшь много полезной информации.

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

Тема в разделе "C++ / C# / .NET", создана пользователем kick, 4 апр 2017.

  1. kick

    kick Магистр Йода Администратор

    Регистрация:
    20 янв 2015
    Сообщения:
    4.918
    Симпатии:
    3.483
    Баллы:
    6.235
    В первую очередь мы подключим нужные файлы и объявим функции, которые будем использовать в дальнейшем.
    Код:
    #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 соответственно.
     
    gvb нравится это.