为啥 SendInput Ctrl+V 在 Outlook 中不起作用?

Posted

技术标签:

【中文标题】为啥 SendInput Ctrl+V 在 Outlook 中不起作用?【英文标题】:Why does SendInput Ctrl+V not work in Outlook?为什么 SendInput Ctrl+V 在 Outlook 中不起作用? 【发布时间】:2014-07-14 00:57:49 【问题描述】:

我有一个程序使用系统范围的热键 Ctrl+Shift+用户选择的键 将文本粘贴到剪贴板通过发送 Ctrl+V 组合使用 SendInput 使用 here。这在大多数程序中都可以正常工作。但是在新电子邮件的收件人字段中的 Outlook 中,我尝试的每个键最终都会弹出“将项目移动到文件夹”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;

【问题讨论】:

使用自动化可能更容易 我的软件适用于任何允许粘贴文本的程序,因此自动化不实用。我刚刚注意到这种 SendInput 技术在 Outlook 中不起作用。 我认为如果您添加了一个好的 SSCCE,那么有人会提供帮助。如果我可以不费吹灰之力地进行复制,那么我会更倾向于提供帮助。就目前而言,我必须投入时间进行复制。事实上,每个潜在的帮助者都需要这样做。也许这一步已经足够了。 【参考方案1】:

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);成功了。谢谢塞巴斯蒂安!【参考方案2】:

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

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

【讨论】:

它似乎没有吃掉一个键击。当我使用 SendInput 发送 Ctrl+V 时,似乎添加了 Shift 键。所以它改为 Ctrl+Shift+V。希望有比全局钩子更简单的方法,但我会尝试的。谢谢。 Outlook 如何做到这一点?它如何区分伪造的输入事件和真实的输入事件?屏幕键盘如何工作?

以上是关于为啥 SendInput Ctrl+V 在 Outlook 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

时间:2019-04-10 标签:c++win32SendInput()

为啥电脑的快捷键ctrl+c和ctrl+v不能用了

电脑为啥不能用键盘Ctrl+VCtrl+C复制粘贴了

vim拷贝粘贴总结(p、Shift+Insert、Shift+Ctrl+v)

如何正确使用 SendInput() 在 C# 中模拟鼠标输入

为啥我用CAD 命令行出现窗口无效说明提示?