I've been tinkering around with an app that drives another application (not Delphi, not mine) that uses this function:
procedure SendKeys(const text: String);
var
i: Integer;
shift: Boolean;
vk,scancode: Word;
ch: Char;
c,s: Byte;
const
vk_keys: Array[0..9] of Byte =
(VK_HOME,VK_END,VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,
VK_NEXT,VK_INSERT,VK_DELETE);
vk_shft: Array[0..2] of Byte = (VK_SHIFT,VK_CONTROL,VK_MENU);
flags: Array[false..true] of Integer = (KEYEVENTF_KEYUP, 0);
begin
shift := false;
for i := 1 to Length(text) do
begin
ch := text;
if ch >= #250 then
begin
s := Ord(ch) - 250;
shift := not Odd(s);
c := vk_shft[s shr 1];
scancode := MapVirtualKey(c,0);
Keybd_Event(c,scancode,flags[shift],0);
end
else
begin
vk := 0;
if ch >= #240 then
c := vk_keys[Ord(ch) - 240]
else if ch >= #228 then
c := Ord(ch) - 116 {228 (F1) ==> $70 (vk_F1)}
else if ch < #32 then
c := Ord(ch)
else
begin
vk := VkKeyScan(ch);
c := LoByte(vk);
end;
scancode := MapVirtualKey(c,0);
if not shift and (Hi(vk) > 0) then
Keybd_Event(VK_SHIFT,$2A,0,0);{ $2A = scancode of VK_SHIFT }
Keybd_Event(c,scancode,0,0);
Keybd_Event(c,scancode,KEYEVENTF_KEYUP,0);
if not shift and (Hi(vk) > 0) then
Keybd_Event(VK_SHIFT,$2A,KEYEVENTF_KEYUP,0);
end;
Application.ProcessMessages;
sleep(500);
end;
end;
const
SK_BKSP = #8;
SK_TAB = #9;
SK_ENTER = #13;
{snip lots defined keys}
SK_ALT_DN = #254;
SK_ALT_UP = #255;
This is a piece of the calling code:
MakeWindowActive(MyWindow);
application.ProcessMessages;
SendKeys(SK_ALT_DN +'F');
SendKeys('X');
SendKeys(SK_ALT_UP);
MakeWindowActive(MyWindow2);
SendKeys(SK_ALT_DN +'Y');
SendKeys(SK_ALT_UP);