5

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;
Community
  • 1
  • 1
user3640611
  • 87
  • 2
  • 10
  • It might be easier to use automation – David Heffernan May 24 '14 at 22:12
  • My software is meant to work with any program that allows pasting of text so automation would not be practical. I just noticed that this SendInput technique does not work in Outlook. – user3640611 May 24 '14 at 23:17
  • I think it more likely that somebody would help if you added a good SSCCE. If I could repro with no effort on my part then I'd be more inclined to help. As it stands I have to invest my time to make a repro. Indeed every potential helper would need to do that. Perhaps that step is sufficiently off putting. – David Heffernan May 25 '14 at 10:32

2 Answers2

3

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;
Mwiza
  • 7,780
  • 3
  • 46
  • 42
Sebastian Z
  • 4,520
  • 1
  • 15
  • 30
0

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.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • It doesn't seem to be eating a key stroke. It seems to be adding the Shift key press when I send Ctrl+V with SendInput. So it gets Ctrl+Shift+V instead. Wishing there was an easier way than global hooks but I'll try it. Thanks. – user3640611 May 24 '14 at 23:28
  • How would Outlook do that? How would it be able to tell the difference between a faked input event and a real one? And how would the on screen keyboard work? – David Heffernan May 25 '14 at 10:31