What is the best way to intercept the Caps Lock button on Windows, for making a program like Launchy?
Currently, I'm setting a low-level hook with SetWindowsHookEx, but that's a bit too low-level for me, since I don't want to intercept other programs that are trying to be active a low level. I'm looking for the highest possible level of interception that can still prevent turning on Caps Lock itself... any better suggestions?
You can use RegisterHotKey:
RegisterHotKey(hWnd, 0, 0, VK_CAPITAL);
Your window will receive a WM_HOTKEY message whenever this key is pressed.
Apparently the best way is to use a low-level hook, since RegisterHotkey doesn't intercept the key.
Related
I am using windows on my laptop. I also remapped caps lock to esc for smoother vim experience.
Now my caps lock light indicator is always off and I start wondering "Is it possible to use caps lock indicator for something else?". Something like blinking on request etc.
I never did something like that so I have very basic questions:
Can light indicator be separately turned on\off without actual caps lock functionality?
Unless your keyboard has its own API to control the lights (gaming keyboards sometimes do), or you have a custom keyboard driver that can control the lights, then what you are asking for is generally not possible with most keyboards, as Windows simply has no API to control just a keyboard's lights without also updating its key states.
UPDATE:
Apparently, there is such an API, after all:
IOCTL_KEYBOARD_QUERY_INDICATORS IOCTL
The IOCTL_KEYBOARD_QUERY_INDICATORS request returns information about the keyboard indicators.
IOCTL_KEYBOARD_SET_INDICATORS IOCTL
The IOCTL_KEYBOARD_SET_INDICATORS request sets the keyboard indicators.
You can use DefineDosDevice() and CreateFile() to open a HANDLE to the desired keyboard, and then use DeviceIoControl() to query the keyboard for its current KEYBOARD_INDICATOR_PARAMETERS, and then update its LedFlags field to include or omit the KEYBOARD_CAPS_LOCK_ON flag to turn the CapLock key's LED light on/off as needed.
See Manipulating the Keyboard Lights in Windows NT for an example.
I’m working on an application that uses the great MASShortcut repository by Shpakovski. I reference this to ask if there is a way to register a shortcut for Capslock in the same way that Shpakovski does in his repository?
It seems that I can’t register 0xffff (Key Codes shows this as Capslock) as a valid shortcut. Even if I combine it with the modifier keys. I also want to catch the press before it toggles the system’s Capslock functionality.
I’m aware that I could listen to all keystrokes and just catch the Capslock when it occurs but I want to avoid this behaviour since I feel it’s potentially insecure and will also decrease the overall system performance.
Edit: I already took a look at some working C++ / C# libraries for Windows which implement this feature. They seem to override the system’s Capslock flag continuously which I found pretty odd. I’m basically having 2 problems here:
1. How to catch the Capslock press without having a keystroke listener all the time
2. How to do so without triggering the system’s Capslock functionality.
One possibility could be to overwrite sendEvent: in your NSApplication delegate. From Apples documentation:
You rarely invoke sendEvent: directly, although you might want to
override this method to perform some action on every event. sendEvent:
messages are sent from the main event loop (the run method).
sendEvent: is the method that dispatches events to the appropriate
responders—NSApp handles application events, the NSWindow object
indicated in the event record handles window-related events, and mouse
and key events are forwarded to the appropriate NSWindow object for
further dispatching.
You could evaluate if the current event has the modifier key pressed and act upon that.
Edit:
For background processing Quartz event taps can be used. If that leads to a rejection, I don't know.
I have been building a very small game in the Windows API, and in the main message loop I use GetAsyncKeyState() to test if a user is pressing the arrow buttons. I use this instead of WM_KEYDOWN because with WM_KEYDOWN there is an initial pause after the first press, and I don't want to modify a user's settings. My antivirus program flags the game as a keylogger program, is there an alternative way about this?
How is the anti-virus program supposed to guess that you are not using GetAsyncKeyState() to spy on the keyboard and log keys? You tell it of course, make an exclusion. If you're worried that your future customers are not so easily convinced then go back to using WM_KEYDOWN/UP. Use an array of 256 bools to keep track of the key state. Set it to true on DOWN, regardless of how many you get, false on UP. Also check if the scanner is happy when you stop calling the API function when your app loses focus. Pay attention to WM_ACTIVATEAPP.
I know there is no way to block or ignore ctrl+Alt+Del within a program. But thats not what I want. Is there a way to only be notified if it WAS pressed? No interaction required, only notification.
Thank you!
I'm not sure why you'd want to do this, and I have a suspicion there's probably a better and cleaner way to accomplish your ultimate goal, but...
Off the top of my head, I would run a timer in the background of your application, and each time the timer fires, check to see if the Ctrl , Alt , and Delete keys were pressed. To do that, you'll have to use GetAsyncKeyState from user32.dll. I'd give you a code sample, but I'm not sure what language you're using. Play around with the interval for the timer to see what it needs to be to balance performance, yet still work.
Doesn't seem that there is an easy way to get a SAS notification, all articles I've found dealt with replacing GINA.
You might want to take a look at these:
Customizing GINA, Part 1
Customizing GINA, Part 2
C++ Q&A Typename, Disabling Keys in Windows XP with TrapKeys
If you only want to find out whether the user has locked his workstation, you should take a look at WTSRegisterSessionNotification in conjunction with WM_WTSESSION_CHANGE.
Is it possible to intercept a keystroke (and characters) sent to a window? By intercept, I mean play man-in-the-middle, instead of having just hooks onto the Window.
I'd like to filter (i.e. eliminate some keystrokes) keystrokes to a window.
Use SetWindowsHookEx(). Just eliminating keystrokes can be done with a simple WH_KEYBOARD_LL hook. It is not a global hook so is easy to get right. Googles very well too.