Signatures

Randal
Posts: 250
Joined: Mon Oct 24, 2005 8:04 pm

Signatures

Post by Randal »

All,

Has anyone been able to capture a signature and save it as a graphic image?

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

Post by Antonio Linares »

Randal,

Class TWindow already provides a METHOD SaveToBmp( cBmpFile ) to save any window, dialog or control image as a BMP file.

All is needed is a sample that uses bLClicked, bMMoved and bLButtonUp DATAs to SetPixel( oWnd:hDC, nRow, nCol, nRGB( 255, 255, 255 ) ) and paint the pixels signature as pressed and later on save it to disk.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Bill Simmeth
Posts: 42
Joined: Wed Oct 26, 2005 1:20 pm
Location: Marshall, Virginia, USA
Contact:

Post by Bill Simmeth »

I've had better luck using the LineTo function. Using SetPixel made the signature look very "dotted". Something like this sample works very nicely...

Code: Select all

#include "FWCE.ch"
#include "DLL.ch"

function Main()
local oWnd, oSay,  nHdc

   PUBLIC nOldX := -1, nOldY := -1

   DEFINE WINDOW oWnd TITLE "Draw"

   @ 5,5 SAY oSay   PROMPT "?" COLOR "N+/W*" PIXEL SIZE 60,15
   @30,5 BUTTON "Clear" SIZE 50,20 PIXEL ACTION oWnd:refresh(.t.)

   nHdc := GetDC(oWnd:hWnd)

   oWnd:bLButtonUp := { |x,y,z| oSay:setText( "Up" ), DoDraw( nHdc, y, x ), nOldX := -1, nOldY := -1 }
   oWnd:bMMoved    := { |x,y,z| DoDraw( nHdc, y, x ) }

   oWnd:activate( {|x,y,z| oSay:setText( "Down" ), DoDraw( nHdc, y, x ) } )

return nil

Function DoDraw( hDc, x, y )

   If nOldX == -1 .And. nOldY == -1
      nOldX := x
      nOldY := y
      MoveToEx( hDc, x, y )
   Else
      LineTo( hDc,x,y )
   EndIf

RETURN Nil

DLL FUNCTION MoveToEx( nHdc AS HDC, nX AS _INT, nY AS _INT, NULL AS _INT ) AS BOOL PASCAL LIB "coredll.dll"
Merry Christmas y'all!
Bill Simmeth
Merchant Software Corp
Marshall, Virginia USA
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Bill,

Excellent! It works very nicely! :-)

We are going to include it in the FWPPC samples if you don't mind it, thanks!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Richard Chidiak
Posts: 946
Joined: Thu Oct 06, 2005 7:05 pm
Location: France
Contact:

Post by Richard Chidiak »

Antonio Linares wrote:Bill,

Excellent! It works very nicely! :-)

We are going to include it in the FWPPC samples if you don't mind it, thanks!
Antonio

Indeed it is excellent.

How would you save only the signature to bmp without the clear button and ?
Ownd:savetobmp() will save the entire window

Richard
http://www.cbati.com

Uestudio
Fwh 13.05 Harbour 3.2 MSVC 2013
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Richard,

We propose some modifications for the sample:

* To remove the pushbutton and the "?"
* To use a pulldown menu for Save and Cancel, this way the entire window client surface may be saved to a file.
* hDC needs to be released or it will consume GDI resources.
* Class TWindow Method SaveToBmp() may need a parameter to specify just the client area, without the caption and the menu.
regards, saludos

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

Post by Antonio Linares »

This sample is based on Bill's one. Its working fine though we have not been able to remove the pulldown menu yet:

Code: Select all

#include "FWCE.ch"

static oWnd

function Main()

   local hDC, lPaint := .f.

   DEFINE WINDOW oWnd TITLE "Please sign" ;
      MENU BuildMenu()

   hDC = oWnd:GetDC()

   oWnd:bLButtonUp = { | nRow, nCol | LineTo( hDC, nCol, nRow ), lPaint := .f. }
   oWnd:bMMoved    = { | nRow, nCol | If( lPaint, LineTo( hDC, nCol, nRow ),) }

   ACTIVATE WINDOW oWnd ;
      ON CLICK ( lPaint := .t., MoveTo( hDC, nCol, nRow ) ) ;
      VALID ( oWnd:ReleaseDC(), .t. )
      
return nil

function BuildMenu()

   local oMenu
   
   DEFINE MENU oMenu RESOURCE 102 ;
      BITMAPS 10 ; // bitmap resources ID
      IMAGES 2     // number of images in the bitmap
   
   REDEFINE MENUITEM ID 110 OF oMenu ;
      ACTION ( oWnd:SaveToBmp( CurDir() + "\sign.bmp" ), oWnd:End() )

   REDEFINE MENUITEM ID 120 OF oMenu ACTION oWnd:End()

return oMenu
It uses this RC:

Code: Select all

