C# WPF, USB handheldscanner - textbox

Markus Freitag 3,791 Reputation points
2020-10-15T11:54:44.51+00:00

Hello,

            txtInput.TextChanged += TxtInput_TextChanged;
            txtInput.KeyDown += TxtInput_KeyDown;

        }

        private void TxtInput_KeyDown(object sender, KeyEventArgs e)
        {
            var theKeyAsAString = e.IsDown.ToString();

            if (e.Key == Key.A)
            {
                Trace.WriteLine("Do Something 44");
            }

            if (e.Key == Key.Execute)
            {
                Trace.WriteLine("Do Something 29");
            }

            if (e.Key == Key.Snapshot)
            {
                Trace.WriteLine("Do Something 30");
            }
        }

        private void TxtInput_TextChanged(object sender, TextChangedEventArgs e)
        {
            var z = e.ToString();

            string t = sender.ToString();
        }

If I scan something with a hand scanner USB keyboard, which event do I get? KeyDown?

Background: The special characters like (char)29 are not transferred.

Does anyone have an idea?

Developer technologies Windows Presentation Foundation
0 comments No comments
{count} votes

Accepted answer
  1. Markus Freitag 3,791 Reputation points
    2020-10-19T05:58:22.07+00:00

    Hello,
    Thanks, looks good.
    33234--1111.png

    From time to time it depends however, for whatever reason.
    The representation is very good, see picture.

    The menu item is my scanner, right?
    It doesn't work via the clipboard or I use it wrong.
    Could you maybe write something, explain it?
    Thanks in advance.


2 additional answers

