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

本文介绍了一种在Windows环境下使用键盘钩子技术来捕捉条形码扫描器输入的方法,确保无论哪个应用程序处于活动状态,都能准确地捕获条形码数据。

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

实现思路:我用的是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

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值