1

I have a WPF desktop application written with NET Core 3.1 and it catches keystrokes with KeyDown command. All characters are caught with the keyboard. When I use a Streamdeck and its System Text feature, which sends keys like a keyboard my WPF app doesn't catch it.

Tested on Notepad and the text sent from the Streamdeck works as it should, e.g. X 1 Enter.

When I debug the only thing that gets sent is Enter key.

private void MyApp_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.X)
    {
        //do something
    }
}

Everything works fine with a normal keyboard. Barcode Scanner works too. It's the Streamdeck that won't catch the text it sends.

Is there anything I need to set in my project to catch it?

StreamDeck Screenshot

Mmedi005
  • 35
  • 7
  • I am not a owner of SteamDeck but are you sure that it sends a series of key strokes? That function sounds like just pasting a predefined text. If it is the case, you cannot capture it as key strokes. – emoacht May 20 '21 at 15:05
  • @emoacht how can I test if it is a predefined text? Why does it work in Notepad? – Mmedi005 May 20 '21 at 16:49
  • Have you tried TextBox control in WPF application? Can StreamDeck send text to the TextBox? If so, Key events are fired? – emoacht May 21 '21 at 00:16
  • @emoacht when I send to the Textbox it is the same as Key Press....the only key that is sent is the Enter Key, all characters are ignored. – Mmedi005 May 21 '21 at 15:46
  • Digging into window message, I figured out how to capture it. I am writing the answer. – emoacht May 24 '21 at 12:43

1 Answers1

1

I myself am interested in Elgato Stream Deck a little and so tried Stream Deck Mobile app. I found when the app sends a text, a pair of WM_KEYDOWN and WM_KEYUP windows messages with VK_PACKET virtual-key code are sent for each letter. It suggests the app utilizes SendInput function to "send Unicode characters as if they were keystrokes".

Then, luckily I found UIElement.PreviewTextInput event can capture each letter. So, assuming the text ends with Enter key, we can retrieve the text sent by the app by aggregating the letters.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private readonly StringBuilder _buffer = new();

    protected override void OnPreviewTextInput(TextCompositionEventArgs e)
    {
        if (e.Text is ("\r\n" or "\r" or "\n")) // Key.Return produces a line break.
        {
            if (_buffer.Length > 0)
            {
                OnTextRecieved(_buffer.ToString());
                _buffer.Clear();
            }
        }
        else
        {
            _buffer.Append(e.Text);
        }
        base.OnPreviewTextInput(e);
    }

    protected virtual void OnTextRecieved(string text)
    {
        Debug.WriteLine($"TextRecieved {text}");
    }
}
emoacht
  • 2,764
  • 1
  • 13
  • 24
  • will try this...thank you so much....does this replace the keydown event if I need to be able to capture the key entry from whatever device the user decides to use? e.g. keyboard, barcode scanner – Mmedi005 May 24 '21 at 18:24
  • Probably no. It depends but you need to prepare for each input device or input method if you wish to capture all of them. – emoacht May 24 '21 at 22:15