#ifdef _CE
   #include "c:\vce\include\arm\windows.h"
   #include "c:\vce\include\arm\commctrl.h"
#endif

#define I_IMAGENONE		(-2)
#define IDS_HELP      104

#ifdef _CE
102 RCDATA
BEGIN
   102, 3,
   0, 110, TBSTATE_ENABLED, TBSTYLE_BUTTON, 201, 0, 0,  
   0, 105, TBSTATE_ENABLED, TBSTYLE_SEP, -1, 0, 0,
   1, 120, TBSTATE_ENABLED, TBSTYLE_BUTTON, 202, 0, 0  
END
#endif

STRINGTABLE DISCARDABLE 
BEGIN
   201 "Save"
   202 "Cancel"
END

102 MENU DISCARDABLE 
BEGIN
    MENUITEM "", 110
    MENUITEM "", 120
END

10 BITMAP "../bitmaps/pocket/okcancel.bmp"
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Richard Chidiak
Posts: 946
Joined: Thu Oct 06, 2005 7:05 pm
Location: France
Contact:

Post by Richard Chidiak »

Antonio

I did other tests based on Bill's sample and was thinking of buttons instead of menus. The problem is to be able to hide the buttons when saving the image. I am not yet there.

Here is my sample.

#include "C:\FWPPC\INCLUDE\FWCE.ch"
#include "C:\FWPPC\INCLUDE\DLL.ch"

function Main()
local oWnd, oSay, nHdc

PUBLIC nOldX := -1, nOldY := -1

HIDEKEYBOARD()

DEFINE WINDOW oWnd TITLE "Draw"

@ 5,5 SAY oSay PROMPT " " COLOR "N+/W*" PIXEL SIZE 15,15
@ 5,30 BUTTON obtn1 prompt "Clear" SIZE 50,20 PIXEL ACTION oWnd:refresh(.t.)
@ 5,100 BUTTON obtn2 prompt "Save" SIZE 80,20 PIXEL ACTION (OBTN1:HIDE(),OBTN2:HIDE(),OWND:SAVETOBMP(CurDir() + "\TESTppc.BMP"))

nHdc := GetDC(oWnd:hWnd)

oWnd:bLButtonUp := { |x,y,z| oSay:setText( " " ), DoDraw( nHdc, y, x ), nOldX := -1, nOldY := -1 }
oWnd:bMMoved := { |x,y,z| DoDraw( nHdc, y, x ) }

oWnd:activate( {|x,y,z| oSay:setText( " " ), DoDraw( nHdc, y, x ) } )
SHOWKEYBOARD()

return nil

Function DoDraw( hDc, x, y )

If nOldX == -1 .And. nOldY == -1
nOldX := x
nOldY := y
MoveToEx( hDc, x, y )
Else
LineTo( hDc,x,y )
EndIf

RETURN Nil

DLL FUNCTION MoveToEx( nHdc AS HDC, nX AS _INT, nY AS _INT, NULL AS _INT ) AS BOOL PASCAL LIB "coredll.dll"
http://www.cbati.com

Uestudio
Fwh 13.05 Harbour 3.2 MSVC 2013
User avatar
Maurizio
Posts: 705
Joined: Mon Oct 10, 2005 1:29 pm
Contact:

Post by Maurizio »

I use this for sending messages from the Pocket PC to the kitchen.

I save the position in an array , after I save the array in a file and I send
the file to the PC server where I then transform the file in an array and I print the message .

Code: Select all


#include "FWCE.ch"
static oWnd, lDown, hDC ,cFile,nOldRow,nOldCol
Static aDati := {}
//====================================================================================
Function Main()
lDown := .F.
nOldRow := 0
nOldCol := 0

DEFINE WINDOW oWnd TITLE "Signature"

 oWnd:bLClicked   := { || lDown := .T. }
 oWnd:bLButtonUp  := { || lDown := .F. ,nOldRow := 0 , nOldCOl := 0 }
 oWnd:bMMoved     := { |nRow, nCol, nKeyFlags| Draw(nCol,nRow)}

 hDC := oWnd:GetDC()

 @ 1, 1 BUTTON oBtn1 PROMPT "Refresh" ;
      ACTION (oWnd:Refresh(),aDAti := {}) SIZE 80, 20

 @ 3, 1 BUTTON oBtn1 PROMPT "S a v e" ;
      ACTION Save() SIZE 80, 20

ACTIVATE WINDOW oWnd

return 0
//====================================================================================
STATIC FUNCTION Draw(nRow,nCol)
IF lDown
   * SetPixel(hDC, nRow, nCol, RGB(0,0,0) )
	IF nOldRow > 0
		DrawLine(nRow,nCol)
      aadd(aDAti,{nRow,nCol})
	ELSE
		// We will need to know when a line starts and finishes
      aadd(aDAti,{nRow+1000,nCol+1000})
	ENDIF
   nOldRow := nRow
   nOldCol := nCol
ENDIF

