Reputation: 51
I've been searching for a way to identify the status of the CAPS LOCK in Python 3 and the only thing I've found applicable was a post here in Stack Overflow answered by Abhijit stating:
You can use ctypes to load user32.dll and then call GetKeyState with nVirtKey = VK_CAPITAL (0x14)
def get_capslock_state(): import ctypes hllDll = ctypes.WinDLL ("User32.dll") VK_CAPITAL = 0x14 return hllDll.GetKeyState(VK_CAPITAL)
I've applied this to my script, but the value returned is not the anticipated 1/0, but a long 9 number sequence which never repeats. I'm not certain how to use this value to return the 1/0, T/F, or any true value to test against.
Any ideas, either based on Abhijit's comment or another method that works in Python 3? Your help is greatly appreciated, as this is driving me nuts.
Upvotes: 1
Views: 4800
Reputation: 6780
I'll throw my hat in the ring - here's an answer I found that works under Windows
import win32api
import win32con
def is_caps_lock_on() -> bool:
return bool(win32api.GetKeyState(win32con.VK_CAPITAL) & 1)
import ctypes
def is_caps_lock_on() -> bool:
VK_CAPITAL = 0x14
return bool(ctypes.windll.user32.GetKeyState(VK_CAPITAL) & 1)
These two solutions are essentially identical, but the ctypes
version leverages the standard library.
In my testing, the call to GetKeyState(VK_CAPITAL)
would return decimal -127
(0xFFFF_FFFF_FFFF_FF81
) when caps-lock was ON, and decimal -128
(0xFFFF_FFFF_FFFF_FF80
) when caps-lock was OFF
Masking this value with & 1
effectively strips off all the bits we don't care about and leaves us with either decimal 1
or 0
; passing this to bool
gives us a simple True
or False
.
Note that it's not strictly necessary to use bool
here since you can just as easily check truthiness against 1
or 0
, but returning a Boolean is probably more "Pythonic".
Upvotes: 0
Reputation: 208
Here is the minimal working answer, which I built upon the answer of danjmwalker
import ctypes
def is_capslock_on():
return True if ctypes.WinDLL("User32.dll").GetKeyState(0x14) else False
print(is_capslock_on())
Upvotes: 0
Reputation: 51
Thanks, Gimson, that did help. I was able to resolve this by calling the value as below:
def CAPSLOCK_STATE():
import ctypes
hllDll = ctypes.WinDLL ("User32.dll")
VK_CAPITAL = 0x14
return hllDll.GetKeyState(VK_CAPITAL)
CAPSLOCK = CAPSLOCK_STATE()
if ((CAPSLOCK) & 0xffff) != 0:
print("\nWARNING: CAPS LOCK IS ENABLED!\n")
This does the trick.
Upvotes: 1
Reputation: 66
From the looks of it, your value is being treated as a full-sized integer.
hllDll.GetKeyState gets its return value from the Win32 GetKeyState function seen here.
The return value from Windows is a Short. Your return value from the function was 361693184, which if you translate into binary is 10101100011110000000000000000. Notice the trailing 16 0-bits. I'm guessing that return value came from a test when you should have gotten a 0, and because it's trying to read a full 32-bit int, the top 16 bits are just garbage.
I would start by looking at your code to see why it might be assuming the value is a 32-bit integer. The joys of duck typing :)
I hope this helps! If this doesn't seem to be the problem, post some code where you call the function, so we can get a better look.
Upvotes: 2