[MFC]区分USB扫码枪和键盘输入的实现
不久前在帮客户做一个生产软件,要用到扫码枪输入一定长度的条码并且有条码长度防呆,结果发现手头的扫码枪居然是模拟键盘输入将条码数据直接发送到焦点控件中的(USB口的扫码枪),比如Edit Control,而由于业务要求,不允许生产线上员工手工输入条码内容,因此我将文本框设为只读,想不到扫码枪也无法输入了。后面百度了一下,也没找到什么好的办法,不过得到了一个可以通过按键输入间隔来识别是否人工输入的思路。
基本思路如下:USB扫码枪将条码内容模拟键盘输入所用的时间在50ms以内,在PreTranslateMessage(MSG* pMsg)函数中增加对键盘信息处理,先记录第一次按键的时间,然后后续每次按键的时间与之作对比,超过了设置的时间阈值的话,就会把文本框的内容全选,下一次输入的文本会覆盖掉之前的。由于生产用的条码足够长,即使员工手工快速输入的内容也达不到长度,后续代码会对条码长度进行防呆。
代码示例如下:
public: virtual BOOL PreTranslateMessage(MSG* pMsg); BOOL m_bKeyFlag;//按键是否第一次按下 DWORD m_dwKeyDown;//记录第一次按键按下的时间
BOOL CDlgScan::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 if (pMsg->hwnd == GetDlgItem(IDC_EDIT_SCAN)->m_hWnd) { if (WM_KEYDOWN == pMsg->message) { if (!m_bKeyFlag)//记录第一次按键的时间,初始化为FALSE { m_bKeyFlag = TRUE; m_dwKeyDown = ::GetTickCount(); } else//把这次的按键时间与第一次的作对比 { if (::GetTickCount() - m_dwKeyDown > 50) { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_SCAN); pEdit->SetFocus(); pEdit->SetSel(0,-1); m_bKeyFlag = FALSE; return TRUE; } } } } return CDialog::PreTranslateMessage(pMsg); }
如果大家有什么更好的方法,可以一起讨论下