Capturar firma en VFP

2,704 views
Skip to first unread message

Victor Espina

unread,
Aug 24, 2012, 11:16:17 AM8/24/12
to publice...@googlegroups.com
En respuesta a un post que aparecio aqui y en el grupo de facturacion electronica de Mexico, relativo a como capturar la firma de una persona de manera electronica en VFP, recorde un ejemplo que habia visto hace algunos anos de como dibujar en forma libre en VFP usando GDIPlusX.

Luego de buscar un poco encontre el proyecto VFP Paint del maestro Cesar Chalom, el cual logro crear, ni mas ni menos, que un clon de Paint dentro de form de VFP, usando solo codigo VFP y GDIPlusX. Explorando ese proyecto encontre que Cesar habia creado una version "liviana" que ofrecia exactamente lo que yo estaba buscando:

a) Un area o "canvas" donde el usuario pudiera hacer un dibujo
b) Una forma de grabar ese dibujo en un archivo de imagen indicado

Luego de hechar una rapida revision al codigo me di cuenta que Cesar ya habia hecho practicamente todo el trabajo; lo unico que tuve que hacer fue:

a) Tomar el Form y convertirlo en una clase basada en Container

b) Cambiar todas las referencias a "THISFORM" por "THIS".

c) Reubicar todos los controles de edicion de modo que los mismos quedaran fuera del area visible, de modo que el control se redujera solamente al "canvas" o area de dibujo.

d) Crear un par de propiedades para poder cambiar el ancho y color del trazo:

THISFORM.canvasFirma.penSize = 4  && en pixels
THISFORM.canvasFirma.penColor = RGB(0,0,0)  && negro

e) Tomar el codigo del boton Save y crear un metodo "Save" con ese codigo:

THISFORM.canvasFirma.Save("firma.png")


El resultado lo pueden ver en la imagen anexa y la clase la pueden descargar desde aqui:



Saludos

Victor Espina


Rick C. Hodgin

unread,
Aug 24, 2012, 11:20:29 AM8/24/12
to publice...@googlegroups.com
This can also be done by using Win32 calls, creating a DibSection bitmap buffer, writing fonts or drawing to it, saving to disk as a BMP file, and using an existing Visual FoxPro image class object to load the image.  If not using an alpha channel, use RGB(255,255,255) color for transparent.

Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 11:23:39 AM8/24/12
to publice...@googlegroups.com
Por cierto, creo que aqui se abre una ventana para que nuestro apreciado Don Edgar Kummers nos colabore con una funcion que, al darle dos firmas digitales, nos pueda decir el grado o % de coincidencia que tienen.

Don Edgar, ahi le dejo ese reto :)

Victor Espina

On Friday, August 24, 2012 11:16:17 AM UTC-4, Victor Espina wrote:

Victor Espina

unread,
Aug 24, 2012, 11:29:10 AM8/24/12
to publice...@googlegroups.com
I'm sure you are right. I just don't have the Win32 API knowledge to pull this out. 

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 11:30:12 AM8/24/12
to publice...@googlegroups.com
If interested I can help.


Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 11:34:34 AM8/24/12
to publice...@googlegroups.com
Sure!! The goal is to create a container-based VFP class that allow  an end-user to create a drawing using a pen or mouse and offers a "Save" method that saves that drawing to a BMP, JPG o PNG file, with the minimal dependency possible.

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 11:39:58 AM8/24/12
to publice...@googlegroups.com
Okay, if this is the goal then it is even easier. :-)

You can use VFP's tools to draw points, line to line, circles, etc, and then you can save what's on the window's "client area" (what the user sees on the form) using a Win32 copy and save from its device context to a generic bitmap, which can then be saved to disk.  Another simpler option would be to use Alt+PrintScreen to copy the bitmap data to the clipboard, and then process it using a tiny C program which you load as a DLL.

I will help you with any of these options, but it will have to be tonight after 6pm.  Right now it is 11:40am here in Indiana, USA where I am.


Best regards,
Rick C. Hodgin

Message has been deleted

Victor Espina

unread,
Aug 24, 2012, 11:49:12 AM8/24/12
to publice...@googlegroups.com
Same time here in Chile.  Take in consideration that the control's only goals sould be:

a) Show an empty drawing canvas
b) Allow the end-user to creating a drawing either using a mouse or a pen
c) Allow to save that drawing to an image file (by code)
d) Optionally, offers properties or methods to set pen's size and color.

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 11:51:45 AM8/24/12
to publice...@googlegroups.com
Victor,

