On Win32, how to detect whether a Left Shift or Ri

2020-07-30 06:50发布

问题:

On Win32, I wonder how to detect whether Left Shift or Right ALT is pressed using Perl, Python, or Ruby (or even in C)?

Not just for the current window, but the global environment overall. Example: when I am typing a document, I can press Right ALT to start the music player written in Ruby, and then press Right ALT again and it can pause or stop the program. thanks.

回答1:

You need to setup a Low Level Keyboard Hook. You do this by calling SetWindowsHookEx with a LowLevelKeyboardProc, and then watch for the appropriate virtual key code.

There are key codes for left and right shift and alt keys.



回答2:

I believe you can also get at the status of a virtual key through GetKeyState e.g. GetKeyState(VK_RSHIFT). Though using a hook as described by Reed Copsey is probably better suited to your purposes rather than polling this function.



回答3:

If you want to know the current state of the keys right now, you can use GetAsyncKeyState() with an argument of VK_LSHIFT or VK_RMENU for left shift and right alt respectively. Make sure to test the most significant bit of the result, since the result contains more than one bit of information, e.g.

if(GetAsyncKeyState(VK_LSHIFT) & 0x8000)
    ; // left shift is currently down

If you instead want to be notified of keypresses instead of polling them asynchronously, you should listen for the WM_KEYDOWN window notification. Put something like this in your window's message handler:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg)
    {
    ...
    case WM_KEYDOWN:
        if(wparam == VK_LSHIFT)
            ; // left shift was pressed
        // etc.
        break;
    }
}

You'll also have to handle the WM_KEYUP message to know when keys are released.



回答4:

Instead of WM_KEYDOWN and WM_KEYUP, use WM_SYSKEYDOWN and WM_SYSKEYUP; then you can check if it's VK_LSHIFT or VK_MENU etc and it will catch those events as they occur.