使用Delphi,我正在尝试找到一种向活动窗口发送字符串/字符串或键击的方法。使用SendInput我有以下代码:
uses
System.SysUtils, Windows, System.Types, System.UITypes, System.Classes,
System.Variants, VCL.Dialogs, VCL.ExtCtrls;
var
input: array of TInput;
s: String;
i: Integer;
begin
s := 'This is a longer string.' +
sLineBreak + 'This is the second string with unicode ασδλκφχωιοευα.';
SetLength(input, Length(s));
i := 1;
while i <= Length(s) do
if ord(s[i]) <> 13 then begin
input[i-1].iType := INPUT_KEYBOARD;
//input[i+5].ki.wVk := 0;
input[i-1].ki.dwFlags := KEYEVENTF_UNICODE;
input[i-1].ki.wScan := ord(s[i]);
i := i+1;
end
else begin //Type Enter key.
//Key down
input[i-1].iType := INPUT_KEYBOARD;
input[i-1].ki.wVk := VK_RETURN;
i := i+1; //Assumes that chr(13) is followed by chr(10).
//Ignore the chr(10) and lift up the Enter key.
input[i-1].iType := INPUT_KEYBOARD;
input[i-1].ki.wVk := VK_RETURN;
input[i-1].ki.dwFlags := KEYEVENTF_KEYUP;
i:= i+1;
end;
//end;
Windows.SendInput(Length(s), input[0], SizeOf(input[0]));
end.
我编译了exe并使用Autohotkey将其分配给热键(F6),以便我可以从任何应用程序触发程序。它在大多数应用程序中运行良好 - 我已经在MS Excel,MS Word,Foxit Phantom pdf,Notepad ++等中进行了测试。字有点慢 - 你可以看到几乎一个一个地出现的字符,但它们都在那里正确。
但是,在Opera邮件(我最想使用该程序的应用程序之一)中,输入字符串在某种程度上总是错误的。以下是一些示例输入:
这是一个更长的字符串.. 他的第二个字符串是unicodeασδλκφχωιοευα.. 这是一个更长的字符串.. 他的第二个字符串是unicodeασδλκφχωιοευα.. 这是一个更长的srrig .. 他的第二个字符串是unicodeασδλκφχωιοευα.. 他是一个更长的字符串.. 他的第二个字符串是unicodeασδλκφχωιοευα.. 这是一个更长的字符串.. 他是第二个带有unicodeασδλκφχωιοευα的字符串..
在Kindle for PC(添加注释)中除了'。'之外的所有内容。转换为'T'。
关于问题是什么以及如何解决问题的任何想法?
谢谢!
答案 0 :(得分:3)
您正在发送按键事件,但不会发送相应的按键事件。每个键击通常需要两个输入事件。一个用于按键,dwFlags = KEYEVENTF_UNICODE
和一个用于按键,dwFlags = KEYEVENTF_UNICODE or KEYEVENTF_KEYUP
。
您可以按以下方式对其进行编码:
procedure SendKeys(const Text: string);
var
C: Char;
Input: TInput;
InputList: TList<TInput>;
begin
InputList := TList<TInput>.Create;
try
for C in Text do begin
if C = #10 then continue;
Input := Default(TInput);
Input.Itype := INPUT_KEYBOARD;
Input.ki.dwFlags := KEYEVENTF_UNICODE;
Input.ki.wScan := ord(C);
InputList.Add(Input);
Input.ki.dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;
InputList.Add(Input);
end;
SendInput(InputList.Count, InputList.List[0], SizeOf(TInput));
finally
InputList.Free;
end;
end;
最后,您很可能使用UI自动化执行此操作,而无需借助输入伪装。