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.
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.
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.
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.
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.