Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Bibliotecas de código fuente (https://www.clubdelphi.com/foros/forumdisplay.php?f=53)
-   -   Componentes lectores DigitalPersona (https://www.clubdelphi.com/foros/showthread.php?t=88952)

AgustinOrtu 02-09-2015 06:10:11

Componentes lectores DigitalPersona
 
Saludos

Para aquel que lo recuerde, en este tema habia solicitado un poco de ayuda referente a los lectores de huella digital. Bueno, al fin y al cabo me he decidido por un lector de los U.Are.U (DigitalPersona)

En concreto el que cayo en mis manos es un DigitalPersona U.are.U 4000B

Para lograr comunicarme con el desde Delphi hago uso de SDK "DigitalPersona One Touch for Windows"

Cuestion, es andar metiendose con controles ActiveX, OLE, Variants.. ese tipo de cosas que cuando uno esta programando y apreta . o control + espacio y no sale nada, son todas llamadas a metodos "misteriosos"

En fin, luego de estudiar un poco, decidi crearme un componente wrapper para poder manejar facilmente el lector. Creo que esta lejos de ser perfecto, asi que bienvenidas sean las criticas/sugerencias. Al parecer cumple bien, será cuestion de probarlo en produccion

Lo tengo alojado en un repositorio en GitLab. Esta liberado bajo la licencia BSD (la de 3 cláusulas). Asi que basicamente pueden usarlo a su antojo como si fuera suyo

El funcionamiento es bastante similar al GRFingerPrint que publico Al Gonzalez hace algun tiempo. Es decir, este componente lo unico que hace es facilitarle la vida al programador delphi; el verdadero trabajo lo hace el SDK. De hecho es requisito que se importen las librerias ActiveX de DigitalPersona (estan en el repo para que la instalacion sea click and run)

Trate de hacerlo mas sencillo posible, asi que minimize todo a dos componentes:

1. TDPFingerPrintEnroll --> Usado para registrar huellas digitales, mediante el tipico proceso de 4 lecturas de un dedo. Hace uso del control ActiveX que se provee en el SDK. Funciona estilo "TxxDialog", es decir, tiene su metodo Execute

Para los Delphinianos: La verdad no se me ocurrio mejor idea que crear una instancia del control ActiveX y luego meterle como Parent un TForm. El form se visualiza con ShowModal al llamar a Execute y se proveen 2 botones (mrOk y mrCancel). Sencillisimo

Hay 3 eventos posibles:
- AfterExecute: Creo que su nombre lo dice todo. Basicamente se dispara cuando se cierra el TForm que comentaba antes. Provee bastante informacion util, como por ejemplo cada dedo con su huella capturada. Para ello cree unos tipos de datos para identificar facilmente a cada dedo (usando enumerativos y set, y helpers para que sea aun mas facil)

- OnFigerEnroll: Se dispara al registrar una nueva huella. Devuelve el dedo en cuestion y el template generado en string

- OnFingerPrintDeleted: Se dispara al eliminar una de las huellas registradas. Para eliminar una huella registrada en el control ActiveX, se debe hacer click sobre uno de los dedos que estan como registrados (color verde).

Solo publica una propiedad: MaxFingerPrintsAllowed, la cual indica la cantidad maxima de huellas que se puede registrar

2. TDPFingerPrintReader --> Representa nuestro lector, en estado de "capturando". Es decir, si esta activo, cada vez que se apoye el dedo en el lector, nuestra aplicacion en cuestion se entera a traves de los eventos.

Creo que el mas importante de los eventos de este componente es el OnCaptured, que se va a disparar cuando se capture una lectura exitosa (de calidad optima para verificacion). Este evento es importante porque nos provee una referencia a una interface de tipo IFingerComparer

IFingerComparer es una interface que viene "cargada" con el template de la huella capturada y lista para comparar contra las que tenemos almacenadas en nuestro soporte externo (en el 99.99% de los casos una BD :))

Para ello, emplearemos el metodo CompareTo

Asi de sencillo:

Verificacion:

Código Delphi [-]
procedure TFMain.DPFingerPrintReader1Captured(Reader: TDPFingerPrintReader; FingerComparer: IFingerComparer);
begin
  while not XXX.Eof do
  begin
    if FingerComparer.CompareTo(XXX.FieldByName('Huella').AsString) then
    begin
      ShowMessage('Encontrado!');
      Break;
    end;

    XXX.Next;
  end;
end;

Registracion:

Código Delphi [-]
procedure TFMain.DPFingerPrintEnroll1AfterExecute(Sender: TDPFingerPrintEnroll; 
const FingerPrints: TFingerPrints;  EnrolledFingers: TFingerSet; const Result: Boolean);
var
  LFinger: TFinger;
  FingerPrint: string;
begin
  XXX.SQL.Text := ' INSERT INTO Huellas (IdPersona, Dedo, Huella) VALUES (:IdPersona, :Dedo, :Huella) ';
  XXX.ParamByName('IdPersona').DataType:= ftInteger;
  XXX.ParamByName('Dedo').DataType:= ftInteger;
  XXX.ParamByName('Huella').DataType:= ftString;
  XXX.Prepare;

  for LFinger := Low(TFinger) to High(TFinger) do
  begin
    if not LFinger in EnrolledFingers then
      Continue;
  
    XXX.ParamByName('IdPersona').AsInteger := AlgunId;
    XXX.ParamByName('Dedo').AsInteger := LFinger;
    XXX.ParamByName('Huella').AsString:= Huella;
    XXX.Execute;
  end;
end;

Instalacion: https://gitlab.com/ortuagustin/TDPFi...ster/README.md

Proximamente en Español, pero deberia entenderse ya que el propio Delphi esta en Ingles.

PD: Si bien es interesante el tema de crear componentes en Delphi, esta es mi primera experiencia. Lo digo para que los mas veteranos no me maten :D

Combat-F2D 02-09-2015 08:43:30

muchisimas gracia spor tu aprte; super interesante

Casimiro Notevi 02-09-2015 10:59:13

^\||/^\||/^\||/

ecfisa 02-09-2015 11:07:42

Gracias por compartirlo Agustín ^\||/

Saludos :)

