Huella Digital. Lector Microsoft Reader. GRFinger ActiveX

Post Reply
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Huella Digital. Lector Microsoft Reader. GRFinger ActiveX

Post by Daniel Asensio »

Con alguno de los ejemplos sobre huella digital de este foro y el control activeX GRFinger he conseguido que llegue hasta devolver el evento ImageAdquired, el problema es que no devuelve en el array 4 la imagen de la huella ("The raw grayscale fingerprint image") y luego ya no se puede recuperar como bitmap.

¿ Es el activeX de Fivewin el que no recoge el valor de ese dato ?
En el manual dice: rawImage As Variant

Es posible si se recoge el dato, hacer luego la llamada con 6 parametros o con 9 con la otra llamada a biometricdisplay:

oFingerX:Do("CapRawImageToHandle", raw:img, raw:width, raw:height, oWnd:hDC, @handle )

Tiene alguien una solución para lectura de huella digital con algun lector similar.

Saludos

Code: Select all

#include "FiveWin.ch"

STATIC oWnd
STATIC oFingerX

FUNCTION Main()

IF IsActiveX("GrFingerX.GrFingerXCtrl")

  DEFINE WINDOW oWnd TITLE "FiveWin ActiveX Support"

  @ 10 , 10 BITMAP oFoto RESOURCE "LOGOIPG" OF oWnd SIZE 100,50 PIXEL NOBORDER

  oFingerX = TActiveX():New( oWnd, "GrFingerX.GrFingerXCtrl", 1,1,10,10)

 *oWnd:oClient = oFingerX

  oFingerX:Do("Initialize")

  contextId:= 0
  oFingerX:Do("CreateContext",contextId)

  oFingerX:Do("CapInitialize")

  oFingerX:bOnEvent = { | event, aParams, pParams | EventInfo( event, aParams, pParams, oFingerX ) }

  ACTIVATE WINDOW oWnd

  oFingerX:Do("CapFinalize")
  oFingerX:Do("Finalize")

ELSE

  MsgStop("TIENE QUE ESTAR INSTALADO GRFINGER","ATENCION")

ENDIF

RETURN nil

***

FUNCTION EventInfo( event, aParams, pParams, oFingerX )
Local cEvent := cValToChar( event )
Local cMsg := "Event: " + cValToChar( event ) + CRLF
Local n

cMsg += "Params: " + CRLF

FOR n = 1 to Len( aParams )
   cMsg += cValToChar( aParams[ n ] ) + CRLF
NEXT

IF cEvent == "SensorPlug" .or. cEvent == "1"
  IF aParams[1] != "File"
    oFingerX:Do("CapStartCapture","DPMSA077A3")
  ENDIF
ELSE
  IF cEvent == "SensorUnplug"
    oFingerX:Do("CapStopCapture","DPMSA077A3")
  ELSE
    IF cEvent == "FingerDown" .or. cEvent = "4"
    ELSE
      IF cEvent == "FingerUp" .or. cEvent = "3"
      ELSE
        IF cEvent == "ImageAcquired" .or. cEvent = "5"
          MsgInfo(Valtype(aParams[4]))
          *raw:img    = aParams[ 4] //rawImage
          *raw:height = aParams[ 3] //height
          *raw:width  = aParams[ 2] //width
          *raw:res    = aParams[ 5] //res
          *PrintBiometricDisplay( .F. , 0 )
        ENDIF
      ENDIF
    ENDIF
  ENDIF
ENDIF

RETURN NIL

***

STATIC FUNCTION PrintBiometricDisplay(biometricDisplay, context )
Local nRet, Handle

If biometricDisplay
  *oFingerX:Do("biometricdisplay", template:tpt, raw:img, raw:width, raw:height, raw:res, oWnd:hDC, @handle, context)
Else
   oFingerX:Do("CapRawImageToHandle", raw:img, raw:width, raw:height, oWnd:hDC, @handle )
End If

MsgInfo(handle)

*IF !(handle ==NIL)
*  oFoto:Picture = handle
*  oFoto:Update()
*ENDIF

RETURN NIL
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Daniel,

