Monday, August 11, 2008

Checking for the CapsLock Key

A couple of months ago I read "The Design of Everyday Things" and in my review I discussed a problem I had when logging into my Amazon account. As it turns out I had CapsLock on so I typed the correct letters for my password but in the wrong case. After realizing this I was able to successfully log into the site. This got me thinking about how this frustration could have been avoided if the developer had added code to check the status of CapsLock and letting the user know if it was on.

As it turns out it is pretty easy to check the status of CapsLock in a Win32 program using the GetKeyState() function. This function returns the state of a virtual key as a short value. The function is contained in the user32.dll so a reference to this external library must be made.

When using C# you must add a reference to the System.Runtime.InteropServices which contains the DllImport function used to define external functions. So to add a reference to the GetKeyState function you must add the following line to your code

   1: [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true,
   2: CallingConvention = CallingConvention.Winapi)]
   3: public static extern short GetKeyState(int keyCode);

With the reference to user32.dll and the GetKeyState function defined you can use the function within your application. In this case I check the state of the CapsLock key when a login form loads and when keys are pressed in the Username and Password boxes by calling the isCapsLock() function. This function displays a warning if the CapsLock is engaged.

   1: private void isCapslock()
   2: {
   3:     if ((((ushort)GetKeyState(0x14 /*VK_CAPITAL*/)) & 0xffff) != 0)
   4:     {
   5:         lblWarning.Text = "Caps Lock is on";
   6:         lblWarning.Visible = true;
   7:     }
   8:     else
   9:         lblWarning.Visible = false;
  10: }

When using Delphi the GetKeyState() function is already built-in so you do not need to add a reference to the user32.dll. The Delphi code is very similar to the C# code.

   1: procedure Form1.isCapsLock();
   2: begin
   3:   if 0 <> (GetKeyState(VK_CAPITAL) and $01) then
   4: begin
   5:     lblWarning.Caption := 'CapsLock is on';
   6:     lblWarning.Visible := true;
   7:   end
   8:   else
   9:     lblWarning.Visible := false;
  10: end; 

These examples are for Windows programs and cannot be used for a web based application. If you would like to provide similar functionality you will have to use some JavaScript to check the status of CapsLock. You can refer to Scott Mitchells article on 4 Guys from Rolla for an ASP.NET example.

1 comment:

Anonymous said...

I was looking for ages for this.... Works great, Thanks a lot.