How to send a simulated key press to the active control #170

Here's a procedure that sends a simulated key press to the active control:

procedure PostKeyEx32(key: Word; const shift: TShiftState;
  specialkey: Boolean);
type
  TShiftKeyInfo = record
    shift: Byte;
    vkey: Byte;
  end;
  ByteSet = set of 0..7;
const
  shiftkeys: array [1..3] of TShiftKeyInfo = (
    (shift: Ord(ssCtrl) ; vkey: VK_CONTROL),
    (shift: Ord(ssShift) ; vkey: VK_SHIFT),
    (shift: Ord(ssAlt) ; vkey: VK_MENU)
  );
var
  flag: DWORD;
  bShift: ByteSet absolute shift;
  j: Integer;
begin
  for j := 1 to 3 do
  begin
    if shiftkeys[j].shift in bShift then
      keybd_event(
        shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), 0, 0
    );
  end;
  if specialkey then
    flag := KEYEVENTF_EXTENDEDKEY
  else
    flag := 0;

  keybd_event(key, MapvirtualKey(key, 0), flag, 0);
  flag := flag or KEYEVENTF_KEYUP;
  keybd_event(key, MapvirtualKey(key, 0), flag, 0);

  for j := 3 downto 1 do
  begin
    if shiftkeys[j].shift in bShift then
      keybd_event(
        shiftkeys[j].vkey,
        MapVirtualKey(shiftkeys[j].vkey, 0),
        KEYEVENTF_KEYUP,
        0
      );
  end;
end;

Parameters:

  • key: virtual keycode of the key to send. For printable keys this is simply the ANSI code Ord(character).
  • shift: state of the modifier keys. This is a set, so you can set several of these keys (shift, control, alt, mouse buttons) in tandem. The TShiftState type is declared in the Classes unit.
  • specialkey: normally this should be False. Set it to True to specify a key on the numeric keypad, for example.

This procedure uses the Windows API function keybd_event to manufacture a series of key events matching the passed parameters. The events go to the control with focus. Note that for characters key is always the upper-case version of the character. Sending without any modifier keys will result in a lower-case character, sending it with [ssShift] will result in an upper-case character.

Usage:

procedure TForm1.SpeedButton1Click(Sender: TObject) ;
begin
  // Simulate PRINTSCREEN - snapshot of the full screen
  PostKeyEx32(VK_SNAPSHOT, [], False) ;

  // Simulate PRINTSCREEN - snapshot of the active window
  PostKeyEx32(VK_SNAPSHOT, [ssAlt], False) ;

  // Simulate Spacebar key
  PostKeyEx32(VK_space, [], False) ;( I changed this)

  // Simulate Alt+F4 - close active window
  PostKeyEx32(VK_F4, [ssAlt], False) ;
end;
You can also find PostKeyEx32 in the DelphiDabbler Code Snippets Database.
Author: Unknown
Contributor: Mike
Added: 2010/10/12
Last updated: 2013/10/12