by Michael S. Kaplan, published on 2006/03/29 03:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/03/29/562606.aspx
A few days ago, Mohammed asked:
I am using System.Windows.Forms.SendKeys to send some keystrokes to the active application. When the CAPS lock on the hosting keyboard is turned on, all my keystrokes get sent with the opposite case, which is an acceptable behavior (SendKeys is dependant on the state of the keyboard).
To work around this issue, I’m trying to detect the state of the CAPS lock key to account for case changes. Does anyone know a way to do this using a .NET library call? I’m using C#.
Thanks,
There is unfortunately nothing built in, which is not to say there shouldn't be!
The trick is to use the GetKeyState function in the Win32 API, which has the following info about its return value:
The return value specifies the status of the specified virtual key, as follows:
- If the high-order bit is 1, the key is down; otherwise, it is up.
- If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.
That first half may sound familiar to those who read Getting all you can out of a keyboard layout, Part #5, since I used it to give information on whether the shift keys were pressed or not.
Well, the second half is what we're dealing with now -- the low order bit must be set to indicate a toggle key like CAPS LOCK has been pressed. So, you can use code something like this:
[DllImport("user32.dll", ExactSpelling=true)]
internal static extern ushort GetKeyState(uint nVirtKey);
internal const byte VK_CAPITAL = 0x14;if(0 != (GetKeyState(VK_CAPITAL) & 1))
{
// do whatever here
}
(You may remember that I hate the Keys enumeration, as I pointed out in Part 0; also, I did not know about VB.Net's My.Computer.Keyboard.CapsLock but luckily Sara Ford was nearby to point this out for those who are using VB and wanted avoid the const definition!)
And there you have it -- how to find out if the CAPS LOCK is toggled.
As I am sure you can imagine, we're going to be making use of this in a future post in the series. :-)
This post brought to you by "Ŧ" (U+0166, a.k.a. LATIN CAPITAL LETTER T WITH STROKE)
# Anonymous on 29 Mar 2006 7:10 AM:
# Michael S. Kaplan on 29 Mar 2006 10:46 AM:
# Mihai on 30 Mar 2006 12:36 AM:
# Luke Ogg on 20 May 2006 2:31 PM:
# Michael S. Kaplan on 20 May 2006 3:09 PM:
# Ray Woods on 7 Jun 2006 10:22 PM:
# Caio Proiete on 18 Mar 2008 12:23 PM:
Wouldn't be easier to just use the CapsLock property of the Console class?
if (Console.CapsLock)
{
// Caps Lock is on...
}
Cheers,
Caio Proiete
# Michael S. Kaplan on 18 Mar 2008 12:30 PM:
In a non-Console app? That kind of thing makes me nervous if it is not either documented as supported (or at least I've had a chance to look at the code behind the implementation!)....
Beyond all that and most significantly
a) there is the fact that it doesn't exist in .Net 1.0/1.1 (the pinvoke solution works in any version)
b) this technique will work for any toggle key. including ones that have no property available.
referenced by