Que valores tienes en ?

MsgInfo(Valtype(aParams[4]))
y
MsgInfo(Valtype(aParams[3]))
regards, saludos

Antonio Linares
www.fivetechsoft.com
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

MsgInfo(aParams[3])
390
MsgInfo(Valtype(aParams[3]))
N
MsgInfo(aParams[4])
nil
MsgInfo(Valtype(aParams[4]))
U

MsgInfo(cMsg)

Event: ImageAcquired
Params:
DPMSA077A3
355
390
(aqui iria el 4 y sale en blanco)
500

Saludos
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Daniel,

> En el manual dice: rawImage As Variant

Es un handle a un bitmap lo que debe ir ahí ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

Creo que contiene caracteres hasta 10000 que luego se pasan como parametros a otra funcion que los convierte en bitmap en la variable handle.

Hay muchos ejemplos de uso en varios lenguajes de programación C#, C++.NET, Delphi, Java, Visual Basic, VB.Net y Visual FoxPro 8, pero no se como adaptar las llamadas a Harbour.

Saludos

GrCapRawImageToHandle(unsigned char* rawImage, unsigned int width, unsigned int height, HDC hdc, HBITMAP &handle);

Este es un fichero de cabecera.

Code: Select all

/******************************************************
 *                                                    *
 *                  GrFinger 4.2 SDK                  *
 *       GrFinger Biometric Fingerprint Library       *
 *                                                    *
 * GrFinger.h                                         *
 * C++ Header file for GrFinger Library               *
 *                                                    *
 * Copyright (c) 2004-2006 Griaule Tecnologia LTDA.   *
 *                                                    *
 * Last Modified: 2006-05-23 Revision: 3              *
 *                                                    *
 ******************************************************/

#ifndef IMPORTDLL_H
#define IMPORTDLL_H
#include "windows.h"

//*****************************************************
//RETURN CODES
//*****************************************************
//success
#define GR_OK                                         0
#define GR_BAD_QUALITY                                0
#define GR_MEDIUM_QUALITY                             1
#define GR_HIGH_QUALITY                               2
#define GR_MATCH                                      1
#define GR_NOT_MATCH                                  0
#define GR_DEFAULT_USED                               3
//initialization errors codes
#define GR_ERROR_INITIALIZE_FAIL                     -1
#define GR_ERROR_NOT_INITIALIZED                     -2
#define GR_ERROR_FAIL_LICENSE_READ                   -3
#define GR_ERROR_NO_VALID_LICENSE                    -4
#define GR_ERROR_NULL_ARGUMENT                       -5
#define GR_ERROR_FAIL                                -6
#define GR_ERROR_ALLOC                               -7
#define GR_ERROR_PARAMETERS                          -8
//extract and match errors codes
#define GR_ERROR_WRONG_USE                         -107
#define GR_ERROR_EXTRACT                           -108
#define GR_ERROR_SIZE_OFF_RANGE                    -109
#define GR_ERROR_RES_OFF_RANGE                     -110
#define GR_ERROR_CONTEXT_NOT_CREATED               -111
#define GR_ERROR_INVALID_CONTEXT                   -112
#define GR_ERROR_ERROR                             -113
#define GR_ERROR_NOT_ENOUGH_SPACE                  -114
//capture error codes
#define GR_ERROR_CONNECT_SENSOR                    -201
#define GR_ERROR_CAPTURING                         -202
#define GR_ERROR_CANCEL_CAPTURING                  -203
#define GR_ERROR_INVALID_ID_SENSOR                 -204
#define GR_ERROR_SENSOR_NOT_CAPTURING              -205
#define GR_ERROR_INVALID_EXT                       -206
#define GR_ERROR_INVALID_FILENAME                  -207
#define GR_ERROR_INVALID_FILETYPE                  -208
#define GR_ERROR_SENSOR                            -209