No problem.  Easy peasy. :-)  Do you want me to write it for you?  Or just to tell you how to write it? :-)


Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 11:56:58 AM8/24/12
to publice...@googlegroups.com
No please, you go for it. I'll just learn from what you do :)

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 12:01:01 PM8/24/12
to publice...@googlegroups.com
Is it okay for me to create a 32-bit C/C++ DLL to make easier?


Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 12:09:34 PM8/24/12
to publice...@googlegroups.com
Yes. A lot better would be to link the Win32 API functions directly from VFP using DECLARE, but I'm aware the PITA that is to handle structs in VFP.  

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 12:16:00 PM8/24/12
to publice...@googlegroups.com
It should be doable.  I'll try.  If I spend more than an hour I'll switch to the DLL. :-)


Best regards,
Rick C. Hodgin

Cesar VfpImaging

unread,
Aug 24, 2012, 3:36:37 PM8/24/12
to publice...@googlegroups.com
Guys,

Why to reinvent the wheel ?
Rick, Victor is using a VFP form that uses GdiPlusX, that is a wrapper that we created to use the Gdiplus.dll functions, exactly the way we have them using the System.Drawing namespace in .NET.

Of course, it's doable, but why do it all again ?

Cheers

Cesar


--
 
 
 

Rick C. Hodgin

unread,
Aug 24, 2012, 3:40:22 PM8/24/12
to publice...@googlegroups.com
No reason. And I'm perfectly okay to NOT write it. :-) I didn't know
what the existing software was.

The solution I was going to implement uses GDI and Win32 only. Would
work on Win95/98/ME/2K machines as well.

Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 4:16:11 PM8/24/12
to publice...@googlegroups.com
Cesar, first I apologize for not asking for your permission to use your code this way; in my defense I can say I was too exited to wait :)

Could be any way to use another control as a drawing context instead a form?  I understand that you use a form in order to use it's hWnd context, but to be honest I didn't like too much the "on-the-fly-form" solution. Any ideas on this?

Amazing work, by the way,what  you did with VFP Paint.

Victor Espina

Walter R. Ojeda Valiente

unread,
Aug 24, 2012, 4:22:29 PM8/24/12
to publice...@googlegroups.com
Hola Víctor

¿Y cuál sería la utilidad de esa clase, para qué podríamos utilizarla?

Saludos.

Walter.





Date: Fri, 24 Aug 2012 08:16:17 -0700
From: vesp...@gmail.com
To: publice...@googlegroups.com
Subject: [vfp] Capturar firma en VFP
--
 
 
 

Cesar VfpImaging

unread,
Aug 24, 2012, 4:37:31 PM8/24/12
to publice...@googlegroups.com
Yes Rick, the current version works on all windows versions. (WinNT4 and 95 included)
I even tried it under Linux just for fun, and all worked normally. It depends only on the gdiplus.dll that comes with VFP9 as an obligatory dll.

Your solution would be very similar!
The wrapper class uses the Win32 API, GDI and GDI+
The purpose of it is to ease the usage of graphics functions.



--




Victor Espina

unread,
Aug 24, 2012, 4:38:31 PM8/24/12
to publice...@googlegroups.com
Pues para capturar firmas digitalmente en un proceso "paper-free".  Por ejemplo, ahora estoy en una implantacion de un cliente que distribuye autos y parte del sistema es un modulo que ejecuta en una tablet y que le sirve al personal, entre otras cosas, para registrar los datos de un vehiculo cuando ingresa al taller por reparacion o mantenimiento.

Actualmente el usuario puede registrar en el table toda la informacion del vehiculo (kilometraje, inventario, defectos visibles), pero luego tiene que imprimir esa informacion en una hoja para que el cliente la firme como conforme.

Con esta clase, esto no seria necesario sino que el usuario podria pedirle al cliente que revise la informacion directo en el tablet y, si esta conforme, firme en conformidad directamente en el tablet y esta firma se almacenaria de modo que si, mas adelante el cliente presentara algun reclamo, se le podria demostrar que el "firmo" que estaba de acuerdo con la inspeccion realizada por el usuario.

En un hotel por ejemplo, serviria para que un huesped pueda firmar su cuenta en el restaurant y el administrador pueda verificar dicha firma contra una firma "autorizada" registrada previamente en el sistema en forma electronica cuando el huesped se registro.

