PDA

Ver la Versión Completa : Deshabilitar HID-USB


petercat
07-04-2016, 21:01:46
Buneas
Resulta que en el programa que estoy haciendo tengo un teclado por USB y ahora un dispositivo RFID tambien por USB que emula el teclado, ahora necesito deshabilitar el lectro USB del RFID mientras no me haga falta para que cuando alguien se aproxime al lector RFID no interfiere con parte del programa en ejecucion, es decir lo que quiero es solicirtar al lector que actue cuando realmente sea necesario, para ello lo que se me ocurre es identificar el HID-USB mediante el ID Venderdor y deshabilitarlo hasta que realmente me haga falta y una vez leido o trascurrido un tiempo con un timer que lo vuelva a deshabilitar.
Podeis orientarme de como podria deshabilitar dicho HID-USB mediante el ID del Vendedor ó productID?'

Muchas gracias

bitbow
07-04-2016, 21:32:16
El objetivo de estos lectores es que funcionen desatendidos por lo cual lo que quieres hacer (a como yo los he usado) v en contra de para lo que se pensaron (kioscos, pasarelas, controles de acceso), basta con identificar el dispositivo de interfaz humana y deshabilitarlo/habilitarlo dependiendo de como lo requieras (no he realizado esta acción en delphi pero seguramente se puede).

Saludos.

Lepe
08-04-2016, 15:28:59
Sea como fuere, échale un vistazo a esta web: http://www.ajpdsoft.com/modules.php?name=News&file=article&sid=463

Creo tiene todo lo que necesitas.

Saludos y suerte!

petercat
10-04-2016, 16:52:32
Gracias pero el ejemplo de apjsoft es para pendrive de memoria.
Lo que realmente quiero es poder habilitar y deshabilitar es el HID del Keyboar, en la actualidad me reconoce dos dispositivos uno HID que el el teclado y otro HID que es el Barcode Reader (Lector RFID), los dos los identifcio mediante el PID y el VID y de momento lo hago con mcHID.dll, pero no se como poder habilitar y deshabilitar o que no estre en uso uno de ellos, es dejarlo inactivo el Lector para cuando realmente me haga falta, de esta manera no interfiere con el programa, dado que si estan escribiendo y pasan sin querer el Tag del lector por encima les sale un chorro de numeros.

Gracias

petercat
11-04-2016, 22:33:18
Buenas sigo con el tema y quizas pueda solucionarlo de otra manera en vez de deshabilitar el lector o teclado. Expongo como estoy viendo la posible solucion pero aun asi necesito ayuda.
Tengo un teclado por USB-HID con un numero VID (Vendedor_ID) "VID:046D:" y un PID (Product_ID) "PID:C31C"
Tengo un lector por USB-HID con un numero VID (Vendedor_ID) "VID:13BA" y un PID (Product_ID) "PID:0018"
Dicha informacion la puedo sacar del Regedit o desde el administrador de dispositivos, los dos utilizan el mismo controlador.
Luego dispongo de dos TEdit "Edit1" y "Edit2" la tecla 0 el la key=#48, pues bien la intencion es que si lee la tecla 0 del dispositivo HID de teclado vaya ela "Edit1" pero si por el contrario leo con el lector, que para ello le he dicho que la primera letra sea un 0, vaya al "Edit2".

Sabria alguien decirme si sepuede identificar del dispositivo de donde viene el numero 0????

Muchas gracias

PD si es necesario cambio el titulo

Casimiro Notevi
12-04-2016, 00:35:05
Si deshabilitas el teclado ¿cómo lo habilitas después?

petercat
12-04-2016, 00:43:23
Si deshabilitas el teclado ¿cómo lo habilitas después?

Por eso he cambiado la idea, la idea es poder saber si los números vienen del HID del teclado o del HID del lector.
No sé si Delphi podrá saber si vienen por uno o por otro dependiendo de si se puede leer el VID y o el PID de donde vengan.

Delfino
12-04-2016, 10:06:35
Has mirado el componente TJvHidDeviceController de la suite JVCL?

Noiro
15-04-2016, 19:22:40
Puedes utilizar RegisterRawInputDevices.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
USHORT = Word;
HRAWINPUT = THandle;
LPVOID = Pointer;

