USB口的红外条形码扫描器的另类使用

本文介绍了一种在Windows环境下实现条形码扫描器数据自动捕获的方法。通过设置键盘钩子监听条形码扫描事件,无论应用程序是否有输入焦点,都能确保扫描的数据被正确读取并处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前的条形码扫描器有点类似外接键盘(其实从消息传送上它就相当于一个键盘),把输入焦点定位到可输入的控件上,一扫描相应的条形码信息就输入到文本框中去了,但是如果没有输入焦点,或另一个不相干的程序获得输入焦点,那就有点乱套了。我想实现的是,不管什么情况,只要扫描器一工作,我的程序就能自动激活,并能获得当前输入的条形码信息。

实现思路:我用的是litele牌的USB口的红外条形码扫描器,仔细分析了一下,扫描成功后,以键盘按键消息的形式把条形码输入信息通知给系统。这样通过键盘钩子就可以方便的获得该信息了。但是,怎样区分信息是键盘还是条形码输入的哪?

很简单,条形码扫描器在很短的时间内输入了至少3个字符以上信息,并且以“回车”作为结束字符,在这种思想指引下,很完美的实现了预定功能。

以下程序要在Win2000/Win XP 下才能运行成功。

form1 中的代码:

'*************************************************************************
'
**模块名:frmDemo
'
**说明:YFsoft版权所有2006-2007(C)
'
**创建人:叶帆http://blog.youkuaiyun.com/yefanqiu
'
**日期:2006-08-3014:55:56
'
**修改人:
'
**日期:
'
**描述:
'
**版本:V1.0.0
'
*************************************************************************
OptionExplicit

PrivateSubForm_Load()
SetHook
EndSub

PrivateSubForm_Unload(CancelAsInteger)
UnHook
EndSub

PrivateSubtmrScan_Timer()
DimstrBarCodeAsString
strBarCode
=GetBarCode
IfLen(strBarCode)>0Then
MsgBox"条形码:"&strBarCode
EndIf
EndSub

模块中的代码:

'*************************************************************************
'
**模块名:basBarCode
'
**说明:YFsoft版权所有2006-2007(C)
'
**创建人:叶帆http://blog.youkuaiyun.com/yefanqiu
'
**日期:2006-08-3015:02:29
'
**修改人:
'
**日期:
'
**描述:获取条形码数据
'
**版本:V1.0.0
'
*************************************************************************
OptionExplicit

PrivateTypeKeyboardBytes
kbByte(
0To255)AsByte
EndType
DimkbArrayAsKeyboardBytes

PrivateDeclareFunctionGetKeyboardStateLib"user32"(pbKeyStateAsKeyboardBytes)AsLong
PrivateDeclareFunctionToAsciiLib"user32"(ByValuVirtKeyAsLong,ByValuScanCodeAsLong,lpbKeyStateAsKeyboardBytes,lpwTransKeyAsLong,ByValfuStateAsLong)AsLong

PrivateDeclareFunctionCallNextHookExLib"user32"(ByValhHookAsLong,ByValncodeAsLong,ByValwParamAsLong,lParamAsAny)AsLong
PrivateDeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(lpvDestAsAny,ByVallpvSourceAsLong,ByValcbCopyAsLong)
PrivateDeclareFunctionGetKeyNameTextLib"user32"Alias"GetKeyNameTextA"(ByVallParamAsLong,ByVallpBufferAsString,ByValnSizeAsLong)AsLong

PrivateTypeEVENTMSG
message
AsLong
paramL
AsLong
paramH
AsLong
Time
AsLong
hwnd
AsLong
EndType

PrivateTypeBARCODES
VirtKey
AsLong'虚拟码
ScanCodeAsLong'扫描码
KeyNameAsString'键的名称
AscIIAsLong'AscII
ChrAsString'字符

BarCode
AsString'扫描码信息
TimeAsDate'扫描时间
bGetFlagAsBoolean'是否已获取扫描码
EndType

PrivateDeclareFunctionSetWindowsHookExLib"user32"Alias"SetWindowsHookExA"(ByValidHookAsLong,ByVallpfnAsLong,ByValhmodAsLong,ByValdwThreadIdAsLong)AsLong
PrivateDeclareFunctionUnhookWindowsHookExLib"user32"(ByValhHookAsLong)AsLong
PrivateDeclareFunctionGetCurrentTimeLib"kernel32"Alias"GetTickCount"()AsLong