ElKurgan 02-09-2015 11:44:05

Gracias por compartir

Saludos
#:-)#

Al González 03-09-2015 07:35:17

Cita:

Empezado por AgustinOrtu (Mensaje 496136)
PD: Si bien es interesante el tema de crear componentes en Delphi, esta es mi primera experiencia. Lo digo para que los mas veteranos no me maten :D

¡Jo! :D Traquilo, este colega es pacífico.

Me da gusto saber que has creado esta solución, Agustín. Sólo felicitarte por atreverte a hacer tu primer componente en Delphi. :)

El mundo de las bibliotecas es fascinante, aunque sólo si te matan reconocen tus esfuerzos. :p

roman 08-09-2015 02:38:29

Aunque vayas a usar un lector digital, tu pregunta realmente no está relacionada con ese tema. Por favor otro hilo para exponer tu duda.

// Saludos

AgustinOrtu 13-09-2015 21:27:46

Gracias a todos por los comentarios

Al, acá en Argentina el "no me maten" viene a decir algo así como "sed blandos conmigo" :). Al escribir a veces me dejo llevar y me olvido de esos pequeños detalles

En fin, quería comentarles que el componente lo pude instalar en 10 Seattle sin modificarle nada y funciona muy bien.

AgustinOrtu 15-09-2015 02:48:45

Pues bien, resulta que ahora tengo problemas

No logro encontrar el motivo, pero basicamente cualquier evento tanto del componente como el de los controles ActiveX se comen las excepciones

es decir, hacer algo como esto:

Código Delphi [-]
  raise Exception.Create('Una excepcion');

Y no pasa nada :confused:

La unica forma de "atraparla" es con Run (F9). Es decir, desde el IDE y con el depurador si veo la excepcion. Sino no. Trate de seguirla y termina en codigo ASM del que poco entiendo. Probe las siguiente variantes:

Código Delphi [-]
  try
    { generar excepcion }
  except
    raise;
  end;


Código Delphi [-]
  try
    { generar excepcion }
  except
    RaiseLastOsError;
  end;

Y fracase estripotosamente :(

Esto sucede en una aplicacion con solo el componente que diseñe yo o bien su contraparte COM. Es decir, la "culpa" esta ahi; pero no tengo ningun manejador OnApplicationException o similar. Tampoco hay un bloque que coma excepciones, o al menos no lo he visto (pero eso deberia ser rastreable usando el depurador). Es mas, si coloco un componente ApplicationEvents, en su evento OnException nunca llega la excepcion en cuestion

Creo que hay algo del modelo COM que se me escapa.

A ver si alguien puede arrojar un poco de luz

Edito:

Aun mas confundido. Esto hace aparecer la excepcion pero...

Código Delphi [-]
  try
    { generar excepcion }
  except
    on E: Exception do
    begin
      Result := False;
      ShowException(E, ExceptAddr);
    end;
  end;

...no me gusta para NADA, aunque es MUCHO peor no poder ver las excepciones

Casimiro Notevi 26-08-2016 20:31:10

Cita:

Empezado por vinicc (Mensaje 508195)
Gracias

Crea un hilo para tu pregunta. gracias.

MAXIUM 24-08-2018 02:03:15

¿Actualizaciones para Delphi 10?

[dcc32 Error] Unit1.pas(13): E2003 Undeclared identifier: 'TFingerPrints'
[dcc32 Error] Unit1.pas(13): E2003 Undeclared identifier: 'TFingerSet'
[dcc32 Error] Unit1.pas(29): E2005 'TFingerPrints' is not a type identifier
[dcc32 Error] Unit1.pas(29): E2005 'TFingerSet' is not a type identifier

MAXIUM 24-08-2018 02:14:02


MAXIUM 24-08-2018 02:24:48


Casimiro Notevi 24-08-2018 11:56:47

¿El fabricante no tiene nada?

MAXIUM 24-08-2018 19:48:05

Cita:

Empezado por Casimiro Notevi (Mensaje 528172)
¿El fabricante no tiene nada?

Creo que me queda trabajar con los dll y la guía SDK del fabricante





La franja horaria es GMT +2. Ahora son las 10:48:03.

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