//*****************************************************
//CONSTS
//*****************************************************
//file format codes
#define GRCAP_IMAGE_FORMAT_BMP                      501
//event values codes
#define GR_PLUG                                      21
#define GR_UNPLUG                                    20
#define GR_FINGER_DOWN                               11
#define GR_FINGER_UP                                 10
#define GR_IMAGE                                     30
//image consts 
#define GR_DEFAULT_RES                              500
#define GR_DEFAULT_DIM                              500
#define GR_MAX_SIZE_TEMPLATE                      10000
#define GR_MAX_IMAGE_WIDTH                         1280
#define GR_MAX_IMAGE_HEIGHT                        1280
#define GR_MAX_RESOLUTION                          1000 /*DPI*/
#define GR_MIN_IMAGE_WIDTH                           50
#define GR_MIN_IMAGE_HEIGHT                          50
#define GR_MIN_RESOLUTION                           125 /*DPI*/
//match const
#define GR_MAX_THRESHOLD                            200
#define GR_MIN_THRESHOLD                             10
#define GR_VERYLOW_FRR                               30 /*FAR 1 IN 1000*/
#define GR_LOW_FRR                                   45 /*FAR 1 IN 10000*/
#define GR_LOW_FAR                                   60 /*FAR 1 IN 30000*/
#define GR_VERYLOW_FAR                               80 /*FAR 1 IN 300000*/
#define GR_ROT_MIN                                    0
#define GR_ROT_MAX                                  180
//context const
#define GR_DEFAULT_CONTEXT                            0
#define GR_NO_CONTEXT                                -1
//colors for BiometricDisplay
#define GR_IMAGE_NO_COLOR                    0x1FFFFFFF
//version constants
#define GRFINGER_FULL                                 1
#define GRFINGER_LIGHT                                2
#define GRFINGER_FREE                                 3

//*****************************************************
//TYPE DEFINITIONS
//*****************************************************
#define DLLIMPORT extern "C" __declspec(dllimport) int __stdcall
#define CALLBACK __stdcall
typedef int GRCAP_STATUS_EVENTS;
typedef int GRCAP_FINGER_EVENTS;
typedef int GRCAP_IMAGE_FORMAT;
typedef long BITMAP_HANDLE;
//CALLBACK functions
typedef void CALLBACK GRCAP_STATUS_EVENT_PROC(char* idSensor, GRCAP_STATUS_EVENTS event);
typedef void CALLBACK GRCAP_FINGER_EVENT_PROC(char* idSensor, GRCAP_FINGER_EVENTS event);
typedef void CALLBACK GRCAP_IMAGE_EVENT_PROC(char* idSensor, unsigned int width, unsigned int height, unsigned char* rawImage, int res);

//*****************************************************
// Functions - CAPTURE
//*****************************************************
DLLIMPORT
GrCapInitialize(GRCAP_STATUS_EVENT_PROC *StatusEventHandler);

DLLIMPORT
GrCapFinalize();

DLLIMPORT
GrCapStartCapture(char* idSensor, GRCAP_FINGER_EVENT_PROC *FingerEventHandler, GRCAP_IMAGE_EVENT_PROC *ImageEventHandler);

DLLIMPORT
GrCapStopCapture(char* idSensor);

DLLIMPORT
GrCapSaveRawImageToFile(unsigned char* rawImage, unsigned int width, unsigned int height, char* fileName, GRCAP_IMAGE_FORMAT imageFormat);

DLLIMPORT
GrCapLoadImageFromFile(char* fileName, int res);

DLLIMPORT
GrCapRawImageToHandle(unsigned char* rawImage, unsigned int width, unsigned int height, HDC hdc, HBITMAP &handle);

DLLIMPORT
GrBiometricDisplay(char* tptQuery, unsigned char* rawImage, int width, int height, int res, HDC hdc, HBITMAP &handle, int matchContext);

//*****************************************************
// Functions - EXTRACT
//*****************************************************
DLLIMPORT
GrExtract(unsigned char *rawimage, int width, int height, int res, char *tpt, int *tptSize, int context);

//*****************************************************
// Functions - MATCH
//*****************************************************
DLLIMPORT
GrInitialize();

DLLIMPORT
GrFinalize();

DLLIMPORT
GrCreateContext (int *contextId);

DLLIMPORT
GrDestroyContext (int contextId);

