5

我有一个带有数据网格的 WPF 窗口。我试图从符号扫描仪中捕获通过虚拟楔形发送的字符串。对于应用程序,它看起来像是输入了字符。此字符串以 ASCII 1 (SOH) 开头。

当窗口具有焦点时,窗口的 PreviewTextInput 会接收 SOH 以及所有其他人类可读和非人类可读的值。 但是,当数据网格具有焦点时,非人类可读的字符将被剥离。

如果我在窗口上有一个 PreviewKeyDown 或 PreviewKeyUp ,那么无论什么有焦点,字符都会正确显示。因此,数据网格在某处将其剥离。不幸的是,因为 KeyDown/KeyUp 不显示 ASCII 字符,所以我不能使用这些事件,而不必编写某种解析算法。

谁能告诉我我能做些什么来让那些非人类可读的控制字符总是被发送到 PreviewTextInput?或者如何解析 PreviewKeyDown 中的所有字符?

编辑:

当窗口有焦点时:

Window PreviewKeyDown - LeftCtrl
Window PreviewKeyDown - A
Window PreviewTextInput - <SOH>
Window PreviewKeyDown - Oem6
Window PreviewTextInput - ]
Window PreviewKeyDown - LeftShift
Window PreviewKeyDown - C
Window PreviewTextInput - C

当数据网格具有焦点时:

Window PreviewKeyDown - LeftCtrl
DataGrid PreviewKeyDown - LeftCtrl
Window PreviewKeyDown - A
DataGrid PreviewKeyDown - A
Window PreviewKeyDown - Oem6
DataGrid PreviewKeyDown - Oem6
Window PreviewTextInput - ]
Window PreviewKeyDown - LeftShift
DataGrid PreviewKeyDown - LeftShift
Window PreviewKeyDown - C
DataGrid PreviewKeyDown - C
Window PreviewTextInput - C
4

1 回答 1

1

好吧,我知道这可能不是您所期望的,但我有一些为某些 Symbol 条形码扫描仪编写软件的经验。在一个应用程序中,我们让用户扫描他们的徽章以验证自己以覆盖某些条件。我们希望用户“扫描”他们的徽章,而不能用键盘输入数字。我记得我们花了很长时间试图弄清楚如何使输入不像键盘输入那样输入。我相信我们能够扫描 Symbol 条码扫描仪手册中的一些配置代码,将其配置为 USB 设备,我们可以根据需要打开并处理其输入。这种方法对我们来说要好得多。

你有没有考虑过尝试这样的事情?

MSDN 论坛上的这篇文章似乎是相关的(将密钥转换为 ASCII

条码阅读器通常可以在两种模式下运行。一种是它充当键盘楔子,就像用户键入代码一样生成击键。另一种是应用程序直接接收扫描的代码,通常是通过串行端口。您已将阅读器切换到一种模式,它会生成适合后一种方式的代码。Ctrl+B 是一个控制代码,SOH (Start Of Header)。它用于使程序与阅读器同步,SOH 表示扫描的开始,您将使用它来重置缓冲区索引。

您需要将阅读器配置为不会生成控制字符的键盘楔形模式。如果需要,您仍然可以通过编写一个 KeyDown 事件处理程序来检测 SOH 和一个 KeyPressed 事件处理程序来检测扫描代码,从而使其工作。避免尝试将您在 KeyDown 中看到的击键转换为字符,KeyPressed 已经为您完成了这项工作。

我相信这可能对您转换为 ASCII 有用:

[DllImport("user32.dll")]
    static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, byte[] arr, uint uFlags, IntPtr hkl);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetKeyboardState(byte[] lpKeyState);


    private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        byte[] keyboardState = new byte[256];
        int keyCode = KeyInterop.VirtualKeyFromKey(e.Key);
        byte[] arr = new byte[4];
        GetKeyboardState(keyboardState );
        Debug.WriteLineIf(ToAsciiEx((uint)keyCode, 0, keyboardState, arr, 0, IntPtr.Zero) > 0, ASCIIEncoding.ASCII.GetString(arr));
    }
于 2012-10-16T03:21:05.127 回答