﻿#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
