我的任务是从Symbol LS2208条形码扫描仪读取条形码 扫描仪设置为deafult但前缀为F13,并且输入'输入'。使用此扫描仪模拟美国键盘。我的键盘是丹麦语,操作系统语言设置为丹麦语 我喜欢独立于用户区域设置。
现在我正在使用:
实现IMessageFilter private const int WM_KEYDOWN = 0x100;
private List<Keys> keysSequence = new List<Keys>();
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;
if (keyCode == Keys.F13)
{
...
return true;
}
if (keyCode == Keys.Enter)
{
...
string barcode = GenerateBarcode(keysSequence);
return true;
}
keysSequence.Add(keyCode);
}
}
当周围的&#39;输入&#39; key是接收到的键序列,用于使用方法GenerateBarcode
创建条形码字符串:
public static string GenerateBarcode(Keys[] captureKeysSequence)
{
StringBuilder barcodeBuffer = new StringBuilder();
bool shift = false;
bool altGr = false;
foreach (Keys keyCode in captureKeysSequence)
{
if (keyCode == Keys.Shift || keyCode == Keys.ShiftKey)
{
shift = true;
continue;
}
if (keyCode == (Keys.Control | Keys.Alt))
{
altGr = true;
continue;
}
barcodeBuffer.Append(GetCharsFromKeys(keyCode, shift, altGr));
shift = false;
altGr = false;
}
return barcodeBuffer.ToString();
}
我在这里处理shift和altGr键。
GetCharsFromKeys
方法现在出现问题:
[DllImport("user32.dll")]
public static extern int ToUnicodeEx(uint virtualKeyCode, uint scanCode,
byte[] keyboardState,
[Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)]
StringBuilder receivingBuffer,
int bufferSize, uint flags, IntPtr dwhkl);
public static string GetCharsFromKeys(Keys keys, bool shift, bool altGr)
{
var buf = new StringBuilder(256);
var keyboardState = new byte[256];
if (shift)
keyboardState[(int)Keys.ShiftKey] = 0xff;
if (altGr)
{
keyboardState[(int)Keys.ControlKey] = 0xff;
keyboardState[(int)Keys.Menu] = 0xff;
}
// Because the Symbol LS2208 maps a US keyboard we need to convert the Keys correctly to chars
ToUnicodeEx((uint)keys, 0, keyboardState, buf, buf.Capacity, 0, InputLanguage.FromCulture(new System.Globalization.CultureInfo("en-US")).Handle);
return buf.ToString();
}
我正在尝试将条形码扫描仪的Keys输入转换为字符串。对于大多数常见的字符,这是很好地工作(包括低位和高位字符和数字)以及键盘上数字上方的一些特殊字符正在工作(例如,&#39; $&#39;)。
但是当用条形码进行测试时,例如&#34; 12/34 - 56&#34;我最终得到了输出&#34; 12 - 34 = 56&#34;?
我认为它与美国和丹麦键盘之间的映射有关,但我无法弄清楚为什么?
有人可以帮助我进行这种转换吗?
答案 0 :(得分:0)
我无法按照我想要的方式解决这个问题:
“通过使用条形码扫描仪设置来使用美式键盘,并接收所设置的Windows区域键盘设置的独立字符。”
所以我不得不将我的要求限制在:
“条形码扫描仪和Windows必须具有相同的键盘设置。”
这使一切变得如此简单。我仍然实现IMessageFilter并同时使用VM_KEYDOWN和VM_MSG。这是我使用的代码(但仍然缺少一些错误/超时处理):
public class BarcodeScannerMessageFilter : IMessageFilter
{
public event EventHandler<BarcodeScannerReadyEventArgs> BarcodeScannerReady;
private bool barcodeStarted = false;
private StringBuilder barcodeBuilder = new StringBuilder();
public BarcodeScannerMessageFilter()
{
Application.AddMessageFilter(this);
}
#region IMessageFilter Members
private const int WM_KEYDOWN = 0x100;
private const int WM_MSG = 0x102;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_KEYDOWN) // Use KeyDown to look for prefix and surfix
{
Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;
if (!barcodeStarted) // Prevent F13 Capture until previous is ended
{
// Check for start capture key (F13)
if (keyCode == Keys.F13)
{
barcodeStarted = true;
return true;
}
}
else
{
// Check for end capture key (Enter)
if (keyCode == Keys.Enter)
{
// Raise barcode capture event with barcode
RaiseBarcodeReadyEventAsync(barcodeBuilder.ToString());
// End sequence
barcodeBuilder.Clear();
barcodeStarted = false;
return true;
}
}
}
else if (m.Msg == WM_MSG) // Catch all char messages
{
char c = (char)m.WParam;
// Else just append char to barcodeBuilder to generate barcode
barcodeBuilder.Append(c);
return true;
}
return false;
}
#endregion
private void RaiseBarcodeReadyEventAsync(string barcode)
{
Task.Factory.StartNew(() =>
{
try
{
// Generate barcode
Console.WriteLine("F13 activated barcode [" + barcode + "]");
if (BarcodeScannerReady != null)
{
BarcodeScannerReady(this, new BarcodeScannerReadyEventArgs(barcode));
}
}
catch (Exception ex)
{
// Do some error logging if needed
Console.WriteLine(ex);
}
});
}
}
public class BarcodeScannerReadyEventArgs : EventArgs
{
public string Barcode { get; private set; }
public BarcodeScannerReadyEventArgs(string barcode)
{
this.Barcode = barcode;
}
}
我希望这可以帮助其他人在解决像我这样的问题。