tagRAWINPUTDEVICE = record
usUsagePage: USHORT;
usUsage: USHORT;
dwFlags: DWORD;
hwndTarget: HWND;
end;
RAWINPUTDEVICE = tagRAWINPUTDEVICE;
TRawInputDevice = RAWINPUTDEVICE;
PRawInputDevice = ^TRawInputDevice;
LPRAWINPUTDEVICE = PRawInputDevice;
PCRAWINPUTDEVICE = PRawInputDevice;

tagRAWINPUTHEADER = record
dwType: DWORD;
dwSize: DWORD;
hDevice: THandle;
wParam: WPARAM;
end;
RAWINPUTHEADER = tagRAWINPUTHEADER;
TRawInputHeader = RAWINPUTHEADER;
PRawInputHeader = ^TRawInputHeader;

tagRAWMOUSE = record
usFlags: WORD;
union: record
case Integer of
0: (
ulButtons: ULONG);
1: (
usButtonFlags: WORD;
usButtonData: WORD);
end;
ulRawButtons: ULONG;
lLastX: LongInt;
lLastY: LongInt;
ulExtraInformation: ULONG;
end;
RAWMOUSE = tagRAWMOUSE;
TRawMouse = RAWMOUSE;
PRAWMOUSE = ^RAWMOUSE;
LPRAWMOUSE = ^RAWMOUSE;

tagRAWKEYBOARD = record
MakeCode: USHORT;
Flags: USHORT;
Reserved: USHORT;
VKey: USHORT;
Message: UINT;
ExtraInformation: ULONG;
end;
RAWKEYBOARD = tagRAWKEYBOARD;
TRawKeyboard = RAWKEYBOARD;
PRawKeyboard = ^TRawKeyboard;
LPRAWKEYBOARD = PRawKeyboard;

tagRAWHID = record
dwSizeHid: DWORD; // byte size of each report
dwCount: DWORD; // number of input packed
bRawData: array [0..0] of BYTE;
end;
RAWHID = tagRAWHID;
TRawHID = RAWHID;
PRawHID = ^TRawHID;
LPRAWHID = PRawHID;


tagRAWINPUT = record
header: TRawInputHeader;
case Integer of
0: (mouse: RAWMOUSE);
1: (keyboard: RAWKEYBOARD);
2: (hid: RAWHID);
end;
RAWINPUT = tagRAWINPUT;
TRawInput = RAWINPUT;
PRawInput = ^TRawInput;
LPRAWINPUT = PRawInput;

TForm1 = class(TForm)
private
protected
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure WMInput(var Message: TMessage); message WM_INPUT;
{ Private declarations }
public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const
GenericDesktopControls: USHORT = 01;
Keyboard: USHORT = 06;
RIDEV_INPUTSINK = $00000100;

RIM_INPUT = 0;
RIM_INPUTSINK = 1;
RID_INPUT = $10000003;

RIM_TYPEMOUSE = 0;
RIM_TYPEKEYBOARD = 1;
RIM_TYPEHID = 2;

RI_KEY_MAKE = 0;
RI_KEY_BREAK = 1;


function RegisterRawInputDevices(
pRawInputDevices: PCRAWINPUTDEVICE;
uiNumDevices: UINT;
cbSize: UINT): BOOL; stdcall; external user32;

function GetRawInputData(
hRawInput: HRAWINPUT;
uiCommand: UINT;
pData: LPVOID;
var pcbSize: UINT;
cbSizeHeader: UINT): UINT; stdcall; external user32;


{ TForm1 }

procedure TForm1.CreateWindowHandle(const Params: TCreateParams);
var
RID: TRawInputDevice;
begin
inherited;

RID.usUsagePage := GenericDesktopControls;
RID.usUsage := Keyboard;
RID.dwFlags := RIDEV_INPUTSINK;
RID.hwndTarget := Handle;
Win32Check(RegisterRawInputDevices(@RID, 1, SizeOf(RID)));
end;

procedure TForm1.WMInput(var Message: TMessage);
var
Size: UINT;
Data: array of Byte;
RawKeyboard: TRawKeyboard;
RawHID: TRawHID;
begin
if (Message.WParam and $FF) in [RIM_INPUT, RIM_INPUTSINK] then
inherited;

if (GetRawInputData(Message.LParam, RID_INPUT, nil, Size,
SizeOf(TRawInputHeader)) = 0) then begin
SetLength(Data, Size);
if (GetRawInputData(Message.LParam, RID_INPUT, Data, Size,
SizeOf(TRawInputHeader)) <> UINT(-1)) then
begin
if (PRawInput(Data)^.header.dwType = RIM_TYPEKEYBOARD) then
begin
RawKeyboard := PRawInput(Data)^.keyboard;

