1

This is my code:

void tbHotkey_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key == Key.LeftShift || e.Key == Key.RightShift || e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl || e.Key == Key.LeftAlt || e.Key == Key.RightAlt || e.Key == Key.LWin || e.Key == Key.RWin)
    {
        return;
    }
    bool IsWinDown = e.KeyboardDevice.IsKeyDown(Key.LWin) | e.KeyboardDevice.IsKeyDown(Key.RWin);
    bool IsCtrlDown = e.KeyboardDevice.IsKeyDown(Key.LeftCtrl) | e.KeyboardDevice.IsKeyDown(Key.RightCtrl);
    bool IsAltDown = e.KeyboardDevice.IsKeyDown(Key.LeftAlt) | e.KeyboardDevice.IsKeyDown(Key.RightAlt);
    bool IsShiftDown = e.KeyboardDevice.IsKeyDown(Key.LeftShift) | e.KeyboardDevice.IsKeyDown(Key.RightShift);
    if (IsWinDown | IsCtrlDown | IsAltDown | IsShiftDown)
    {
        (sender as TextBox).Text =
          (IsWinDown ? "Windows + " : "") +
          (IsCtrlDown ? "Control + " : "") +
          (IsAltDown ? "Alt + " : "") +
          (IsShiftDown ? "Shift + " : "") +
          e.Key.ToString();
    }
}

It is saving the hotkey that the user types as KeyEventArgs.Key.ToString() but I need to save it as such that I can pass it to the "keys" parameter in SendKeys.Send() method easily.

Can anyone suggest how do I do this?

Elmo
  • 6,409
  • 16
  • 72
  • 140
  • I have used PostMessage with WM_KEYDOWN, and the VirtualKeyFromKey method as well to [replay stored key strokes](http://stackoverflow.com/a/16255097/385995). – Mike Fuchs Apr 27 '13 at 20:17

2 Answers2

1

You are trying to mix the WPF Key enum with the Winforms SendKeys.Send() method, which I probably wouldn't recommend. It would be cleaner and simpler in the end to send keystrokes with the WPF event system, using the Key enum directly and not involve Winforms at all, see this question.

However, if you really want to do it anyway, you need to format the string according to the documentation for SendKeys.Send(), where the modifier keys have the following codes:

  • SHIFT = "+"
  • CTRL = "^"
  • ALT = "%"

So your code could be something like:

            (sender as TextBox).Text = "(" +
              (IsCtrlDown ? "^" : "") +
              (IsAltDown ? "%" : "") +
              (IsShiftDown ? "+" : "") + ")" +
              e.Key.ToString().ToLower();

For example, if you press Ctrl+Alt+R, this would give you the string (^%)r which is a valid input for SendKeys.Send(). Note that this only currently works for letter keys, if you want to handle other special keys like caps lock, you would have to modify the code to look at the value of e.Key and output the appropriate string from the SendKeys documentation.

The windows key is funny, it is really a combination of Ctrl and Esc, so you might be able to send ^{ESC} to SendKeys to emulate that, but I'm not sure if that would work for your needs or just bring up the start menu.

Also note that in WPF you would actually need to use SendKeys.SendWait(), see this question.

Community
  • 1
  • 1
WildCrustacean
  • 5,896
  • 2
  • 31
  • 42
  • I added some more details to the answer. – WildCrustacean Jan 03 '13 at 13:38
  • There is no automatic conversion that I know of. If you want to handle all those special keys, you have to do it yourself (with a big `switch` or something). If you don't want to deal with these sort of headaches created by mixing WPF and Winforms, then try a WPF only solution like I mentioned at first. – WildCrustacean Jan 03 '13 at 14:10
  • Yes, that looks like a cleaner way to deal with key events in WPF to me. – WildCrustacean Jan 03 '13 at 16:57
0

I used the SendInput API to send keystrokes and used the KeyInterop.VirtualKeyFromKey function to convert the key from System.Windows.Input.Key to Virtual Key code.

Elmo
  • 6,409
  • 16
  • 72
  • 140