Sort by: Most helpful
  1. Andy ONeill 361 Reputation points
    2020-10-15T14:33:23.143+00:00

    I still think Previewtextinput

    Nobody is pressing any keys and textchanged happens after the textbox has interpreted input.
    So for example if you pressed the key combination for ß I think you'll get ß in textchanged. The set of keys you typed in previewtextinput.

    private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)  
    {  
        // Put a break point in and take a look at what you get in e  
    }  
    

    https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.textcompositioneventargs?view=netcore-3.1

    I think it'll likely fire multiple times but I don't have a scanner to hand to experiment.

    1 person found this answer helpful.

  2. gekka 12,206 Reputation points MVP Volunteer Moderator
    2020-10-16T09:07:16.757+00:00

    The following code replaces the control code with Unicode 0x2400 or later.

    <Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d" Title="MainWindow" Height="200" Width="600"
            FocusManager.FocusedElement="{Binding ElementName=textBox1,Mode=OneTime}">
        <DockPanel TextElement.FontSize="24" TextElement.FontFamily="Consolas" LastChildFill="False">
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="Test" Click="MenuItem_Click" />
            </Menu>
    
            <TextBox x:Name="textBox1" DockPanel.Dock="Top" Margin="10">
                <TextBox.CommandBindings>
                    <CommandBinding Command="{x:Static ApplicationCommands.Copy}"
                                    CanExecute="TextBox_Copy_CanExecute"
                                    Executed="TextBox_Copy_Executed"/>
    
                    <CommandBinding Command="{x:Static ApplicationCommands.Cut}"
                                    CanExecute="TextBox_Cut_CanExecute"
                                    Executed="TextBox_Cut_Executed"/>
    
                    <CommandBinding Command="{x:Static ApplicationCommands.Paste}"
                                    CanExecute="TextBox_Paste_CanExecute"
                                    Executed="TextBox_Paste_Executed"/>
                </TextBox.CommandBindings>
            </TextBox>
    
            <TextBox DockPanel.Dock="Top" Margin="10" />
        </DockPanel>
    </Window>
    
    
    namespace WpfApp1
    {
        using System;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Controls.Primitives;
        using System.Windows.Input;
        using System.Linq;
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                this.replace = new ReplaceControlChar(this);
            }
    
            private ReplaceControlChar replace;
    
            private void TextBox_Copy_CanExecute(object sender, CanExecuteRoutedEventArgs e) => replace.TextBox_Copy_CanExecute(sender, e);
            private void TextBox_Copy_Executed(object sender, ExecutedRoutedEventArgs e) => replace.TextBox_Copy_Executed(sender, e);
            private void TextBox_Paste_CanExecute(object sender, CanExecuteRoutedEventArgs e) => replace.TextBox_CutPaste_CanExecute(sender, e);
            private void TextBox_Paste_Executed(object sender, ExecutedRoutedEventArgs e) => replace.TextBox_Paste_Executed(sender, e);
            private void TextBox_Cut_CanExecute(object sender, CanExecuteRoutedEventArgs e) => replace.TextBox_CutPaste_CanExecute(sender, e);
            private void TextBox_Cut_Executed(object sender, ExecutedRoutedEventArgs e) => replace.TextBox_Cut_Executed(sender, e);
    
            private void MenuItem_Click(object sender, RoutedEventArgs e)
            {
                char EOT = '\u0004';
                char RS = '\u001e';
                char GS = '\u001d';
    
                if (FocusManager.GetFocusedElement(this) is TextBoxBase)
                {
                    Task.Run(() =>
                    {
                        System.Windows.Forms.SendKeys.SendWait("[{)}>"+ $"{ RS }06{ GS }17V98897{ GS }1P4L0014-163B{ GS }SSA10197{ RS }{ EOT }");
                    });
                }
            }
        }
    
        class ReplaceControlChar : System.Windows.Forms.NativeWindow
        {
            #region Replace
    
            private System.Windows.Window _Window;
    
            public bool Enable { get; set; } = true;
    
            public ReplaceControlChar(System.Windows.Window w)
            {
                this._Window = w;
    
                if (!w.IsLoaded)
                {
                    w.Loaded += (s, e) => Assign();
                }
                else
                {
                    Assign();
                }
            }
    
            private void Assign()
            {
                var hwnd = new System.Windows.Interop.WindowInteropHelper(_Window).Handle;
                var hs = System.Windows.Interop.HwndSource.FromHwnd(hwnd);
                this.AssignHandle(hwnd);
            }
    
            protected override void WndProc(ref System.Windows.Forms.Message m)
            {
                switch (m.Msg)
                {
                case 0x102://WM_CHAR
                    int ic = m.WParam.ToInt32();
    
                    System.Diagnostics.Debug.WriteLine(ic.ToString("X02"));
                    if (Enable && (0 <= ic && ic < 0x20))
                    {
                        if (FocusManager.GetFocusedElement(_Window) is TextBoxBase)
                        {
                            m.WParam = new IntPtr(ic + 0x2400);
                        }
                    }
                    break;
                }
                base.WndProc(ref m);
            }
            #endregion
    
            #region Copy / Cut / Paste
    
            public void TextBox_Copy_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                var txb = e.Source as TextBox;
                if (Enable && txb != null)
                {
                    e.CanExecute = true;
                    e.Handled = true;
                }
            }
    
            public void TextBox_CutPaste_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                var txb = e.Source as TextBox;
                if (Enable && txb != null && !txb.IsReadOnly)
                {
                    e.CanExecute = true;
                    e.Handled = true;
                }
            }
    
            public void TextBox_Copy_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                e.Handled = true;
                var txb = sender as TextBox;
    
                StringBuilder sb = new StringBuilder();
                string text = txb.SelectedText;
                if (text.Length > 0)
                {
                    text = new string(text.Select(c => (0x2400 <= c && c < 0x2420) ? (char)(c - 0x2400) : c).ToArray());
                }
                Clipboard.SetText(text);
            }
    
            public void TextBox_Cut_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                var txb = e.Source as TextBox;
                if (Enable && txb != null)
                {
                    TextBox_Copy_Executed(sender, e);
                    txb.SelectedText = "";
                }
            }
    
            public void TextBox_Paste_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                e.Handled = true;
                var txb = e.Source as TextBox;
    
                var d = Clipboard.GetDataObject();
                var text = Clipboard.GetText(TextDataFormat.UnicodeText);
                if (text.Length > 0)
                {
                    text = new string(text.Select(c => (00 <= c && c < 0x20) ? (char)(c + 0x2400) : c).ToArray());
                }
            }
            #endregion
        }
    }
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.