nonopolarity
nonopolarity

Reputation: 151126

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

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.

Upvotes: 3

Views: 6958

Answers (5)

Gru
Gru

Reputation: 490

Events for VK_LSHIFT are not dispatched. Instead, both are dispatched through VK_SHIFT. VK_LSHIFT and left/right-specific others are only good for GetKeyState Also, using WM_SYSKEYDOWN instead of WM_KEYDOWN will make no difference in this case.

switch(msg)
    {
    ...
    case WM_KEYDOWN:
      if(wparam == VK_LSHIFT) {
         bool isLeftShift = (GetKeyState(VK_LSHIFT) < 0);
      }

Upvotes: 1

pete
pete

Reputation: 2046

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.

Upvotes: 1

Adam Rosenfield
Adam Rosenfield

Reputation: 400464

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.

Upvotes: 1

Beetny
Beetny

Reputation: 417

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.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564641

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.

Upvotes: 5

Related Questions