嗨,我正在尝试SendKeys ('hello world');
在 Visual Basic Delphi 中完成经典,但我发现你不能这样做。
有谁知道该怎么做?
查看 Win32 APIkeybd_event()
和SendInput()
函数。这两个函数都在 Delphi 的Windows
单元中声明。
例如:
uses
Windows;
procedure SendKeys(const S: String);
var
I: Integer;
begin
for I := 1 to Length(S) do
begin
// keybd_event() does not support Unicode, so you should use SendInput() instead...
keybd_event(S[I], MapVirtualKey(S[I], 0),0, 0);
keybd_event(S[I], MapVirtualKey(S[I], 0), KEYEVENTF_KEYUP, 0);
end;
end;
uses
Windows;
{$POINTERMATH ON}
procedure SendKeys(const S: String);
var
InputEvents: PInput;
I, J: Integer;
begin
if S = '' then Exit;
GetMem(InputEvents, SizeOf(TInput) * (Length(S) * 2));
try
J := 0;
for I := 1 to Length(S) do
begin
InputEvents[J].Itype := INPUT_KEYBOARD;
InputEvents[J].ki.wVk := 0;
InputEvents[J].ki.wScan := Ord(S[I]);
InputEvents[J].ki.dwFlags := KEYEVENTF_UNICODE;
InputEvents[J].ki.time := 0;
InputEvents[J].ki.dwExtraInfo := 0;
Inc(J);
InputEvents[J].Itype := INPUT_KEYBOARD;
InputEvents[J].ki.wVk := 0;
InputEvents[J].ki.wScan := Ord(S[I]);
InputEvents[J].ki.dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;
InputEvents[J].ki.time := 0;
InputEvents[J].ki.dwExtraInfo := 0;
Inc(J);
end;
SendInput(J, InputEvents[0], SizeOf(TInput));
finally
FreeMem(InputEvents);
end;
end;
以下是我在过去必须做的一些自动化项目中组装的一些功能。他们利用keybd_event()
API。
procedure SendKeys(const AString: String; const AAmount: Integer = 1);
const
TReadableChars = [32..126];
TShiftChars = [33..43, 58, 60, 62..90, 94..95, 123..126];
type
TKeyInfo = record
AsChar : Char;
AsOrd : Integer;
VK : Integer;
SC : Integer;
UseShift: Boolean;
end;
TKeys = TList<TKeyInfo>;
var
key : TKeyInfo;
keys : TKeys;
C1, C2: Integer;
begin
keys := TKeys.Create;
try
for C1 := 1 to Length(AString) do
begin
key.AsChar := AString[C1];
key.AsOrd := Ord(key.AsChar);
if key.AsOrd in TReadableChars then
begin
key.VK := VkKeyScan(key.AsChar);
key.UseShift := key.AsOrd in TShiftChars;
key.SC := MapVirtualKey(key.VK, 0);
keys.Add(key);
end;
end;
for C1 := 1 to AAmount do
for C2 := 0 to keys.Count - 1 do
begin
key := keys[C2];
if key.UseShift then
keybd_event(VK_SHIFT, 0, 0, 0);
keybd_event(key.VK, key.SC, 0, 0);
keybd_event(key.VK, key.SC, KEYEVENTF_KEYUP, 0);
if key.UseShift then
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
end;
finally
keys.Free;
end;
end;
procedure SendKey(const AVKCode: Integer; const AAmount: Integer = 1);
var
C1: Integer;
begin
for C1 := 1 to AAmount do
begin
keybd_event(AVKCode, 0, 0, 0);
keybd_event(AVKCode, 0, KEYEVENTF_KEYUP, 0);
end;
end;
此函数还能够发送特殊字符,如 Enter/Chr(13)、Escape/Chr(27)、...
procedure SendKeyString(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[i];
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 {228 (F1) => $70 (vk_F1)}
c := Ord(ch) - 116
else
if ch < #110 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 { $2A = scancode of VK_SHIFT }
Keybd_Event(VK_SHIFT, $2A, 0, 0);
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;
end;
end;
这里是SendKeyString()
上下文中的整个单元(包含 ):
{****************************************************}
{ SendKeys Unit for Delphi 32 }
{ Copyright (c) 1999 by Borut Batagelj (Slovenia) }
{ Aleksey Kuznetsov (Ukraine) }
{ Home Page: www.utilmind.com }
{ E-Mail: info@utilmind.com }
{****************************************************}
unit SendKeys;
interface
uses
Windows, SysUtils;
const
SK_BKSP = #8;
SK_TAB = #9;
SK_ENTER = #13;
SK_ESC = #27;
SK_ADD = #107;
SK_SUB = #109;
SK_F1 = #228;
SK_F2 = #229;
SK_F3 = #230;
SK_F4 = #231;
SK_F5 = #232;
SK_F6 = #233;
SK_F7 = #234;
SK_F8 = #235;
SK_F9 = #236;
SK_F10 = #237;
SK_F11 = #238;
SK_F12 = #239;
SK_HOME = #240;
SK_END = #241;
SK_UP = #242;
SK_DOWN = #243;
SK_LEFT = #244;
SK_RIGHT = #245;
SK_PGUP = #246;
SK_PGDN = #247;
SK_INS = #248;
SK_DEL = #249;
SK_SHIFT_DN = #250;
SK_SHIFT_UP = #251;
SK_CTRL_DN = #252;
SK_CTRL_UP = #253;
SK_ALT_DN = #254;
SK_ALT_UP = #255;
procedure SendKeyString(Text: String);
procedure SendKeysToTitle(WindowTitle: String; Text: String);
procedure SendKeysToHandle(WindowHandle: hWnd; Text: String);
procedure MakeWindowActive(wHandle: hWnd);
function GetHandleFromWindowTitle(TitleText: String): hWnd;
implementation
procedure SendKeyString(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[i];
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 {228 (F1) => $70 (vk_F1)}
c := Ord(ch) - 116
else
if ch < #110 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 { $2A = scancode of VK_SHIFT }
Keybd_Event(VK_SHIFT, $2A, 0, 0);
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;
end;
end;
procedure MakeWindowActive(wHandle: hWnd);
begin
if IsIconic(wHandle) then
ShowWindow(wHandle, SW_RESTORE)
else
BringWindowToTop(wHandle);
end;
function GetHandleFromWindowTitle(TitleText: String): hWnd;
var
StrBuf: Array[0..$FF] of Char;
begin
Result := FindWindow(PChar(0), StrPCopy(StrBuf, TitleText));
end;
procedure SendKeysToTitle(WindowTitle: String; Text: String);
var
Window: hWnd;
begin
Window := GetHandleFromWindowTitle(WindowTitle);
MakeWindowActive(Window);
SendKeyString(Text);
end;
procedure SendKeysToHandle(WindowHandle: hWnd; Text: String);
begin
MakeWindowActive(WindowHandle);
SendKeyString(Text);
end;
end.