DLLIMPORT
GrVerify (char *queryTemplate, char *referenceTemplate, int *verifyScore, int context);

DLLIMPORT
GrIdentifyPrepare (char *templateQuery, int context);

DLLIMPORT
GrIdentify (char *templateReference, int *identifyScore, int context);

//*****************************************************
// Functions - CONFIG
//*****************************************************
DLLIMPORT
GrSetIdentifyParameters (int identifyThreshold, int identifyRotationTolerance, int context);

DLLIMPORT
GrSetVerifyParameters (int verifyThreshold, int verifyRotationTolerance, int context);

DLLIMPORT
GrGetIdentifyParameters(int &identifyThreshold, int &identifyRotationTolerance, int context);

DLLIMPORT
GrGetVerifyParameters(int &verifyThreshold, int &verifyRotationTolerance, int context);

DLLIMPORT
GrSetBiometricDisplayColors(int minutiaeColor, int minutiaeMatchedColor, int segmentColor, int segmentMatchedColor, int directionColor, int directionMatchedColor);

DLLIMPORT
GrGetGrFingerVersion(unsigned char *majorRelease, unsigned char *minorRelease);

#endif
Saludos

Daniel Asensio
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Daniel,

Te envio por email una librería. Por favor construye el EXE con esa nueva librería y te aparecerá un MsgInfo() con un valor que necesito me digas cual es, gracias
regards, saludos

Antonio Linares
www.fivetechsoft.com
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

Me dice:

tipo 8209

Gracias
Saludos

Daniel Asensio
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Daniel,

Te hemos enviado una librería modificada que ya debería devolver un número (puntero) en la posición cuarta del array
regards, saludos

Antonio Linares
www.fivetechsoft.com
fleal
Posts: 234
Joined: Tue Oct 25, 2005 12:39 am
Location: México, DF

Licencia

Post by fleal »

Daniel,
¿Tu entiendes el asunto de las licencias de Griaule?

Según yo.
La licencia integrador Ligt o Full se compra una sola vez. La puedes instalar en ilimitado número de PCs.
El programa que tu creas. El EXE cuando se instala en otra pc deberás pagar una licencia. Desde los 37 dolares.
Entonces, es pagar por el SDK y pagar por cada instalación que se realize.
Ahora, la licencia del Microsoft Fingerprint prohibe usar el lector como producto integrador. Es decir, solo podrá ser usado para los propositos señalados en la licencia de aceptación del producto. Como llave para ingresar a una pc. No podrá ser usado como parte de otro producto.
La buena noticia es que el mismo driver sirve para el Digital Persona y ese es lo contrario. Es un producto para integradores.
Por último solo el mensaje de alguien que envio un mensaje a Microsoft y en respuesta le dicen que tienen pensando sacar un fix para evitar que los lectores de su marca funcionen con la libreria de Griaule por que violan la licencia de uso.

Asi pues yo he descartado el usar Griaule y revisar otro como el de Kimaldi o el mismo Digital Persona.

Gracias
Fernando Leal
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

Fernando,

El utilizar ese modelo de lector para las pruebas es porque lo tenia a mano, lo compre hace un año para probar y hasta ahora no lo habia usado.

En caso de venta a clientes no seria ese modelo, parece demasiado sencillo para utlizarlo de continuo en fichajes.

Pense en GrFinger, porque permite hasta 5 modelos diferentes de lectores y desarrollando una sola vez puedo luego elegir entre varios aparatos. No estoy limitado a un modelo concreto.

Tampoco me parece excesivo el precio por instalación. En principio son para pocas instalaciones.

De todas formas mirare esas otras alternativas.

Gracias
Saludos

Daniel Asensio
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

Fernando,

Sobre las licencias de GrFinger si que esta un poco liado:

En su pagina de precios en el SDK LIGHT hay un [?] que acercando el raton enseña este texto:

Code: Select all

Si compra Licencias de Integrador, usted paga solo una vez y puede desarrollar la aplicación basada en GrFinger en un numero ilimitado de computadoras. Tome en cuenta que usted también puede desarrollarlo usando nuestra licencia de prueba, ubicada en la página de Descargas.
Luego para desarrollarlo no necesitas el SDK, basta con la licencia de prueba y 37 Dolares por instalación del EXE