if (RawKeyboard.VKey = VK_CONTROL) then begin
if RawKeyboard.Flags and RI_KEY_BREAK = RI_KEY_BREAK then
Cursor := crDefault
else
Cursor := crSizeAll; // will call continously until key is released
end;
// might opt to reset the cursor regardless of pointer position...


if (RawKeyboard.VKey = Ord('A')) then
begin
// ....
end;
end
else if (PRawInput(Data)^.header.dwType = RIM_TYPEHID) then
begin
RawHID := PRawInput(Data).hid;
// ....
end;
end;

end;
end;

end.


Para poder "escuchar" el HID tendrás que registrarlo en la llamada RegisterRawInputDevices pasando un array con el total de dispositivos.

petercat
19-04-2016, 17:59:21
Gracias a nuestro amigo Noiro he podido conseguir distinguir el dispositivo Teclado del dispositivo RFID, podria valer para distinguir un teclado de un lector de codigo de barras etc.
Tan solo al codigo que pego Noiro se le han cambiado algunos parametros y con ello nos da el resultado del teclado en el Label1 y el lector en el Label2.
Una vez conseguido esto definido cada una de las direcciones del dispositivo y podemos aislar el teclado del lector tanto en un edit como en un memo.
Pego el codigo por si alguno esta buscando una solucion parecida a la mia.
Gracias a todos
PD si es necesario cambiar el titulo: "Deshabiliar HID-USB" por el de "Identificar multiteclado HID-USB"

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
USHORT = Word;
HRAWINPUT = THandle;
LPVOID = Pointer;
HANDLE = THandle;

tagRAWINPUTDEVICE = record
usUsagePage: USHORT;
usUsage: USHORT;
dwFlags: DWORD;
hwndTarget: HWND;
end;
RAWINPUTDEVICE = tagRAWINPUTDEVICE;
TRawInputDevice = RAWINPUTDEVICE;
PRawInputDevice = ^TRawInputDevice;
LPRAWINPUTDEVICE = PRawInputDevice;
PCRAWINPUTDEVICE = PRawInputDevice;

tagRAWINPUTHEADER = record
dwType: DWORD;
dwSize: DWORD;
hDevice: THandle;
wParam: WPARAM;
end;
RAWINPUTHEADER = tagRAWINPUTHEADER;
TRawInputHeader = RAWINPUTHEADER;
PRawInputHeader = ^TRawInputHeader;

tagRAWMOUSE = record
usFlags: WORD;
union: record
case Integer of
0: (
ulButtons: ULONG);
1: (
usButtonFlags: WORD;
usButtonData: WORD);
end;
ulRawButtons: ULONG;
lLastX: LongInt;
lLastY: LongInt;
ulExtraInformation: ULONG;
end;
RAWMOUSE = tagRAWMOUSE;
TRawMouse = RAWMOUSE;
PRAWMOUSE = ^RAWMOUSE;
LPRAWMOUSE = ^RAWMOUSE;

tagRAWKEYBOARD = record
MakeCode: USHORT;
Flags: USHORT;
Reserved: USHORT;
VKey: USHORT;
Message: UINT;
ExtraInformation: ULONG;
end;
RAWKEYBOARD = tagRAWKEYBOARD;
TRawKeyboard = RAWKEYBOARD;
PRawKeyboard = ^TRawKeyboard;
LPRAWKEYBOARD = PRawKeyboard;

tagRAWHID = record
dwSizeHid: DWORD; // byte size of each report
dwCount: DWORD; // number of input packed
bRawData: array [0..0] of BYTE;
end;
RAWHID = tagRAWHID;
TRawHID = RAWHID;
PRawHID = ^TRawHID;
LPRAWHID = PRawHID;


tagRAWINPUT = record
header: TRawInputHeader;
case Integer of
0: (mouse: RAWMOUSE);
1: (keyboard: RAWKEYBOARD);
2: (hid: RAWHID);
end;
RAWINPUT = tagRAWINPUT;
TRawInput = RAWINPUT;
PRawInput = ^TRawInput;
LPRAWINPUT = PRawInput;

TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
private
protected
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure WMInput(var Message: TMessage); message WM_INPUT;
{ Private declarations }
public
{ Public declarations }

end;

var
Form1: TForm1;
KBName: array[0..1023] of AnsiChar;

implementation

{$R *.dfm}

