5

我有一个程序,它使用系统范围的热键Ctrl++通过使用此处使用的SendInput 发送 +Shift组合a key of the user's choice将文本粘贴到剪贴板中。这在大多数程序中都可以正常工作。但是在新电子邮件的“收件人”字段中的 Outlook 中,我尝试的每个键最终都会弹出“将项目移动到文件夹”Outlook 对话框,该对话框应该是+ +组合键。在 Body 字段中没有任何反应。有什么想法吗?请参阅下面的重现代码:CtrlVCtrlShiftV

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;
4

2 回答 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;
于 2014-05-25T18:08:31.417 回答
0

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

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

于 2014-05-24T22:22:19.137 回答