Dies hilft wahrscheinlich auch nicht weiter, aber zumindest für unsere Nim Freunde ist was dabei :
Keyboard input/Flush the keyboard buffer - Rosetta Code
Library: POSIX
Dies hilft wahrscheinlich auch nicht weiter, aber zumindest für unsere Nim Freunde ist was dabei :
Keyboard input/Flush the keyboard buffer - Rosetta Code
Library: POSIX
ich habe nicht alles durchgelesen :I
aber habe etwas ähnliches gemacht,
GUI -> Felder die ausgefüllt werden müssen -> Inputfeld wird aktiv -> fürs scannen wird Inputfeld anvisiert -> Nun Scannt der Nutzer erst ... nachdem Inputfeld beschrieben ist mach das nächste feld frei und so weiter.
Wenn du das auch so ähnlich machen möchtest und den Inhalt dabei nicht sehen möchtest dann mach doch aus dem Inputfeld ein @ES_Password.
Um damit dann weiter zu arbeiten könntest du den Wert einfach auslesen und in einer Variable speichern, ohne ihn anschauen zu müssen.
@Edit.. du wolltest ja kein inputbox anzeigen lassen sry ...
So, noch etwas konstruktives!
Ich konnte den Msg-Queue von der Scanner-Eingabe "befreien", somit braucht man kein Dummy-Input mehr:
#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
; hier muss der DeviceName von eurem Scanner drinstehen
; beim auskommentieren von Zeile 41 wird der DeviceName beim scannen angezeigt.
Global $g_sDevName = '\\?\HID#VID_13BA&PID_0018#6&238b7016&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}'
Global $g_hGui = GUICreate('BarcodeScanner', 300, 120)
Global $g_idLabel = GUICtrlCreateLabel('', 5, 5, 290, 30) ; fuer die Ausgabe vom Barcode-Scanner
GUICtrlSetFont(-1, 16)
Global $g_idInput = GUICtrlCreateInput('', 5, 40, 290, 30) ; zum testen ein Input, fuer eine Eingabe von der Tastatur
GUICtrlSetFont(-1, 16)
Local $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')
GUISetState(@SW_SHOW)
GUICtrlSetState($g_idInput, $GUI_FOCUS)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local Static $sBuffer = ''
Local $devType, $devName, $tRIM, $tText
$tRIM = DllStructCreate($tagRAWINPUTHEADER)
If Not _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) Then Return
$devType = $tRIM.Type
$tText = DllStructCreate('wchar data[256]')
If Not _WinAPI_GetRawInputDeviceInfo($tRIM.hDevice, $tText, 256, $RIDI_DEVICENAME) Then Return
$devName = $tText.data
;~ ConsoleWrite(StringFormat("DevName: '%s'\r\n", $devName))
If $devName = $g_sDevName Then ; hier wird getestet, ob die Eingabe vom Barcode-Scanner kommt
If $devType = $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 = 13 Then ; wenn VKey = 13 (@CR) wird bei meinem Barcode-Scanner als Postfix gesendet (evtl. anpassen)
GUICtrlSetData($g_idLabel, $sBuffer) ; Buffer im Label anzeigen
$sBuffer = '' ; Buffer leeeren, fuer naechsten Code
ConsoleWrite('--- New Code ---' & @CRLF) ; nur zum debuggen
Else ; alle anderen Zeichen werden in den Buffer 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', 'PeekMessage', 'struct*', $tMsg, 'hwnd', $g_hGui, 'uint', $WM_KEYFIRST, 'uint', $WM_KEYLAST, 'uint', $PM_REMOVE)[0]
Until $tMsg.message = 0x0101 Or $tMsg.message = 0
EndFunc
Alles anzeigen
Oscar
Also ich habe den DeviceName \\?\HID#VID_04B4&PID_0100#7&1dd93500&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}, also ein anderer als Du ihn hast.
Aber ich brauche dqa nichts änderen, das läuft auch ohne das ich den DeviceName abändere.
Aber ich brauche dqa nichts änderen, das läuft auch ohne das ich den DeviceName abändere.
Jein!
Wenn Du da nicht den richtigen Devicenamen einträgst, dann wird der Barcode im Input angezeigt (was ein Zeichen dafür ist, dass die Funktion den Code nicht bearbeitet hat, sieh mal in die Consolenausgabe).
Der Barcode soll aber oben im Label angezeigt werden. Das Input-Control dient nur dazu, aufzuzeigen, dass gleichzeitig auch noch eine Eingabe von Tastatur möglich ist.
Oscar
Habe mein meinen DeviceName eingebe.
Beispiel 3x direkt nacheinander mein EDV-Lieblingsbuch eingescannt:
9783836235075
9783836235075
9783836235075
Sieht super aus. DANKE, kann ich bestimmt auch mal gebrauchen und lager ich mal ein.
Hallo Oscar ,
danke für deinen Code, die Funktionsweise entspricht auch dem was ich benötige, aber ich bekomme einfach die InputBox da nicht raus, kannst du mir da noch einen Tipp geben ?
aber ich bekomme einfach die InputBox da nicht raus, kannst du mir da noch einen Tipp geben ?
Was ist denn so schwer daran, etwas aus dem Script zu löschen?
#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
; hier muss der DeviceName von eurem Scanner drinstehen
; beim auskommentieren von Zeile 41 wird der DeviceName beim scannen angezeigt.
Global $g_sDevName = '\\?\HID#VID_13BA&PID_0018#6&238b7016&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}'
Global $g_hGui = GUICreate('BarcodeScanner', 300, 120)
Global $g_idLabel = GUICtrlCreateLabel('', 5, 5, 290, 30, $SS_CENTER) ; fuer die Ausgabe vom Barcode-Scanner
GUICtrlSetFont(-1, 16)
Local $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')
GUISetState(@SW_SHOW)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local Static $sBuffer = ''
Local $devType, $devName, $tRIM, $tText
$tRIM = DllStructCreate($tagRAWINPUTHEADER)
If Not _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) Then Return
$devType = $tRIM.Type
$tText = DllStructCreate('wchar data[256]')
If Not _WinAPI_GetRawInputDeviceInfo($tRIM.hDevice, $tText, 256, $RIDI_DEVICENAME) Then Return
$devName = $tText.data
;~ ConsoleWrite(StringFormat("DevName: '%s'\r\n", $devName))
If $devName = $g_sDevName Then ; hier wird getestet, ob die Eingabe vom Barcode-Scanner kommt
If $devType = $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 = 13 Then ; wenn VKey = 13 (@CR) wird bei meinem Barcode-Scanner als Postfix gesendet (evtl. anpassen)
GUICtrlSetData($g_idLabel, $sBuffer) ; Buffer im Label anzeigen
$sBuffer = '' ; Buffer leeeren, fuer naechsten Code
ConsoleWrite('--- New Code ---' & @CRLF) ; nur zum debuggen
Else ; alle anderen Zeichen werden in den Buffer 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', 'PeekMessage', 'struct*', $tMsg, 'hwnd', $g_hGui, 'uint', $WM_KEYFIRST, 'uint', $WM_KEYLAST, 'uint', $PM_REMOVE)[0]
Until $tMsg.message = 0x0101 Or $tMsg.message = 0
EndFunc
Alles anzeigen
Hi Oscar ,
wenn ich alles entferne was mit dem GUI zutun hat, läuft das ganze script nicht mehr. Wenn ich das richtig verstehe reagiert das Script auch erst wenn sich etwas in der GUI verändert ?
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Gibt es denn eine Möglichkeit das GUI auszublenden ? Ich habe es hiermit versucht (GUISetState(@SW_HIDE)) dann zeigt er zwar kein Eingabefenster mehr an, aber dann fängt er die Daten des Scanners nicht ab. Da wo der Wurster steht, schreibt er die Daten des Scanners rein, aber genau das möchte ich nicht, ich brauche die scannereingabe in einer Variable.
Für alte Hasen wahrscheinlich eine Kleinigkeit, für Neueinsteiger wie mich aber ne echte Herausforderung, bin also für jede Hilfe dankbar.
Gibt es denn eine Möglichkeit das GUI auszublenden ?
Ganz ohne Gui geht es nicht, weil die Events Windowbasiert sind. Man kann das Fenster aber verstecken und den Buffer an eine globale Variable übergeben:
#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
; hier muss der DeviceName von eurem Scanner drinstehen
; beim auskommentieren von Zeile 41 wird der DeviceName beim scannen angezeigt.
Global $g_sDevName = '\\?\HID#VID_13BA&PID_0018#6&238b7016&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}'
Global $g_sBarcode = '' ; die globale Variable, an die die Eingabe uebergeben wird
Global $g_hGui = GUICreate('BarcodeScanner', 300, 120)
Global $g_idLabel = GUICtrlCreateLabel('', 5, 5, 290, 30, $SS_CENTER) ; fuer die Ausgabe vom Barcode-Scanner
GUICtrlSetFont(-1, 16)
Local $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')
GUISetState(@SW_HIDE)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local Static $sBuffer = ''
Local $devType, $devName, $tRIM, $tText
$tRIM = DllStructCreate($tagRAWINPUTHEADER)
If Not _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_HEADER) Then Return
$devType = $tRIM.Type
$tText = DllStructCreate('wchar data[256]')
If Not _WinAPI_GetRawInputDeviceInfo($tRIM.hDevice, $tText, 256, $RIDI_DEVICENAME) Then Return
$devName = $tText.data
;~ ConsoleWrite(StringFormat("DevName: '%s'\r\n", $devName))
If $devName = $g_sDevName Then ; hier wird getestet, ob die Eingabe vom Barcode-Scanner kommt
If $devType = $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 = 13 Then ; wenn VKey = 13 (@CR) wird bei meinem Barcode-Scanner als Postfix gesendet (evtl. anpassen)
GUICtrlSetData($g_idLabel, $sBuffer) ; Buffer im Label anzeigen
$g_sBarcode = $sBuffer ; Buffer an die globale Variable uebergeben
ConsoleWrite('Global: ' & $g_sBarcode & @CRLF) ; nur zum debuggen
$sBuffer = '' ; Buffer leeeren, fuer naechsten Code
ConsoleWrite('--- New Code ---' & @CRLF) ; nur zum debuggen
Else ; alle anderen Zeichen werden in den Buffer 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', 'PeekMessage', 'struct*', $tMsg, 'hwnd', $g_hGui, 'uint', $WM_KEYFIRST, 'uint', $WM_KEYLAST, 'uint', $PM_REMOVE)[0]
Until $tMsg.message = 0x0101 Or $tMsg.message = 0
EndFunc
Alles anzeigen
Hi Oscar ,
danke, das geht in die richtige Richtung
Gibt es noch eine Möglichkeit die scandaten abzufangen, also nur in die Variable zu schreiben und sie nicht an das "System" zu übertragen ?
In der Console sieht das jetzt so aus:
100028
Global: 100028
100032
Global: 100032
100033
Global: 100033
Der Wert Global ist klar, der kommt hiervon: ConsoleWrite('Global: ' & $g_sBarcode & @CRLF) ; nur zum debuggen
Die Scandaten dazwischen kommen aber, soweit ich das sehe direkt vom Scanner und die brauche ich da nicht.
Ich hoffe das ist irgendwie verständlich
Sobald ich das Fenster auf @SW_HIDE setzte, überträgt er die Scandaten ans System, mit @SW_SHOW fängt er die Scandaten ab, aber ich habe das Fenster was ich nicht haben möchte.
Ich habe das Fenster jetzt als Workarround ausserhalb des Bildschirms platziert, das geht, aber da gibt es bestimmt noch eine sauberer Lösung, oder ?
aber da gibt es bestimmt noch eine sauberer Lösung, oder ?
Hmm...das Problem ist, dass da die Tastatureingaben der Gui abgefangen werden.
Ob und wie man das systemweit machen kann, weiß ich nicht.
Es ist sogar so, dass die Scandaten an ein anderes Fenster gesendet werden, wenn das gerade aktiv ist. Insofern nützt es wenig, die eigene Gui zu verstecken.
Was willst Du denn mit den Scandaten machen? Benutzt Du denn gar keine Gui? Es muss ja nicht die Gui aus dem Beispiel sein.
Hi, das soll ein Terminal/Monitor werden, der soll nur eine Excel/HTML Seite darstellen, die bei Änderung aktualisiert wird. Auf dem Terminal/Monitor sollen Fertigungsaufträge dargestellt werden. Das alles funktioniert auch soweit schon sehr gut. Jetzt möchte ich an den Terminals/Monitor noch die Möglichkeit haben die Fertigungsaufträge zu scannen und somit diesen den Status "Angefangen" und "Abgeschlossen" mitgeben und genau dafür benötige ich die Scanfunktion.
Hmm...das Problem ist, dass da die Tastatureingaben der Gui abgefangen werden.
Ob und wie man das systemweit machen kann, weiß ich nicht.
Es ist sogar so, dass die Scandaten an ein anderes Fenster gesendet werden, wenn das gerade aktiv ist. Insofern nützt es wenig, die eigene Gui zu verstecken.
Sofern Pre- und Postzeichen gesendet werden, die auch definitiv im allgemeinen Datenverkehr niemals an das System gesendet werden, könnte ich mir vorstellen, dass ein systemweiter Keyboard-Hook auch ohne ein Fenster auskommt und somit die Daten einfängt. Ich habe nur keinen Scanner hier zum Testen.
dass ein systemweiter Keyboard-Hook auch ohne ein Fenster auskommt und somit die Daten einfängt.
Ja, wenn ein Prefix gesendet wird, kann man das hier benutzen:
#include <GUIConstantsEx.au3>
#include <StructureConstants.au3>
#include <WinAPIConstants.au3>
#include <WinAPIInternals.au3>
#include <WinAPISys.au3>
#include <WinAPISysInternals.au3>
#include <WindowsConstants.au3>
; Hier den Postfix-Code von eurem Scanner eintragen.
Global $g_iPostfix = 0x0D
; Hier den Prefix-Code von eurem Scanner eintragen.
Global $g_iPrefix = 0x03
HotKeySet('{ESC}', '_Exit')
OnAutoItExitRegister('OnAutoItExit')
Global $hKeyProc = DllCallbackRegister('_KeyProc', 'long', 'int;wparam;lparam')
Global $hmod = _WinAPI_GetModuleHandle(0)
Global $hKeyHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hKeyProc), $hmod)
Global $hGui = GUICreate('Barcodescanner', 300, 140)
Global $idBarcode = GUICtrlCreateLabel('', 10, 10, 280, 30)
GUICtrlSetFont(-1, 16, 400, 0, 'Courier New')
Global $idInput = GUICtrlCreateInput('', 10, 50, 280, 30)
GUICtrlSetFont(-1, 16, 400, 0, 'Courier New')
GUISetState(@SW_HIDE)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Func _Exit()
Exit
EndFunc
; ACHTUNG! Callback-Funktion!
; In dieser Funktion darf es keinen blockierenden Code (z.B. MsgBox, Sleep, etc.) geben!
; Hier werden direkt die virtuellen Keycodes der Tastatur ausgewertet:
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Func _KeyProc($nCode, $wParam, $lParam)
Local $tKBDLLHOOK = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $iKeyCode = $tKBDLLHOOK.vkCode, $iPressTime
Local Static $sBuffer = '', $bBarcodeActive = False
If $nCode >= 0 Then
If $iKeyCode = $g_iPrefix And $wParam = $WM_KEYUP Then
$bBarcodeActive = Not $bBarcodeActive
ConsoleWrite('$bBarcodeActive = ' & $bBarcodeActive & @CRLF)
$sBuffer = ''
EndIf
If $bBarcodeActive Then
Switch $wParam
Case $WM_KEYDOWN
Return 1
Case $WM_KEYUP
Switch $iKeyCode ; Keycode auswerten
Case $g_iPostfix
ConsoleWrite(StringFormat('Barcode = "%s"\r\n', $sBuffer))
GUICtrlSetData($idBarcode, $sBuffer)
$sBuffer = ''
$bBarcodeActive = False
ConsoleWrite('$bBarcodeActive = ' & $bBarcodeActive & @CRLF)
Return 1
Case 0x30 To 0x39, 0x41 To 0x5A ; 0 - 9, A - Z
$sBuffer &= Chr($iKeyCode)
Return 1
EndSwitch
EndSwitch
EndIf
EndIf
Return _WinAPI_CallNextHookEx($hKeyHook, $nCode, $wParam, $lParam)
EndFunc ;==>_KeyProc
; Wichtig! Beim Programmende den Hook wieder entfernen.
Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hKeyHook)
DllCallbackFree($hKeyProc)
EndFunc ;==>OnAutoItExit
Alles anzeigen
Hallo Oscar ,
besten Dank für deine ganze Unterstützung hier, das Script passt so perfekt zu meinem Vorhaben.
Ich habe aber leider noch ein Verständnisproblem, wo setzte ich am besten den Teil rein, an dem er den vom Scanner ausgelesenen Wert weg schreibt ?
Kann ich das in der Funktion KeyProc hinzufügen ?
Ist auch nichts aufregendes:
Func StatusSave()
if fileexists($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Start.log") Then
Local $hFile = FileOpen($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Ende.log", 1)
Else
Local $hFile = FileOpen($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Start.log", 1)
EndIf
_FileWriteLog($hFile, $sBuffer& @CRLF)
FileClose($hFile)
EndFunc
Ich würde es ja auch dort platzieren, wo die Funktion KeyProc gestartet wird, jedoch finde ich die Stelle nicht.
Kann ich das in der Funktion KeyProc hinzufügen ?
Ja, mit Übergabeparameter geht's ohne Zuweisung an eine globale Variable:
#include <GUIConstantsEx.au3>
#include <StructureConstants.au3>
#include <WinAPIConstants.au3>
#include <WinAPIInternals.au3>
#include <WinAPISys.au3>
#include <WinAPISysInternals.au3>
#include <WindowsConstants.au3>
; Hier den Postfix-Code von eurem Scanner eintragen.
Global $g_iPostfix = 0x0D
; Hier den Prefix-Code von eurem Scanner eintragen.
Global $g_iPrefix = 0x03
HotKeySet('{ESC}', '_Exit')
OnAutoItExitRegister('OnAutoItExit')
Global $hKeyProc = DllCallbackRegister('_KeyProc', 'long', 'int;wparam;lparam')
Global $hmod = _WinAPI_GetModuleHandle(0)
Global $hKeyHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hKeyProc), $hmod)
Global $hGui = GUICreate('Barcodescanner', 300, 140)
Global $idBarcode = GUICtrlCreateLabel('', 10, 10, 280, 30)
GUICtrlSetFont(-1, 16, 400, 0, 'Courier New')
Global $idInput = GUICtrlCreateInput('', 10, 50, 280, 30)
GUICtrlSetFont(-1, 16, 400, 0, 'Courier New')
GUISetState(@SW_HIDE)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit
Func _Exit()
Exit
EndFunc
; ACHTUNG! Callback-Funktion!
; In dieser Funktion darf es keinen blockierenden Code (z.B. MsgBox, Sleep, etc.) geben!
; Hier werden direkt die virtuellen Keycodes der Tastatur ausgewertet:
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Func _KeyProc($nCode, $wParam, $lParam)
Local $tKBDLLHOOK = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $iKeyCode = $tKBDLLHOOK.vkCode, $iPressTime
Local Static $sBuffer = '', $bBarcodeActive = False
If $nCode >= 0 Then
If $iKeyCode = $g_iPrefix And $wParam = $WM_KEYUP Then
$bBarcodeActive = Not $bBarcodeActive
ConsoleWrite('$bBarcodeActive = ' & $bBarcodeActive & @CRLF)
$sBuffer = ''
EndIf
If $bBarcodeActive Then
Switch $wParam
Case $WM_KEYDOWN
Return 1
Case $WM_KEYUP
Switch $iKeyCode ; Keycode auswerten
Case $g_iPostfix
ConsoleWrite(StringFormat('Barcode = "%s"\r\n', $sBuffer))
_StatusSave($sBuffer)
$sBuffer = ''
$bBarcodeActive = False
ConsoleWrite('$bBarcodeActive = ' & $bBarcodeActive & @CRLF)
Return 1
Case 0x30 To 0x39, 0x41 To 0x5A ; 0 - 9, A - Z
$sBuffer &= Chr($iKeyCode)
Return 1
EndSwitch
EndSwitch
EndIf
EndIf
Return _WinAPI_CallNextHookEx($hKeyHook, $nCode, $wParam, $lParam)
EndFunc ;==>_KeyProc
; Wichtig! Beim Programmende den Hook wieder entfernen.
Func OnAutoItExit()
_WinAPI_UnhookWindowsHookEx($hKeyHook)
DllCallbackFree($hKeyProc)
EndFunc ;==>OnAutoItExit
Func _StatusSave($sBuffer)
Local $hFile
If FileExists($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Start.log") Then
$hFile = FileOpen($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Ende.log", 1)
Else
$hFile = FileOpen($Freigabe & "\Prod-Status\" & $Gewerk & "\" & $sBuffer & "_Start.log", 1)
EndIf
_FileWriteLog($hFile, $sBuffer & @CRLF)
FileClose($hFile)
EndFunc ;==>StatusSave
Alles anzeigen
Hallo Oscar ,
danke für den Tipp, das funktioniert.
Jetzt habe ich aber noch das Problem, dass er die scanns eine Zeit lang funktionieren, dabei schreibt er sowohl das Log weg, wie auch in der Console sieht man die Aktivitäten. Nach einer gewissen Zeit jedoch, einige scanvorgänge später schreibt er weder die Log noch zeigt er in der Console etwas an. Es scheint, alsob der Hook nicht mehr auf den Scanner reagiert. Vielleicht noch eine Idee was das sein könnte ?
Vielleicht noch eine Idee was das sein könnte ?
Hast Du da noch etwas anderes eingebaut?
Bitte poste Dein ganzes Script!