¿ Y si la compras puedes instalarla ilimitadas veces ? O tambien hace falta 37 Dolares por EXE. No esta claro. Pero se supone que no hara falta pagar por instalación.

No lo he consultado todavia con ellos, primero tengo que saber que podre usarla desde Fivewin, que parece que si.
Saludos

Daniel Asensio
fleal
Posts: 234
Joined: Tue Oct 25, 2005 12:39 am
Location: México, DF

Suerte

Post by fleal »

Daniel,
Este es el post con la info.
A ver que le entiendes tu. :-) Yo la verdad estoy confundido, pero ya ando viendo otros SDK mientras tanto.
http://forum.griaule.com/viewtopic.php?t=3948

¿Cómo lo he solucionado?
Bueno, tengo una aplicación en VB 6.0 y tengo otra aplicación en FWH o si, seguramente pensarás entonces que ya uso el lector de huella con FWH. Pues si y no.
Verás yo uso el Desktop Identity tambien de Griaule. Ese programa registra la huella de los usuarios... El truco está en que el programa se queda residente y cuando pones el dedo en lector este envia el ID asociado de la huella a cualquier aplicación abierta. Pruebalo, verás que funciona como un lector de Códigos de Barras. El resultado lo muestra en cualquier programa. Asi pues, mi programa está en un get y cuando recibe algo lo busca en mis base de usuarios, encuentra el ID y marco la entrada o salida... según sea el caso.
Espero haberme explicado. Es una solución muy trucha.
Pero de momento me vale.
ramirezosvaldo
Posts: 101
Joined: Mon Oct 10, 2005 6:48 pm
Location: Cd. Juarez Chihuahua
Contact:

Post by ramirezosvaldo »

Daniel

A lo mejor el problema esta en el ActiveX,

Te comento que inicie a hacer pruebas con el ActiveX de Xbase++ pero no di con bola.

Entonces me anime a usar DLL, y claro con la Ayuda de Pablo Botella, lo echamos a jalar, en mis pruebas ya se visualiza la huella, la grabo y despues comparo con mi DBF.

Te recomiendo que te inclines por DLL, la libreria o ejemplos que realizamos estan sencillos y con toda confianza mandame un correo privado.

Saludos
Osvaldo Ramirez
Daniel Asensio
Posts: 7
Joined: Fri May 18, 2007 3:26 pm

Post by Daniel Asensio »

Despues de muchas pruebas he conseguido que funcione leer la huella, guardarla y luego compararla y saber si es o no correcta. Con una mezcla entre activex y llamadas a la libreria.

El problema es que aleatoriamente se produce un GPF.

Tambien sucede el GPF si cargo la DLL al principio y la descargo al finalizar. Y tambien si comento el bloque del ImageAdquired.

Tiene alguien otra forma de hacerlo.

Code: Select all


#include "FiveWin.ch"

STATIC oWnd

STATIC ttptSize
STATIC ttpt

STATIC lProcesandoHuella

FUNCTION Main()
Local oFingerX

cStatus:= Space(1000)

lProcesandoHuella:= .F.

cAntes:= Memoread("LECTURA1.DAT")

IF IsActiveX("GrFingerX.GrFingerXCtrl")

  DEFINE WINDOW oWnd TITLE "FiveWin ActiveX Support"

  oFingerX = TActiveX():New( oWnd, "GrFingerX.GrFingerXCtrl.1")

  oWnd:oClient = oFingerX

  oFingerX:Do("Initialize")

  oFingerX:Do("CapInitialize")

  oFingerX:bOnEvent = { | event, aParams, pParams | EventInfo( event, aParams, pParams, oFingerX) }

  ACTIVATE WINDOW oWnd ON INIT IniciaHuella(oFingerX) VALID SalirHuella(oFingerX)

ELSE

  MsgStop("TIENE QUE ESTAR INSTALADO GRFINGER","ATENCION")

ENDIF

RETURN NIL

***

FUNCTION IniciaHuella(oFingerX)

