Damit man das Script leichter findet, mache ich mal ein extra Thema dafür auf.
Problem:
Wenn man einen Barcode-Scanner besitzt, der eine Tastaureingabe emuliert und man zusätzlich aber auch ein oder mehrere Eingabefelder für andere Daten haben will, so ist es schwierig die Eingabe von Barcode-Scanner nur in dem dafür vorgesehenen Eingabefeld einzutragen. Normalerweise wird der Barcode einfach als Tastatureingabe gesendet und landet somit in dem Eingabefeld, das gerade den Eingabefokus besitzt.
Lösung:
Es gibt eine Möglichkeit, die Eingabe vom Barcode-Scanner zu erkennen. Dafür muss man das InputDevice registrieren (der DeviceName dient dabei der Unterscheidung).
Mein Script habe ich ausführlich kommentiert, sodass hoffentlich verständlich wird, wie man sein eigenes Script anpassen muss, um diese Lösung verwenden zu können.
#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
; In der Variablen "$g_sDevName" sollte der DeviceName von eurem Barcode-Scanner drinstehen.
; Wenn nach Scriptstart der Barcode-Scanner benutzt wird, steht der DeviceName im unteren Feld.
; Mit dem Button [Copy] kann man den DeviceName benutzen und in die Zwischenablage kopieren, um ihn dann hier einzufuegen.
Global $g_sDevName = '' ; z.B. '\\?\HID#VID_13BA&PID_0018#6&238b7016&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}'
; Hier den Postfix-Code von eurem Scanner eintragen. Bei meinem Scanner ist das @CR = 0x0D (Hex).
Global $g_iPostfix = 0x0D
#Region *** Ein Fenster fuer den Scanner-Test erstellen ***
Global $g_hGui = GUICreate('Barcode-Scanner Test', 640, 130)
GUISetBkColor(0xBBBBBB)
GUICtrlCreateGroup('Barcode', 5, 5, 290, 50)
Global $g_idLabel = GUICtrlCreateLabel('', 15, 20, 270, 26, $SS_CENTER) ; fuer die Ausgabe vom Barcode-Scanner
GUICtrlSetFont(-1, 18, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xAAFFEE)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup('Tastatur', 345, 5, 290, 50)
Global $g_idInput = GUICtrlCreateInput('', 355, 20, 270, 26) ; ein Input, fuer eine Eingabe von der Tastatur
GUICtrlSetFont(-1, 14, 400, 0, 'Arial')
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup('DeviceName', 5, 80, 630, 42)
Global $g_idDevName = GUICtrlCreateLabel('', 15, 95, 560, 18, $SS_CENTER)
GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xEEEEEE)
Global $g_idCopy2Clip = GUICtrlCreateButton('Copy', 580, 90, 50, 28)
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
GUICtrlSetTip(-1, 'Benutze diesen DeviceName und' & @CRLF & 'kopiere ihn in die Zwischenablage.')
GUICtrlCreateGroup('', -99, -99, 1, 1)
#EndRegion *** Ein Fenster fuer den Scanner-Test erstellen ***
#Region *** das InputDevice registrieren ***
Global $tRID = DllStructCreate($tagRAWINPUTDEVICE)
$tRID.UsagePage = 0x01
$tRID.Usage = 0x06
$tRID.Flags = $RIDEV_INPUTSINK
$tRID.hTarget = $g_hGui
_WinAPI_RegisterRawInputDevices($tRID)
GUIRegisterMsg($WM_INPUT, 'WM_INPUT')
#EndRegion *** das InputDevice registrieren ***
GUISetState(@SW_SHOW, $g_hGui)
GUICtrlSetState($g_idInput, $GUI_FOCUS)
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $g_idCopy2Clip
$g_sDevName = GUICtrlRead($g_idDevName)
ClipPut($g_sDevName)
GUICtrlSetData($g_idInput, '')
GUICtrlSetState($g_idInput, $GUI_FOCUS)
GUICtrlSetBkColor($g_idDevName, 0xCCFFCC)
Sleep(500)
GUICtrlSetBkColor($g_idDevName, 0xEEEEEE)
EndSwitch
WEnd
Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local Static $sBuffer = ''
Local $tRIM, $tDevInfo
$tRIM = DllStructCreate($tagRAWINPUTHEADER)
If Not _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) Then Return
$tDevInfo = DllStructCreate('wchar name[256]')
If Not _WinAPI_GetRawInputDeviceInfo($tRIM.hDevice, $tDevInfo, 256, $RIDI_DEVICENAME) Then Return
GUICtrlSetData($g_idDevName, $tDevInfo.name)
If $tDevInfo.name = $g_sDevName Then ; hier wird getestet, ob die Eingabe vom Barcode-Scanner kommt
If $tRIM.Type = $RIM_TYPEKEYBOARD Then ; sicherstellen, dass eine Tastatur-Emulation erfolgt
$tRIM = DllStructCreate($tagRAWINPUTKEYBOARD)
If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then
Switch $tRIM.Message
Case $WM_KEYDOWN
If $tRIM.VKey = $g_iPostfix Then ; wenn der Postfix gesendet wurde (evtl. oben anpassen)
; steht hier der gesendete Barcode in der Variablen $sBuffer.
; Hier kann man $sBuffer an eine globale Variable uebergeben und/oder
GUICtrlSetData($g_idLabel, $sBuffer) ; im Label anzeigen lassen.
$sBuffer = '' ; Buffer leeeren, fuer naechsten Code
ConsoleWrite('--- New Code ---' & @CRLF) ; nur zum debuggen
Else ; alle anderen Zeichen werden in $sBuffer uebernommen
$sBuffer &= Chr($tRIM.VKey)
ConsoleWrite('Char: ' & Chr($tRIM.VKey) & @CRLF) ; nur zum debuggen
EndIf
EndSwitch
_ClearKeyBuffer() ; die Eingabe vom Barcode-Scanner aus dem Msg-Queue loeschen
EndIf
EndIf
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_INPUT
Func _ClearKeyBuffer()
Local Const $tagMSG = 'hwnd hwnd;uint message;wparam wParam;lparam lParam;dword time;long X;long Y;dword lPrivate'
Local Const $PM_REMOVE = 0x0001
Local $tMsg = DllStructCreate($tagMSG), $ret
Do
$ret = DllCall('user32.dll', 'bool', 'PeekMessageW', _
'struct*', $tMsg, _
'hwnd', $g_hGui, _
'uint', $WM_KEYFIRST, _
'uint', $WM_KEYLAST, _
'uint', $PM_REMOVE)
Until $tMsg.message = 0x0101 Or $tMsg.message = 0
EndFunc ;==>_ClearKeyBuffer
Alles anzeigen