RETURN NIL
//=================================================
Static  Procedure DrawLine( nRow,nCol	 )
   LOCAL n, hPen, hOldPen
   oWnd:GetDc()
   hPen := CreatePen( 0, 1, RGB(0,0,0)  )
   hOldPen := SelectObject( oWnd:hDc, hPen )

   MoveTo( oWnd:hDC,nOldRow,nOldCol )
   LineTo( oWnd:hDC, nRow, nCol )

   SelectObject( oWnd:hDc, hOldPen )
   DeleteObject( hPen )
   oWnd:ReleaseDc()
   RETURN
//=================================================
Function Save()
	Local nX := 0
	Local cTxt := aSave(aDAti)
	MemoWrit(  CurDir() + "\Prova.txt", cTxt )
RETURN NIL

//-------------------------------------------------------------------------------------------
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
#include "item.api"

HB_FUNC( SETPIXEL )
{
   hb_retnl( SetPixel( ( HDC ) hb_parnl( 1 ), hb_parni( 2 ), hb_parni( 3 ), hb_parnl( 4 ) ) );
}
#pragma ENDDUMP



function ASave( aArray )

   local n, cType, uData
   local cInfo := ""

   for n = 1 to Len( aArray )
      cType = ValType( aArray[ n ] )
      do case
         case cType == "A"
              cInfo += ASave( aArray[ n ] )

         case cType == "O"
              cInfo += aArray[ n ]:Save()

         otherwise
              cInfo += ( cType + I2Bin( Len( uData := cValToChar( aArray[ n ] ) ) ) + ;
                         uData )
      endcase
   next

return "A" + I2Bin( 2 + Len( cInfo ) ) + I2Bin( Len( aArray ) ) + cInfo

//----------------------------------------------------------------------------//
















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

Post by Antonio Linares »

Maurizio,

Yes, thats a very good idea too, to save the signature as an array of points (nCol, nRow) like a vectorial draw.
regards, saludos

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

Post by Antonio Linares »

Richard,

The buttons should dissapear, don't they ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Richard Chidiak
Posts: 946
Joined: Thu Oct 06, 2005 7:05 pm
Location: France
Contact:

Post by Richard Chidiak »

They are supposed to but they don't. This is the poblem.
http://www.cbati.com

Uestudio
Fwh 13.05 Harbour 3.2 MSVC 2013
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Richard,

Yes, the same happened with the pulldown menu. I guess it is caused as there is an existing hDC in use.

Maybe you may try to call oWnd:ReleaseDC() before hidding the buttons.

If you use Bill's code, then call ReleaseDC( oWnd:hWnd, oWnd:hDC )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Richard Chidiak
Posts: 946
Joined: Thu Oct 06, 2005 7:05 pm
Location: France
Contact:

Post by Richard Chidiak »

Antonio

No change, same result. We need to update the window before saving it

I keep searching
http://www.cbati.com

Uestudio
Fwh 13.05 Harbour 3.2 MSVC 2013
Bill Simmeth
Posts: 42
Joined: Wed Oct 26, 2005 1:20 pm
Location: Marshall, Virginia, USA
Contact:

Post by Bill Simmeth »

This sample uses a SAY object to collect the signature and its DC is saved to the bitmap file. It works nicely...

Code: Select all

#include "FWCE.ch"
#include "DLL.ch"

function Main()
local oMain, oSig, nHdc
local cDir := CurDir()

   PUBLIC nOldX := -1, nOldY := -1

   DEFINE WINDOW oMain TITLE "Draw"

   @60,5 SAY oSig PROMPT "" SIZE 230,150 PIXEL BORDER

   @25, 5 BUTTON "Clear" SIZE 50,20 PIXEL ACTION oSig:refresh(.t.)
   @25,60 BUTTON "Save"  SIZE 50,20 PIXEL ACTION ( oSig:saveToBmp( cDir + "\MySig.BMP" ), oSig:refresh(.t.) )

   nHdc := GetDC( oSig:hWnd )

   oSig:bLButtonUp := { |x,y,z| DoDraw( nHdc, y+1, x+1 ), nOldX := -1, nOldY := -1 }
   oSig:bMMoved    := { |x,y,z| DoDraw( nHdc, y, x ) }
   oSig:bLClicked  := { |x,y,z| DoDraw( nHdc, y, x ) }

   ACTIVATE WINDOW oMain

return nil

Function DoDraw( hDc, x, y )

   If nOldX == -1 .And. nOldY == -1
      nOldX := x
      nOldY := y
      MoveToEx( hDc, x, y )
   Else
      LineTo( hDc,x,y )
   EndIf

RETURN Nil

DLL FUNCTION MoveToEx( hWnd AS HDC, nX AS _INT, nY AS _INT, NULL AS _INT ) AS BOOL PASCAL LIB "coredll.dll"
Merry Christmas!!
Bill Simmeth
Merchant Software Corp
Marshall, Virginia USA
Post Reply