Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Deshabilitar HID-USB (https://www.clubdelphi.com/foros/showthread.php?t=90106)

petercat 07-04-2016 21:01:46

Deshabilitar HID-USB
 
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?...rticle&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

Cita:

Empezado por Casimiro Notevi (Mensaje 504311)
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.

Código Delphi [-]
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

Identificar multiteclado HID-USB
 
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"

Código Delphi [-]
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

me podrias ayudar con este descubrimiento tuyo
 
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


La franja horaria es GMT +2. Ahora son las 02:15:19.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi