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