Search code examples
delphidelphi-xe8

How can I capture keyboard status when my application doesn't have the focus?


My girlfriend's new laptop doesn't have indicator LEDs for NumLock and CapsLock, so I wrote a small program which show their status on screen:

procedure TForm1.Timer1Timer(Sender: TObject);  
var  
  KeyState: TKeyboardState;  
begin  
  GetKeyboardState(KeyState);  
  if KeyState[VK_NUMLOCK] = 0 then  
    PanelNumLock.Color := clSilver  
  else  
    PanelNumLock.Color := clLime;  
  if KeyState[VK_CAPITAL] = 0 then  
    PanelCapsLock.Color := clSilver  
  else  
    PanelCapsLock.Color := clLime;  
end;

enter image description here

This works as long as my program has the focus, but when the focus goes to anther program statuses are no longer updated. (However, just moving the mouse over the form, no clicking, is sufficient for updating.)

How can I let the program update when another application has the focus?


Solution

  • You can simply use GetKeyState in your Timer.

    if GetKeyState(VK_NUMLOCK) = 1 then
      PanelNumLock.Color := clLime
    else
      PanelNumLock.Color := clSilver;
    
    if GetKeyState(VK_CAPITAL) = 1 then
      PanelCapsLock.Color := clLime
    else
      PanelCapsLock.Color := clSilver;
    

    This works even when your application doesn't have the focus. Tested on XP.