user3640611
user3640611

Reputation: 87

Why does SendInput Ctrl+V not work in Outlook?

I have a program that uses system wide hotkeys Ctrl+Shift+a key of the user's choice to paste the text in the clipboard by sending the Ctrl+V combination using SendInput as used here. This works fine in most programs. But in Outlook on the To field of a new email, every key I try ends up bringing up the "Move Item To Folder" Outlook dialog box which is supposed to be the Ctrl+Shift+V key combination. In the Body field nothing happens. Any ideas what is happening here? See code to reproduce below:

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;

Upvotes: 5

Views: 1281

Answers (2)

Sebastian Z
Sebastian Z

Reputation: 4730

SendInput does not reset the current state of the keyboard. So Outlook sees the Ctrl+Shift of your Hotkey. You have to simulate releasing the Shift key.

So if I do the following, it works in 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;

Upvotes: 3

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66215

Outlook eats key strokes like that. The only workaround is to install a keyboard hook (SetWindowsHookEx(WH_GETMESSAGE, ...)). In your hook proc you can use FindControl() to find the Delphi control. You can then decide whether to pass the message to that control and reset the message to WM_NULL or let it pass through to Outlook.

Why not use the Outlook Object Model to modify the text? Inspector.GetWordEditor returns Word's Document object.

Upvotes: 0

Related Questions