PDA

Ver la Versión Completa : Componentes lectores DigitalPersona


AgustinOrtu
02-09-2015, 05:10:11
Saludos

Para aquel que lo recuerde, en este tema (http://www.clubdelphi.com/foros/showthread.php?t=88284) 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 (https://gitlab.com/ortuagustin/TDPFingerPrint) 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:


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:


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/TDPFingerPrint/blob/master/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, 07:43:30
muchisimas gracia spor tu aprte; super interesante

Casimiro Notevi
02-09-2015, 09:59:13
^\||/^\||/^\||/

ecfisa
02-09-2015, 10:07:42
Gracias por compartirlo Agustín ^\||/

Saludos :)

ElKurgan
02-09-2015, 10:44:05
Gracias por compartir

Saludos
#:-)#

Al González
03-09-2015, 06:35:17
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, 01: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, 20: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, 01: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:


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:


try
{ generar excepcion }
except
raise;
end;




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...


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, 19:31:10
Gracias
Crea un hilo para tu pregunta. gracias.

MAXIUM
24-08-2018, 01: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, 01:14:02
https://i.imgur.com/fAyw3u1.png

MAXIUM
24-08-2018, 01:24:48
https://i.imgur.com/7CRhnvX.png

Casimiro Notevi
24-08-2018, 10:56:47
¿El fabricante no tiene nada?

MAXIUM
24-08-2018, 18:48:05
¿El fabricante no tiene nada?

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

https://i.imgur.com/1gH5PwM.png

https://i.imgur.com/zFryHxn.png