PrivateConstWH_KEYBOARD_LL=13
Privatem_lHookAsLong
Publicg_BarCodeAsBARCODES

'*************************************************************************
'
**函数名:SetHook/UnHook
'
**输入:无
'
**输出:无
'
**功能描述:装卸钩子
'
**全局变量:
'
**调用模块:
'
**作者:叶帆
'
**日期:2006-08-3015:11:37
'
**修改人:
'
**日期:
'
**版本:V1.0.0
'
*************************************************************************
PublicSubSetHook()
m_lHook
=SetWindowsHookEx(WH_KEYBOARD_LL,AddressOfCallHookProc,App.hInstance,0)
EndSub

PublicSubUnHook()
Ifm_lHook<>0Then
UnhookWindowsHookExm_lHook
EndIf
EndSub

'*************************************************************************
'
**函数名:GetBarCode
'
**输入:无
'
**输出:(String)-
'
**功能描述:获取扫描码
'
**全局变量:
'
**调用模块:
'
**作者:叶帆
'
**日期:2006-08-3016:46:04
'
**修改人:
'
**日期:
'
**版本:V1.0.0
'
*************************************************************************
PublicFunctionGetBarCode()AsString
Ifg_BarCode.bGetFlag=TrueThen
g_BarCode.bGetFlag
=False
GetBarCode
=g_BarCode.BarCode
Else
GetBarCode
=""
EndIf
EndFunction

'*************************************************************************
'
**函数名:CallHookProc
'
**输入:ByValcode(Long)-
'
**:ByValwParam(Long)-
'
**:ByVallParam(Long)-
'
**输出:(Long)-
'
**功能描述:
'
**全局变量:
'
**调用模块:
'
**作者:叶帆
'
**日期:2006-08-3015:03:47
'
**修改人:
'
**日期:
'
**版本:V1.0.0
'
*************************************************************************
PrivateFunctionCallHookProc(ByValcodeAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong
DimmsgAsEVENTMSG
DimstrKeyNameAsString
DimlngKeyAsLong
StaticlngTimeAsLong
StaticstrBarCodeAsString

Ifcode=0Then
CopyMemorymsg,lParam,LenB(msg)
IfwParam=&H100Then'WM_KEYDOWN
g_BarCode.VirtKey=msg.messageAnd&HFF'虚拟码
g_BarCode.ScanCode=msg.paramLAnd&HFF'扫描码

strKeyName
=Space(255)
IfGetKeyNameText(g_BarCode.ScanCode*65536,strKeyName,255)>0Then'键名
g_BarCode.KeyName=Trim(strKeyName)
Else
g_BarCode.KeyName
=""
EndIf

'---------------------------------------
CallGetKeyboardState(kbArray)
IfToAscii(g_BarCode.VirtKey,g_BarCode.ScanCode,kbArray,lngKey,0)>0Then
g_BarCode.AscII
=lngKey
g_BarCode.Chr
=Chr(lngKey)
EndIf

'--------------------
IfAbs(GetCurrentTime-lngTime)>50Then
strBarCode
=g_BarCode.Chr
Else
If(msg.messageAnd&HFF)=13AndLen(strBarCode)>3Then'回车
g_BarCode.BarCode=strBarCode
g_BarCode.Time
=Now
g_BarCode.bGetFlag
=True
EndIf
strBarCode
=strBarCode&g_BarCode.Chr
EndIf
lngTime
=GetCurrentTime
'---------------------------------------
'测试代码
CallShowKeyInfo
'---------------------------------------
EndIf

EndIf

CallHookProc
=CallNextHookEx(m_lHook,code,wParam,lParam)
EndFunction

'显示调试信息
PublicSubShowKeyInfo()
frmDemo.txtKey(
0)=g_BarCode.KeyName
frmDemo.txtKey(
1)=g_BarCode.VirtKey
frmDemo.txtKey(
2)=g_BarCode.ScanCode

frmDemo.txtKey(
3)=g_BarCode.AscII
frmDemo.txtKey(
4)=g_BarCode.Chr
frmDemo.txtBarCode
=g_BarCode.BarCode

frmDemo.lblTime
=g_BarCode.Time
EndSub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值