2014-09-13 230 views
2

使用Delphi,我试图找到一种方法来发送字符串/一系列字符或击键到活动窗口。使用SendInput我有以下代码:SendInput在某些应用程序中不起作用 - Windows与Delphi

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ασδλκφχωιοευα.. 这是一个longr srrig .. 他是第二个字符串使用Unicodeασδλκφχωιοευα.. 他是一个较长的字符串.. 他是第二个字符串使用Unicodeασδλκφχωιοευα.. THISIS更长的字符串.. 他是第二个字符串使用Unicode ασδλφφχωιοευα..

在用于PC的Kindle(添加注释)中,除''之外的所有内容。被转换为'T'。

任何想法是什么问题以及如何解决它?

谢谢!

回答

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自动化而无需求助于输入伪造。

+0

这样可以解决问题,谢谢! – 2014-09-13 17:21:18

相关问题