De hecho, si Edgard nos echa una mano aqui, hasta se podria validar automaticamente si la firma es valida o no.

En fin, tiene muchas aplicaciones en muchas areas.  Claro, tambien hay productos, tanto software como hardware, que se especializa en esta area. Pero si el presupuesto es limitado (como es la norma en nuestro caso) esta clase te permitiria ofrecer un gran valor agregado a tus clientes.

Saludos

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 4:44:36 PM8/24/12
to publice...@googlegroups.com
What is your API?  I have created a "graphics" object for VFrP that handles graphics functions for VFrP's bit buffers.


Best regards,
Rick C. Hodgin

Cesar VfpImaging

unread,
Aug 24, 2012, 4:47:14 PM8/24/12
to publice...@googlegroups.com
Hi Victor,

>>Cesar, first I apologize for not asking for your permission to use your code this way; in my defense I can say I was too exited to wait :)

There's absolutely no need to apologize. VFP Paint is Open Source. I'm glad you found some uses for it.
My goal was to generate a working sample for people to get encouraged to work with GdiPlusX. I personally have an empowered version of it, that I use to do more complex drawings, integrated to one of my apps.


>>Could be any way to use another control as a drawing context instead a form?  I understand that you use a form in order to use it's hWnd context, but to be honest I didn't like too much the "on-the-fly-form" solution. Any ideas on this?

Not really the real trick in VFPPaint is that there we're drawing directly on the main VFP screen surface, not in the form! I catch the HWND, and send the Drawing commands directly to the Screen. Meanwhile, I capture the click positions, and store a copy in a separate Bitmap object.

Saludos

Cesar


--
 
 
 

Victor Espina

unread,
Aug 24, 2012, 4:50:06 PM8/24/12
to publice...@googlegroups.com
So, why did you use a form (I'm talking about the dinamically-generated form you created with TEXT-ENDTEXT in the AfterInit event) instead of, lets say, a GDI ImageCanvas object ?

Victor Espina

Rick C. Hodgin

unread,
Aug 24, 2012, 4:50:16 PM8/24/12
to publice...@googlegroups.com
Cesar, that is EXACTLY what I was going to do. :-)  Awesome.

I implemented a GridX class in VFP6 that used an extended form of drawing on the VFP DC.  I used got the WndProc address and replaced with my own, intercepted WM_PAINT, and then drew where I wanted to, and then ValidateRect() my areas, then call original wndproc.

You used GDI+ for the simplified rendering to your own canvas / bit buffer?


Best regards,
Rick C. Hodgin

Victor Espina

unread,
Aug 24, 2012, 4:52:12 PM8/24/12
to publice...@googlegroups.com
Rick, as I stated in the initial post, this is not my code but Cesat's. All I did was to convert it from a VFP Form to a container-based class in a VFP class library. All I know about how it works is that its based on GDIPlusX.

Regards

Victor Espina

Walter R. Ojeda Valiente

unread,
Aug 24, 2012, 4:54:48 PM8/24/12
to publice...@googlegroups.com
¿Y te parece que una persona que no está habituada a usar esos dispositivos podría firmar de manera similar a cuándo lo hace con un lápiz?

Me refiero a los clientes del taller mecánico o del restaurante. Algunos quizás no hayan usado una computadora en su vida. ¿La firma que estampen sería similar a la que escribirían en un papel?

Saludos.

Walter.




Date: Fri, 24 Aug 2012 13:38:31 -0700
From: vesp...@gmail.com
To: publice...@googlegroups.com
Subject: Re: [vfp] Capturar firma en VFP
--
 
 
 

Oscar Díaz

unread,
Aug 24, 2012, 4:56:31 PM8/24/12
to publice...@googlegroups.com
Estimado Victor:

Muchas gracias por el ajuste que hizo, yo utilizo la versión del maestro Cesar Chalom,
pero esta me parece más sencilla para el cliente, la uso en el programa que desarrolle para los odontologos, www.dentagrama.com ellos la utilizan para que el paciente firme los consentimientos informados, que es la información que el Dr. le lee al paciente indicandole lo que le va a realizar y el paciente, debe firmar que está deacuerdo.

Pienso que a futuro TODOS tendremos la firma digitalizada y registrada para hacer cualquier trámite.

Saludos desde Bogotá.co

--
 
 
 

Cesar VfpImaging

unread,
Aug 25, 2012, 3:04:02 PM8/25/12
to publice...@googlegroups.com
Hi Victor,

