views:

172

answers:

3

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.

+3  A: 

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.

Reed Copsey
This is mentioned in the link you cite, but a good thing to remember: The system imposes a time-out for these callbacks, so it's good not to do too much computation in them.
asveikau
Yes. If you need to do long running work, you should queue it for processing in another thread, and not do it in the hook itself.
Reed Copsey
A: 

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.

Beetny
A: 

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.

Adam Rosenfield