8

Is it possible, to capture (somewhere in app.xaml.cs i guess) any key and if it pressed open window?

Thanks for help!

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
user13657
  • 745
  • 3
  • 17
  • 36
  • Something along the lines of `if (ky.Key == Key.Up || ky.Key == Key.Down || ky.Key == Key.Right || ky.Key == Key.Left || ky.Key == Key.Add || ky.Key == Key.Subtract || ky.Key == Key.PageUp || ky.Key == Key.PageDown)`? Please provide more information! – Kush Dec 19 '12 at 17:52
  • Search web/stackoverflow for ProcessCmdKey, WndProc for WPF. In low level, it should be possible to override such method in top-level form, which would receive all messages, and process your key press. Examples [1](http://stackoverflow.com/questions/6126618/processcmdkey-analog-in-wpf) [2](http://stackoverflow.com/questions/2790913/hotkey-not-global-in-windows-forms-net) [3](http://stackoverflow.com/questions/624367/how-to-handle-wndproc-messages-in-wpf) and [4](http://stackoverflow.com/questions/2487242/how-to-catch-esc-key-press-with-wndproc) – Algirdas Dec 19 '12 at 19:18

3 Answers3

9

There is a better way. Found this on a MS forum. Works like a charm.

Put this code in Application startup:

EventManager.RegisterClassHandler(typeof(Window),
     Keyboard.KeyUpEvent,new KeyEventHandler(keyUp), true);

private void keyUp(object sender, KeyEventArgs e)
{
      //Your code...
}
Adam Calvet Bohl
  • 1,009
  • 14
  • 29
4

You could use something like this gist to register a global hook. It will fire whenever the given keys are pressed while your application is running. You can use it in your App class like this:

public partial class App
{
    private HotKey _hotKey;

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);
        RegisterHotKeys();
    }

    protected override void OnExit(ExitEventArgs e)
    {
        base.OnExit(e);
        UnregisterHotKeys();
    }

    private void RegisterHotKeys()
    {
        if (_hotKey != null) return;

        _hotKey = new HotKey(ModifierKeys.Control | ModifierKeys.Shift, Key.V, Current.MainWindow);
        _hotKey.HotKeyPressed += OnHotKeyPressed;
    }

    private void UnregisterHotKeys()
    {
        if (_hotKey == null) return;

        _hotKey.HotKeyPressed -= OnHotKeyPressed;
        _hotKey.Dispose();
    }

    private void OnHotKeyPressed(HotKey hotKey)
    {
        // Do whatever you want to do here
    }
}
khellang
  • 17,550
  • 6
  • 64
  • 84
  • Im trying to use this example, but getting error while debuging: App.OnStartup(object, System.Windows.StartupEventArgs)': no suitable method found to override – user13657 Dec 20 '12 at 12:27
  • Check out the revised answer – khellang Dec 20 '12 at 12:41
  • Thanks for fast response. Unfortunately - dont know why, but doesnt work for me. I put all that code (including class from link), but never goes into "keyPress" – user13657 Dec 20 '12 at 13:08
  • Ok - works now. But.. as i said in first post i have lot of windows. Actually it works on first (loginWindow) only. Is it possible, to somehow use it in all windows without putting methods insde of them? – user13657 Dec 20 '12 at 13:10
  • Ok, i think i get it. Im using RegisterHotKeys as method in my login window. When user is looged, im creating object of this class, thanks for what in each window i have acces to this. Thank you very much for help! :) – user13657 Dec 20 '12 at 13:43
  • Thank you very much! This works like charm. onExit didn't worked for me so I have found another approach of MainWindow.Closing. – Nikki Punjabi Feb 25 '16 at 18:50
3

Yes and no.

Focus plays a role in the order for which a given key is handled. The control which captures the initial key press can opt to not pass the key along, which would prohibit you from capturing it at the top most level. In addition there are controls within the .NET framework that swallow certain keys under certain scenarios, however I am unable to recall a specific instance.

If your application is small and the depth is nothing more than a Window with buttons, this is certainly attainable and would follow the standard approach to capturing key strokes within a WPF application.

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
          myVariable = true;
    if (ctrl && e.Key == Key.S)
          base.OnKeyDown(e);
}

protected override void OnKeyUp(KeyEventArgs e)
{
    if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
          myVariable = false;

    base.OnKeyUp(e);
}

If your application is large you can attempt a global hook as detailed here but understand that the aforementioned caveats can still exist.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88