2014-09-13 110 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

相關問題