>>So, why did you use a form (I'm talking about the dinamically-generated form you created with TEXT-ENDTEXT in the AfterInit event) instead of, lets say, a GDI ImageCanvas object ?

Aha,

That's because I wanted to make the drawing canvas to be scrollable. Notice that I put a form inside another. The inner form allows you to use the scrollbars to expand the drawing panel.
Only for that reason :-D




--
 
 
 

Cesar VfpImaging

unread,
Aug 25, 2012, 3:16:31 PM8/25/12
to publice...@googlegroups.com
Hi Rick,

>>I implemented a GridX class in VFP6 that used an extended form of drawing on the VFP DC.  I used got the WndProc address and replaced with my own, intercepted WM_PAINT, and then drew where I wanted to, and then ValidateRect() my areas, then call original wndproc.

Oh, very interesting. In VFP9 we have the enhanced BINDEVENTS command that allows us to intercept the windows events, how did you manage to intercept WM_PAINT in VFP6 ? I presume that you've created an external library, FLL or DLL bringing a function for that ?
What exactly did your Extended Grid class do ? Any screenshots?



>>You used GDI+ for the simplified rendering to your own canvas / bit buffer?

VFP Paint draws directly in the form surface, using some basic GDI+ commands. When the user releases the mouse button, I draw the line again in a GDI bitmap object.
VIsit this link to have an idea of what I'm talking about

Cheers

Cesar



--
 
 
 

Victor Espina

unread,
Aug 25, 2012, 3:24:33 PM8/25/12
to publice...@googlegroups.com
I understand. I will try to modify the code to remove the need of that form and try tu use an ImageCanvas instead because I my case the canvas doesn't need to be scrollable.

Thsnks for your answer

Victor Espina

Rick C. Hodgin

unread,
Aug 25, 2012, 3:26:01 PM8/25/12
to publice...@googlegroups.com
Cesar,


>how did you manage to intercept WM_PAINT in VFP6 ?
>I presume that you've created an external library, FLL or DLL
>bringing a function for that ?

Yes.  I had created a generic UTILS.DLL that was a catch-all for all additions.  The DLL would intercept those events and allow me to draw directly onto the VFP form.


>What exactly did your Extended Grid class do ?
>Any screenshots?

It was for a project that I haven't worked on since late 2005.  The grid allowed columns in a narrow grid.  Suppose you have a two-column grid that is a 9-digit general ledger account code, and an amount.  Rather than take up lots of vertical screen space, I created the GridX class to allow a multi-column form.  The data begins in the upper-left-most position, drawing down for its height, and then once reaching its maximum, displays an arrow which goes up to the top of another column which appears to its right.  That column then proceeds down until it reaches its height, and then this repeats until the width is reached.  Using the up/down arrows scrolls down each column to the top of the next, and repeats.  When it reaches the left-most or right-most positions, the data begins to scroll with each item going up/down by migrating to the column immediate over from it.

I do not have a screenshot, but I will be implementing this feature in the GridX class in Visual FreePro.  So, you will be able to see it in use again in several months. :-)

In all the code I write I try to be as far backward compatible as possible.  There are users out there with VFP3 still today.  I do not want to force them to upgrade to some later version for some great expense when I can write code that allows their prior / existing investment to do the work.

That code I wrote for GridX was in VFP6, but would also work in VFP3 or VFP5.

To me, offering this full backward support is of tremendous value, which is my VFrP will support text-based DOS-like support for old code written for FoxBASE+ for DOS, FoxPro for DOS, and then limited GUI support for FoxPro for Windows, etc.

People should not be forced to pay out more money to have more features, especially when in items such as software, the advancement of features are created one time and can be replicated to everybody on the planet for essentially free.  No new hardware would be required unless the capabilities of the newer technologies force it.  But if one of your considerations is to maintain full backward compatibility, you will go as far as you can in that software for that design, and then branch off for a new product for the newer technologies.

As for technologies existing in 2010 and later ... there are almost no limits any longer.  A person can obtain a six+ CPU core machine with 16GB of memory for what a single-core 500MHz machine cost a decade ago.  And it will only get cheaper over time.

Cesar VfpImaging

unread,
Aug 25, 2012, 8:51:32 PM8/25/12
to publice...@googlegroups.com
Victor,

For this specific case, for drawing signatures, I'd never use the ImageCanvas, because it is really slower than drawing directly on the screen, believe me !
The first version used it, but the the performance was lousy, very slow and bad response to the mouse commands, so I decided to try to work directly on the screen.