RETURN NIL

***

FUNCTION SalirHuella(oFingerX)

oFingerX:Do("CapStopCapture","DPMSA077A3")

oFingerX:Do("CapFinalize")
oFingerX:Do("Finalize")

RETURN ( .T. )

***

FUNCTION EventInfo( event, aParams, pParams, oFingerX )
Local cEvent

IF .not. lProcesandoHuella

  cEvent := cValToChar( event )

  IF cEvent == "SensorPlug" .or. cEvent == "1"
    IF aParams[1] != "File"
      oFingerX:Do("CapStartCapture","DPMSA077A3")
    ENDIF
  ELSE
    IF cEvent == "SensorUnplug"
      oFingerX:Do("CapStopCapture","DPMSA077A3")
    ELSE
      IF cEvent == "FingerDown" .or. cEvent = "4"
      ELSE
        IF cEvent == "FingerUp" .or. cEvent = "3"
        ELSE
          IF cEvent == "ImageAcquired" .or. cEvent = "5"

            lProcesandoHuella:= .T.

            xLib:= LoadLibrary("GrFinger.dll")

            GrInitialize()

            ttptSize = 10000
            ttpt = SPACE(10000)

            ret:= GrExtract( aParams[ 4], aParams[ 2], aParams[ 3], aParams[ 5], @ttpt, @ttptSize, 0 )

           * Forma 1
           *
           *GrIdentifyPrepare( ttpt, 0 )
           *nIdScore:= 0
           *nId:= GrIdentify( cAntes, @nIdScore , 0 )

           * Forma 2

            nIdScore:= 0
            nId:= GrVerify( ttpt , cAntes, @nIdScore , 0 )

            *Memowrit("PRUEBA",Subs(ttpt,1,ttptSize))

            ttpt:= ""

            oWnd:cTitle(Time()+" "+Str(ret)+" "+Str(nId)+" "+Str(nIdScore))

            SysWait(1)

            GrFinalize()

            FreeLibrary(xLib)

            lProcesandoHuella:= .F.

          ENDIF

        ENDIF
      ENDIF
    ENDIF
  ENDIF

ENDIF

RETURN NIL

***


DLL32 FUNCTION GrInitialize() AS LONG PASCAL FROM "_GrInitialize@0" LIB xLib
DLL32 FUNCTION GrFinalize() AS LONG PASCAL FROM "_GrFinalize@0" LIB xLib

*DLL32 FUNCTION GrCapInitialize(status AS LPSTR) AS LONG PASCAL FROM "_GrCapInitialize@4" LIB xLib

DLL32 FUNCTION GrExtract( rawImage AS LONG, width AS LONG, height AS LONG, res AS LONG, ttpt AS LPSTR, @ttptSize AS LONG , context AS LONG ) AS LONG PASCAL FROM "_GrExtract@28" LIB xLib

DLL32 FUNCTION GrIdentifyPrepare( ttpt AS LPSTR, context AS LONG ) AS LONG PASCAL FROM "_GrIdentifyPrepare@8" LIB xLib
DLL32 FUNCTION GrIdentify( ttpt AS LPSTR, @Idscore AS LONG, context AS LONG ) AS LONG PASCAL FROM "_GrIdentify@12" LIB xLib

DLL32 FUNCTION GrVerify( ttpt AS LPSTR, qtpt AS LPSTR, @Idscore AS LONG, context AS LONG ) AS LONG PASCAL FROM "_GrVerify@16" LIB xLib

Saludos

Daniel Asensio
mikelinos
Posts: 1
Joined: Sun Jul 18, 2010 3:36 am

Re: Huella Digital. Lector Microsoft Reader. GRFinger ActiveX

Post by mikelinos »

Hola daniel!

Espero te encuentres bien, la pregunta es ver si tu me podrías orientar sobre como hacer una aplicación de control de asistencia vía microsoft fingerprint.

Acabo de ver que tienes algun ejemplo, pero me gustaria saber si me podrias explicar como hacerlo, y saber si tienes algun codigo fuente para guiarme.

Saludos mi correo es miguel21_0529@hotmail.com
Post Reply