为什么在Outlook中使用SendInput Ctrl+V无效?

5

我有一个程序,使用系统级热键Ctrl+Shift+用户自定义的按键通过使用类似这里所示的SendInput发送Ctrl+V组合键来粘贴剪贴板中的文本。在大多数程序中都可以正常工作。但是在Outlook中,在新电子邮件的To字段上,我尝试的所有键都会弹出“移动项目到文件夹”Outlook对话框,这应该是Ctrl+Shift+V组合键。在Body字段中没有任何反应。这里发生了什么?可参考以下代码进行复现:

procedure TForm1.FormCreate(Sender: TObject);
begin
  If not RegisterHotkey( Handle, 1, MOD_SHIFT or  MOD_CONTROL, Ord('P') ) Then
    ShowMessage('Error');
end;

Procedure TForm1.WMHotkey( Var msg: TWMHotkey );
var
  KeyInputs: array of TInput;

  procedure KeybdInput(VKey: Byte; Flags: DWORD);
  begin
    SetLength(KeyInputs, Length(KeyInputs)+1);
    KeyInputs[high(KeyInputs)].Itype := INPUT_KEYBOARD;
    with  KeyInputs[high(KeyInputs)].ki do
    begin
      wVk := VKey;
      wScan := MapVirtualKey(wVk, 0);
      dwFlags := Flags;
    end;
  end;

Begin
  If (msg.HotKey > 0) And (msg.HotKey < 2) Then
  Begin
    Clipboard.AsText:= 'Some text';
    KeybdInput(VK_CONTROL, 0);                // Ctrl
    KeybdInput(Ord('V'), 0);
    KeybdInput(Ord('V'), KEYEVENTF_KEYUP);
    KeybdInput(VK_CONTROL, KEYEVENTF_KEYUP); // Ctrl
    SendInput(Length(KeyInputs), KeyInputs[0], SizeOf(KeyInputs[0]));
  end
End;

可能更容易使用自动化。 - David Heffernan
我的软件旨在与允许粘贴文本的任何程序配合使用,因此自动化并不实用。我刚刚注意到这种SendInput技术在Outlook中无法工作。 - user3640611
我认为如果您添加了一个好的SSCCE,有人更可能会帮助您。如果我可以轻松地重现问题,那么我更愿意提供帮助。但事实上,我必须投入时间来重现问题。实际上,每个潜在的帮助者都需要这样做。也许这一步已经足够令人望而却步了。 - David Heffernan
2个回答

3

SendInput不会重置键盘的当前状态。因此,Outlook会看到您的热键中的Ctrl+Shift。您需要模拟释放Shift键。

所以,如果我按照以下方式操作,在Outlook中就可以正常工作:

var
  input: TInput;
begin
  // This releases the shift Key:
  input.Itype := INPUT_KEYBOARD;
  input.ki.wVk := VK_SHIFT;
  input.ki.wScan := 0;
  input.ki.dwFlags := KEYEVENTF_KEYUP;
  input.ki.time := 0;
  input.ki.dwExtraInfo := 0;
  SendInput(1, input, sizeof(input));

  // Send 'V'
  input.Itype := INPUT_KEYBOARD;
  input.ki.wVk := Ord('V');
  input.ki.wScan := Ord('V');
  input.ki.dwFlags := 0;
  input.ki.time := 0;
  input.ki.dwExtraInfo := 0;
  SendInput(1, input, sizeof(input));
  input.ki.dwFlags := KEYEVENTF_KEYUP;
  SendInput(1, input, sizeof(input));
end;

是的,添加以下代码可以解决问题:KeybdInput(VK_SHIFT, KEYEVENTF_KEYUP);感谢Sebastian! - user3640611

0

Outlook会吞噬这样的按键。唯一的解决方法是安装一个键盘钩子(SetWindowsHookEx(WH_GETMESSAGE, ...))。在您的钩子过程中,您可以使用FindControl()来查找Delphi控件。然后,您可以决定是否将消息传递给该控件并将消息重置为WM_NULL,或者让它通过到Outlook。

为什么不使用Outlook对象模型来修改文本?Inspector.GetWordEditor返回Word的Document对象。


似乎没有接收到按键输入。当我使用SendInput发送Ctrl + V时,它似乎添加了Shift键的按下。因此它会变成Ctrl + Shift + V。希望有比全局钩子更简单的方法,但我会尝试一下。谢谢。 - user3640611
Outlook怎么做到的呢?它如何能够区分伪造的输入事件和真实的事件?屏幕键盘又是如何工作的呢? - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接