const
GenericDesktopControls: USHORT = 01;
Keyboard: USHORT = 06;
RIDEV_INPUTSINK = $00000100;

RIM_INPUT = 0;
RIM_INPUTSINK = 1;
RID_INPUT = $10000003;

RIDI_DEVICENAME = $20000007;
RIDI_DEVICEINFO = $2000000b;
RIDI_PREPARSEDDATA = $20000005;

RIM_TYPEMOUSE = 0;
RIM_TYPEKEYBOARD = 1;
RIM_TYPEHID = 2;

RI_KEY_MAKE = 0;
RI_KEY_BREAK = 1;


function RegisterRawInputDevices(
pRawInputDevices: PCRAWINPUTDEVICE;
uiNumDevices: UINT;
cbSize: UINT): BOOL; stdcall; external user32;

function GetRawInputData(
hRawInput: HRAWINPUT;
uiCommand: UINT;
pData: LPVOID;
var pcbSize: UINT;
cbSizeHeader: UINT): UINT; stdcall; external user32;

function GetRawInputDeviceInfoA(hDevice: THANDLE; uiCommand: UINT; pData: POINTER;
var pcbSize: UINT): UINT; stdcall; external user32;


{ TForm1 }



procedure TForm1.CreateWindowHandle(const Params: TCreateParams);
var
RID: TRawInputDevice;
begin
inherited;

RID.usUsagePage := GenericDesktopControls;
RID.usUsage := Keyboard;
RID.dwFlags := RIDEV_INPUTSINK;
RID.hwndTarget := Handle;
Win32Check(RegisterRawInputDevices(@RID, 1, SizeOf(RID)));
end;


procedure TForm1.WMInput(var Message: TMessage);
var
Size: UINT;
Data: array of Byte;
RawKeyboard: TRawKeyboard;
RawHID: TRawHID;
devName: array of Byte;
//lo pasamos al var general
// KBName: array[0..1023] of AnsiChar;
Key :Char;
begin
if (Message.WParam and $FF) in [RIM_INPUT, RIM_INPUTSINK] then
inherited;

if (GetRawInputData(Message.LParam, RID_INPUT, nil, Size,
SizeOf(TRawInputHeader)) = 0) then begin
SetLength(Data, Size);
if (GetRawInputData(Message.LParam, RID_INPUT, Data, Size,
SizeOf(TRawInputHeader)) <> UINT(-1)) then
begin
if (PRawInput(Data)^.header.dwType = RIM_TYPEKEYBOARD) then
begin
RawKeyboard := PRawInput(Data)^.keyboard;

if (RawKeyboard.VKey = VK_CONTROL) then begin
if RawKeyboard.Flags and RI_KEY_BREAK = RI_KEY_BREAK then
Cursor := crDefault
else
Cursor := crSizeAll; // will call continously until key is released
end;
// might opt to reset the cursor regardless of pointer position...

// Al pulsar la tecla 'A' nos devolvera en el Label1 en KBName nos dara
//la ruta de acceso a la instancia del dispositivo
if (RawKeyboard.VKey = Ord('A')) then
begin
Size := 1024;
if (GetRawInputDeviceInfoA(PRawInput(Data)^.header.hDevice, RIDI_DEVICENAME,
@KBName, Size) <> UINT(-1)) then
begin
Label1.Caption := Ansistring(KBName);
end;
// ....
end;

// Al pulsar la tecla '0' nos devolvera en el Label2 en KBName nos dara
//la ruta de acceso a la instancia del dispositivo
if (RawKeyboard.VKey = Ord('0')) then
begin
Size := 1024;
if (GetRawInputDeviceInfoA(PRawInput(Data)^.header.hDevice, RIDI_DEVICENAME,
@KBName, Size) <> UINT(-1)) then
begin
Label2.Caption := Ansistring(KBName);
end;
// ....
end;

end
else if (PRawInput(Data)^.header.dwType = RIM_TYPEHID) then
begin
RawHID := PRawInput(Data).hid;
// ....
end;
end;

end;
end;

end.

Alexandro Prado
27-06-2023, 00:18:15
Hola petercat, vengo de Brasil, tengo un problema que solucionaste. ¿Podría darme un ejemplo más completo de cómo está reconociendo el lector hid rfid y cómo está trabajando con sus lecturas?
También tengo un lector HID que simula el teclado y quiero controlar cuándo empezar a leer o capturar su respuesta sin que afecte lo que está haciendo el operador.
si me pueden ayudar se los agradecere