Search code examples
c++winapivisual-c++keyboard-hook

Can't exit loops dynamically while using keyboard hook


I'm having some issues about exiting "while" loops while using keyboard hook. Here is my code:

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    PKBDLLHOOKSTRUCT key = (PKBDLLHOOKSTRUCT)lParam;
    if (wParam == WM_KEYDOWN && nCode == HC_ACTION)
    {

    }

    if (wParam == WM_KEYUP)
    {
        if (key->vkCode == VK_CAPITAL) {
            capslockState = GetKeyState(VK_CAPITAL) & 0x0001;
            myLoop(capslockState);
        }
    }
    return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
}

And here is my function:

int myLoop(int a) {
    while (a == 1) {
        for (i = 0; i < n; i++) {
            // do some stuff
        }
        if (a == 0) {
            break;
            return 0;
        } 
        else {
            i = 0;
        }
    }
}

I tried couple more ways to achieve my goal but I couldn't do it. My goal is: I want to open the program, doesn't matter if Caps Lock is on or off, if I hit Caps Lock, it'll start my loop and if I hit it again, it'll stop. I was, somehow, able to make it using lots of "while" loops and threads but it was using almost all my CPU power. How can I create a performance friendly, dynamic loop while using keyboard inputs? Thank you.


Solution

  • My goal is: I want to open the program, doesn't matter if Caps Lock is on or off, if I hit Caps Lock, it'll start my loop and if I hit it again, it'll stop.

    You can check the following code to see if it works.

    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(NULL, nCode,
                wParam, lParam);
    
        if (wParam == VK_CAPITAL) {
    
            if(hThread == NULL)
                hThread = CreateThread( NULL, 0, myLoop, NULL, 0, NULL); 
    
            if (capslockState)
                capslockState = 0;
            else
                capslockState = 1;
        }
    
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }
    
    DWORD WINAPI myLoop(LPVOID lpParam)
    {
        while (1) {
            for (UINT16 i = 0; (i < n && capslockState == 1); i++) {
                // do some stuff
            }
            Sleep(100);
        }
        return 0;
    }
    

    What I made main edits on your code:

    1. To make main thread can response to messages and keep your for loop, you need create a new thread(CreateThread) for running your for loop.
    2. Since you "doesn't matter if Caps Lock is on or off" so no need check if the capslock is on or off state.
    3. To check the which key is hit use wParam to compare with virtual-key code.
    4. Problems have pointed by others.

    More reference "Using Hooks"