【问题标题】: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,那么有人会提供帮助。如果我可以不费吹灰之力地进行复制,那么我会更倾向于提供帮助。就目前而言,我必须投入时间进行复制。事实上,每个潜在的帮助者都需要这样做。也许这一步已经足够了。

标签: delphi outlook delphi-xe hotkeys sendinput


【解决方案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 如何做到这一点?它如何区分伪造的输入事件和真实的输入事件?屏幕键盘如何工作?
猜你喜欢
  • 2016-12-02
  • 1970-01-01
  • 2018-05-19
  • 2022-06-30
  • 2013-11-27
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 2018-03-06
相关资源
最近更新 更多