VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 2463|回复: 2

[求助] C# Winform中无焦点状态下获取键盘输入或者USB扫描枪数据

[复制链接]
81_avatar_middle
在线会员 liangwei1362 发表于 2017-6-6 23:53:22 | 显示全部楼层 |阅读模式
最近在做个国外很火的项目,碰到一些问题,下面的代码老是报错,哪位有经验的大神帮我看看~

扫描器是优力科的MS3398下面是扫描器的参数API
http://www.posunitech.com/products_detail/productId=83.html
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. namespace Common
  7. {
  8.    public class BardCodeHooK
  9.    {
  10.        public delegate void BardCodeDeletegate(BarCodes barCode);
  11.        public event BardCodeDeletegate BarCodeEvent;
  12.        public struct BarCodes
  13.        {
  14.            public int VirtKey;//虚拟吗
  15.            public int ScanCode;//扫描码
  16.            public string KeyName;//键名
  17.            public uint Ascll;//Ascll
  18.            public char Chr;//字符
  19.            public string BarCode;//条码信息
  20.            public bool IsValid;//条码是否有效
  21.            public DateTime Time;//扫描时间
  22.        }
  23.        private struct EventMsg
  24.        {
  25.            public int message;
  26.            public int paramL;
  27.            public int paramH;
  28.            public int Time;
  29.            public int hwnd;
  30.        }
  31.        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  32.        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
  33.        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  34.        private static extern bool UnhookWindowsHookEx(int idHook);
  35.        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  36.        private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
  37.        [DllImport("user32", EntryPoint = "GetKeyNameText")]
  38.        private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize);
  39.        [DllImport("user32", EntryPoint = "GetKeyboardState")]
  40.        private static extern int GetKeyboardState(byte[] pbKeyState);
  41.        [DllImport("user32", EntryPoint = "ToAscii")]
  42.        private static extern bool ToAscii(int VirtualKey, int ScanCode, byte[] lpKeySate, ref uint lpChar, int uFlags);
  43.        delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
  44.        BarCodes barCode = new BarCodes();
  45.        int hKeyboardHook = 0;
  46.        string strBarCode = "";
  47.        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
  48.        {
  49.            if (nCode == 0)
  50.            {
  51.                EventMsg msg = (EventMsg)Marshal.PtrToStructure(lParam, typeof(EventMsg));
  52.                if (wParam == 0x100)//WM_KEYDOWN=0x100
  53.                {
  54.                    barCode.VirtKey = msg.message & 0xff;//虚拟吗
  55.                    barCode.ScanCode = msg.paramL & 0xff;//扫描码
  56.                    StringBuilder strKeyName = new StringBuilder(225);
  57.                    if (GetKeyNameText(barCode.ScanCode * 65536, strKeyName, 255) > 0)
  58.                    {
  59.                        barCode.KeyName = strKeyName.ToString().Trim(new char[] { ' ', '\0' });
  60.                    }
  61.                    else
  62.                    {
  63.                        barCode.KeyName = "";
  64.                    }
  65.                    byte[] kbArray = new byte[256];
  66.                    uint uKey = 0;
  67.                    GetKeyboardState(kbArray);
  68.                    if (ToAscii(barCode.VirtKey, barCode.ScanCode, kbArray, ref uKey, 0))
  69.                    {
  70.                        barCode.Ascll = uKey;
  71.                        barCode.Chr = Convert.ToChar(uKey);
  72.                    }
  73.                    TimeSpan ts = DateTime.Now.Subtract(barCode.Time);
  74.                    if (ts.TotalMilliseconds > 50)
  75.                    {
  76.                        strBarCode = barCode.Chr.ToString();
  77.                    }
  78.                    else
  79.                    {
  80.                        if ((msg.message & 0xff) == 13 && strBarCode.Length > 3)
  81.                        {
  82.                            barCode.BarCode = strBarCode;
  83.                            barCode.IsValid = true;
  84.                         }
  85.                         strBarCode += barCode.Chr.ToString();
  86.                     }
  87.                     barCode.Time = DateTime.Now;
  88.                     if (BarCodeEvent != null) BarCodeEvent(barCode);//触发事件
  89.                     barCode.IsValid = false;
  90.                 }
  91.             }
  92.             return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
  93.         }
  94.         //安装钩子
  95.         public bool Start()
  96.         {
  97.             if (hKeyboardHook == 0)
  98.             {
  99.                 //WH_KEYBOARD_LL=13
  100.                 hKeyboardHook = SetWindowsHookEx(13, new HookProc(KeyboardHookProc), Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
  101.             }
  102.             return (hKeyboardHook != 0);
  103.         }
  104.         //卸载钩子
  105.         public bool Stop()
  106.         {
  107.             if (hKeyboardHook != 0)
  108.             {
  109.                 return UnhookWindowsHookEx(hKeyboardHook);
  110.             }
  111.             return true;
  112.         }
  113.     }
  114. }
  115. 页面中用法:
  116. using System;
  117. using System.Collections.Generic;
  118. using System.ComponentModel;
  119. using System.Data;
  120. using System.Drawing;
  121. using System.Text;
  122. using System.Windows.Forms;
  123. namespace Common
  124. {
  125.     public partial class FrmMain : Form
  126.     {
  127.         BardCodeHooK BarCode = new BardCodeHooK();
  128.         public FrmMain()
  129.         {
  130.             InitializeComponent();
  131.             BarCode.BarCodeEvent += new BardCodeHooK.BardCodeDeletegate(BarCode_BarCodeEvent);
  132.         }
  133.         private delegate void ShowInfoDelegate(BardCodeHooK.BarCodes barCode);
  134.         private void ShowInfo(BardCodeHooK.BarCodes barCode)
  135.         {
  136.             if (this.InvokeRequired)
  137.             {
  138.                 this.BeginInvoke(new ShowInfoDelegate(ShowInfo), new object[] { barCode });
  139.             }
  140.             else
  141.             {
  142.                 textBox1.Text = barCode.KeyName;
  143.                 textBox2.Text = barCode.VirtKey.ToString();
  144.                 textBox3.Text = barCode.ScanCode.ToString();
  145.                 textBox4.Text = barCode.Ascll.ToString();
  146.                 textBox5.Text = barCode.Chr.ToString();
  147.                 textBox6.Text = barCode.IsValid? barCode.BarCode : "";//是否为扫描枪输入,如果为true则是 否则为键盘输入
  148.                 textBox7.Text += barCode.KeyName;
  149.                 //MessageBox.Show(barCode.IsValid.ToString());
  150.             }
  151.         }
  152.         //C#中判断扫描枪输入与键盘输入
  153.         //Private DateTime _dt = DateTime.Now;  //定义一个成员函数用于保存每次的时间点
  154.         //private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
  155.         //{
  156.         //    DateTime tempDt = DateTime.Now;          //保存按键按下时刻的时间点
  157.         //    TimeSpan ts = tempDt .Subtract(_dt);     //获取时间间隔
  158.         //    if (ts.Milliseconds > 50)                           //判断时间间隔,如果时间间隔大于50毫秒,则将TextBox清空
  159.         //        textBox1.Text = "";
  160.         //    dt = tempDt ;
  161.         //}
  162.         void BarCode_BarCodeEvent(BardCodeHooK.BarCodes barCode)
  163.         {
  164.             ShowInfo(barCode);
  165.         }
  166.         private void FrmMain_Load(object sender, EventArgs e)
  167.         {
  168.             BarCode.Start();
  169.         }
  170.         private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
  171.         {
  172.             BarCode.Stop();
  173.         }
  174.         private void textBox6_TextChanged(object sender, EventArgs e)
  175.         {
  176.             if (textBox6.Text.Length > 0)
  177.             {
  178.                 MessageBox.Show("条码长度:" + textBox6.Text.Length + "\n条码内容:" + textBox6.Text, "系统提示");
  179.             }
  180.         }
  181.     }
  182. }
复制代码





上一篇:opengl 如何降低刷新率?
下一篇:360安装启动界面的实现思路和细节(UI大神)

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

51_avatar_middle
online_admins Syc 发表于 2017-6-7 10:00:35 | 显示全部楼层
C# 的话,我是无能为力了。。。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

75_avatar_middle
在线会员 besteast 发表于 2017-6-16 21:14:07 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /1 下一条

QQ
QQ在线咨询
联系电话
13591366679
手机扫一扫 关注本站精彩内容
wxqrcode

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-11-16 12:19

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表