Delphi 为什么SendInput Ctrl+;V在Outlook中不工作?

Delphi 为什么SendInput Ctrl+;V在Outlook中不工作?,delphi,outlook,delphi-xe,hotkeys,sendinput,Delphi,Outlook,Delphi Xe,Hotkeys,Sendinput,我有一个程序,它使用系统范围的热键Ctrl+Shift+用户选择的一个键,通过使用SendInput发送Ctrl+V组合,将文本粘贴到剪贴板中。这在大多数程序中都很有效。但在Outlook中,在新电子邮件的“收件人”字段中,我尝试的每个键都会显示“将项目移动到文件夹”Outlook对话框,该对话框应该是Ctrl+Shift+V组合键。在身体领域,什么也没有发生。你知道这里发生了什么吗?请参阅下面要复制的代码: procedure TForm1.FormCreate(Sender: TObject

我有一个程序,它使用系统范围的热键Ctrl+Shift+用户选择的一个键,通过使用SendInput发送Ctrl+V组合,将文本粘贴到剪贴板中。这在大多数程序中都很有效。但在Outlook中,在新电子邮件的“收件人”字段中,我尝试的每个键都会显示“将项目移动到文件夹”Outlook对话框,该对话框应该是Ctrl+Shift+V组合键。在身体领域,什么也没有发生。你知道这里发生了什么吗?请参阅下面要复制的代码:

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;
过程TForm1.FormCreate(发送方:TObject);
开始
如果未注册快捷键(手柄,1,模式移位或模式控制,Ord('P')),则
ShowMessage('Error');
结束;
程序TForm1.WMHotkey(Var msg:TWMHotkey);
变量
按键输入:TInput数组;
过程KeybdInput(VKey:字节;标志:DWORD);
开始
设置长度(键输入,长度(键输入)+1);
按键输入[高(按键输入)]。它的类型:=输入\键盘;
使用键输入[高(键输入)]。ki do
开始
wVk:=VKey;
wScan:=MapVirtualKey(wVk,0);
dwFlags:=标志;
结束;
结束;
开始
如果(msg.HotKey>0)和(msg.HotKey<2),则
开始
Clipboard.AsText:=“一些文本”;
KeybdInput(VK_控件,0);//Ctrl键
键盘输入(Ord('V'),0);
keybd输入(Ord('V'),KEYEVENTF_KEYUP);
KeybdInput(VK_控件,KEYEVENTF_KEYUP);//Ctrl键
SendInput(长度(KeyInputs)、KeyInputs[0]、SizeOf(KeyInputs[0]);
结束
结束;

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


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

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;

使用自动化可能更容易。我的软件可以与任何允许粘贴文本的程序一起使用,因此自动化将不实用。我刚刚注意到这种SendInput技术在Outlook中不起作用。我认为如果您添加了一个好的SSCCE,更有可能有人会提供帮助。如果我能不费吹灰之力地责备别人,那么我会更愿意帮忙。就目前的情况而言,我必须投入时间来重做。事实上,每个潜在的帮手都需要这样做。也许这一步已经够让人讨厌的了。它似乎并没有吃掉关键的一击。当我使用SendInput发送Ctrl+V时,似乎添加了Shift键。所以它得到了Ctrl+Shift+V。希望有一个比全局钩子更简单的方法,但我会试试。谢谢。Outlook将如何做到这一点?它如何区分伪造的输入事件和真实的输入事件?屏幕上的键盘是如何工作的?是的,添加KeybdInput(VK_SHIFT,KEYEVENTF_KEYUP);这就是诀窍。谢谢你,塞巴斯蒂安!