How can I display the the current status of the CAPS LOCK key in my
application?
There are several ways to address this, and one I have seen before is to check the
KeyPress event, and modify the status according to each press of the CapsLock key.
The problem with this approach is that it would not give you the necessary status
at the time the application started. We therefore have to get our hands dirty to get the
ideal solution, and dig into the Windows API. Luckily, the code is quite simple.
We use the GetKeyState function, passing it the CapsLock key constant and receiving a
return value. If the return value is zero, CapsLock is off, otherwise it is on. Simple
code then, dropped into a button click event:
procedure TForm1.Button1Click(Sender: TObject);
begin
if GetKeyState(VK_CAPITAL) > 0 then
Label1.Caption := 'Caps Lock On'
else
Label1.Caption := 'Caps Lock Off';
end;
Naturally this could easily be modified into a usable function to return the value so
that it could be used by more than one routine and avoid code duplication. Firstly, modify
it to return the integer status:
function GetCapsLockStatus: Integer;
begin
Result := GetKeyState(VK_CAPITAL);
end;
You would call this from wherever you wanted, and one possible use would achieve the
same thing as the original code:
procedure TForm1.Button1Click(Sender: TObject);
begin
if GetCapsLockStatus > 0 then
Label1.Caption := 'Caps Lock On'
else
Label1.Caption := 'Caps Lock Off';
end;
You could also convert it to a function that returns a string:
function GetCapsLockStatusString: Integer;
begin
if GetCapsLockStatus > 0 then
Result := 'On'
else
Result := 'Off';
end;
Usage of this would be simple, assigning the resulting string directly to a label
caption:
procedure TForm1.Button2Click(Sender: TObject);
begin
Label1.Caption := GetCapsLockStatusString;
end;
Once you have the original status you can either monitor keypresses for the CapsLock
key (check for the virtual key constant VK_CAPITAL) and change the caption appropriately,
or simply insert the call into a routine that is regularly called. Note that
inserting the function call into the OnKeyPress event would work, but there would be
consequences in the performance hit caused by the function running and the label being
rewritten every time any key is pressed.
There we go then - simple but effective use of the Windows API to achieve the desired
result.
Chris Bray
© Vertical Software 2004, all rights reserved.
|