USB口的条形码扫描器接口编程(VB) 转

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

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

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

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

 

form1 中的代码:

'*************************************************************************

Option Explicit

Private Sub Form_Load()
   SetHook
End Sub

Private Sub Form_Unload(Cancel As Integer)
   UnHook
End Sub

Private Sub tmrScan_Timer()
    Dim strBarCode As String
    strBarCode = GetBarCode
    If Len(strBarCode) > 0 Then
        MsgBox "条形码:" & strBarCode
    End If
End Sub
模块中的代码:

'*************************************************************************
'**模 块 名:basBarCode
'**描    述:获取条形码数据
'**版    本:V1.0.0
'*************************************************************************
Option Explicit

Private Type KeyboardBytes
    kbByte(0 To 255) As Byte
End Type
Dim kbArray As KeyboardBytes

Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As KeyboardBytes) As Long
Private Declare Function ToAscii Lib "user32" (ByVal uVirtKey As Long, ByVal uScanCode As Long, lpbKeyState As KeyboardBytes, lpwTransKey As Long, ByVal fuState As Long) As Long

Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, ByVal lpvSource As Long, ByVal cbCopy As Long)
Private Declare Function GetKeyNameText Lib "user32" Alias "GetKeyNameTextA" (ByVal lParam As Long, ByVal lpBuffer As String, ByVal nSize As Long) As Long

Private Type EVENTMSG
    message As Long
    paramL As Long
    paramH As Long
    Time As Long
    hwnd As Long
End Type

Private Type BARCODES
    VirtKey As Long         '虚拟码
    ScanCode As Long           '扫描码
    KeyName As String       '键的名称
    AscII As Long           'AscII
    Chr As String           '字符
   
    BarCode As String      '扫描码信息
    Time As Date            '扫描时间
    bGetFlag As Boolean     '是否已获取扫描码
End Type

Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function GetCurrentTime Lib "kernel32" Alias "GetTickCount" () As Long

Private Const WH_KEYBOARD_LL = 13
Private m_lHook As Long
Public g_BarCode As BARCODES

'*************************************************************************
'**函 数 名:SetHook / UnHook
'**输    入:无
'**输    出:无
'**功能描述:装卸钩子
'**全局变量:
'**调用模块:
'**版    本:V1.0.0
'*************************************************************************
Public Sub SetHook()
    m_lHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf CallHookProc, App.hInstance, 0)
End Sub

Public Sub UnHook()
    If m_lHook <> 0 Then
        UnhookWindowsHookEx m_lHook
    End If
End Sub

'*************************************************************************
'**函 数 名:GetBarCode
'**输    入:无
'**输    出:(String) -
'**功能描述:获取扫描码
'**全局变量:
'**调用模块:
'**版    本:V1.0.0
'*************************************************************************
Public Function GetBarCode() As String
    If g_BarCode.bGetFlag = True Then
        g_BarCode.bGetFlag = False
        GetBarCode = g_BarCode.BarCode
    Else
        GetBarCode = ""
    End If
End Function

'*************************************************************************
'**函 数 名:CallHookProc
'**输    入:ByVal code(Long)   -
'**        :ByVal wParam(Long) -
'**        :ByVal lParam(Long) -
'**输    出:(Long) -
'**功能描述:
'**全局变量:
'**调用模块:
'**版    本:V1.0.0
'*************************************************************************
Private Function CallHookProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim msg As EVENTMSG
    Dim strKeyName As String
    Dim lngKey As Long
    Static lngTime As Long
    Static strBarCode As String

If code = 0 Then
        CopyMemory msg, lParam, LenB(msg)
        If wParam = &H100 Then   'WM_KEYDOWN
            g_BarCode.VirtKey = msg.message And &HFF           '虚拟码
            g_BarCode.ScanCode = msg.paramL And &HFF              '扫描码
           
            strKeyName = Space(255)
            If GetKeyNameText(g_BarCode.ScanCode * 65536, strKeyName, 255) > 0 Then  '键名
                g_BarCode.KeyName = Trim(strKeyName)
            Else
                g_BarCode.KeyName = ""
            End If

'---------------------------------------
            Call GetKeyboardState(kbArray)
            If ToAscii(g_BarCode.VirtKey, g_BarCode.ScanCode, kbArray, lngKey, 0) > 0 Then
                g_BarCode.AscII = lngKey
                g_BarCode.Chr = Chr(lngKey)
            End If

'--------------------
            If Abs(GetCurrentTime - lngTime) > 50 Then
                strBarCode = g_BarCode.Chr
            Else
                If (msg.message And &HFF) = 13 And Len(strBarCode) > 3 Then '回车
                    g_BarCode.BarCode = strBarCode
                    g_BarCode.Time = Now
                    g_BarCode.bGetFlag = True
                End If
                strBarCode = strBarCode & g_BarCode.Chr
            End If
            lngTime = GetCurrentTime
            '---------------------------------------
            '测试代码
            ’Call ShowKeyInfo
            '---------------------------------------
        End If

End If

CallHookProc = CallNextHookEx(m_lHook, code, wParam, lParam)
End Function

'显示调试信息
Public Sub ShowKeyInfo()
    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
   

posted @ 2015-06-30 23:34  海蟹  阅读(836)  评论(0编辑  收藏  举报