Originally, the GdiPlusX team had the intention of creating a new ImageCanvas option, something like what you saw in VFPPaint, having the canvas as an independent form, having its own handle, allowing more options to draw, and specially, better performance. But at the end, the project became very big, and this was just left behind. But you have the idea in VFP Paint. So, my recommendation is to keep things as they are, or even remove the internal form, ans keep drawing in the main form.

Good luck!



--
 
 
 

Douglas Sánchez

unread,
Aug 27, 2012, 12:38:35 AM8/27/12
to publice...@googlegroups.com
Hola Cesar, saludes, una consulta ya se puede enviar sin vista previa un correo en la ultima version.
y si la ultima es la v2.99m, desde ya muchas gracias.

Douglas

2012/8/26 Cesar VfpImaging <cch...@gmail.com>
AWESOME!

Thanks for the detailed explanation!

And good luck with VFPro


--
 
 
 

--
 
 
 



--
Ing. Douglas Sánchez Guillén
      Consultor Informatico
Claro: 505 88495476

Cesar VfpImaging

unread,
Aug 27, 2012, 1:05:54 AM8/27/12
to publice...@googlegroups.com
Douglas, el asunto en discusion aca no tiene nada que ver con FOxyPreviewer, por que no cambias el Asunto?
La v2.99q trae un nuevo metodo para enviar por correo sin previsualizar, mire el ejemplo "test_simplified_configureemail2.prg"

--
 
 
 

Douglas Sánchez

unread,
Aug 28, 2012, 10:59:05 AM8/28/12
to publice...@googlegroups.com
Gracias, and I,m sorry, pero es que aproveche estabas en el foro onlien. thank yoou again...

2012/8/26 Cesar VfpImaging <cch...@gmail.com>

Mario Oviedo

unread,
Sep 11, 2012, 4:59:29 PM9/11/12
to publice...@googlegroups.com
DA ERROR ESE ENLACE

--
 
 
 

Edgardo Darío Guardini

unread,
May 13, 2015, 7:03:51 PM5/13/15
to publice...@googlegroups.com, vesp...@gmail.com
Estimado Victor, muchas gracias por el excelente ejemplo, me es de gran utilidad !!, ahora tengo un pequeño gran problema: como se puede hacer para q el control canvas sea movable con el form ? pq moves el form pero el control grafico queda anclado en la pantalla...

Saludos
Dario desde Mendoza, AR

Cesar VfpImaging

unread,
Aug 26, 2012, 6:28:03 PM8/26/12
to publice...@googlegroups.com
AWESOME!

Thanks for the detailed explanation!

And good luck with VFPro
--
 
 
 

Daniel Del Giudice

unread,
Jan 30, 2017, 7:15:08 PM1/30/17
to Comunidad de Visual Foxpro en Español
Amigos,

alguno implementó este tema de digitalizar la firma desde una aplicación Fox? Qué tableta usaron? Cómo fue la integración entre aplicación y tableta?

Yo estoy por meterme en este tema y veo que hay tabletas muy económicas y otras bastante caras, con un rango de precios entre 30 y 450 dólares. La tableta Topaz es una de las caras pero la que garantiza la implementación ya que en el sitio tiene ejemplos de fox con un ocx que proveen ellos. Luego hay otras como las Genius o las Huion con precios muy buenos pero no sé si se las podrá integrar con la aplicación. Espero sus comentarios.

Desde ya muchas gracias!

Daniel Del Giudice
Argentina

Giancarlo Pasini

unread,
Mar 9, 2017, 3:13:48 AM3/9/17
to Comunidad de Visual Foxpro en Español
Good morning,

It would need a very big favor: if I put the class into my form works but stopping me all the controls of my form and I can not get out ... if I do not put the property AlwaysOnTop = .T. I do not see the image, but the work of amia form controls.

you can aiutrmi

Thank you
Giancarlo

OSCAR HENAO

unread,
Sep 10, 2018, 8:43:53 PM9/10/18
to Comunidad de Visual Foxpro en Español
Hola Victor, que buen aporte, estoy necesitando implementar la captura de la firma para un cliente asì como en la ese form de la imagen. Nunca he utilizado clases no se mucho del tema. Solo necesito una versión así ligera donde esté el espacio para firmar con dos botones de guardar y borrar. Tu me podrías ayudar con esto? Saludos...  
Reply all
Reply to author
Forward
0 new messages