Over the past few years we have developed Windows Mobile applications that require a a signature to be recorded; either for a collection, a delivery or to indicate a customer is satisfied with a job.

There are several examples on how to do this in C# or Visual Basic but we’ve never been happy with the form of the data that gets sent back to the server. One of my colleagues had a requirement for a windows mobile application that recorded a signature and the signature was then viewable in a Silverlight application; this is how we did it.

This first post is only about the signature capture and the methods to convert a signature into a simple ascii string ready to be sent via a HTTP Post.

sign here

First we start by creating a new project and adding a picturebox to the main form.  The “please sign here” image is then inserted into the picturebox as the default image.

To allow drawing on the picturebox (so we can make a signature) we only need to trap three events: MouseDown, MouseMove and MouseUp.

If we look at the following code:

Public Class Form1
    Dim lastx As Int16
    Dim lasty As Int16
    Dim bit As Bitmap
    Dim mdown As Boolean

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    bit = PictureBox1.Image

End Sub

Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown 
    mdown = True ‘ global boolean
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    Dim g As Graphics = Graphics.FromImage(bit)
    Dim myPen As Pen = New Pen(Color.Black, 2)

    If mdown Then
        g.DrawLine(myPen, lastx, lasty, e.X, e.Y) 
        PictureBox1.Image = bit ‘ bit is the bitmap of the picturebox defined as a global
        lastx = e.X
        lasty = e.Y

    End If
End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    mdown = False ‘ global boolean
   

End Sub

End Class

If you take this code and paste it into your project you’ll find you can now draw in the picturebox.

We now need to add the code to allow the signature to be sent via HTTP to a server.

We do this by capturing the “Drawline” coordinates and converting these into a HEX string.

First add two global strings to your project:

Public DrawLines As String = “”
Public CurrentLine As String = “”

Then amend your MouseDown, MouseUp and MouseMove routines to be:

Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    lastx = e.X
    lasty = e.Y
    CurrentLine = Hexit(e.X) & Hexit(e.Y)
    mdown = True
End Sub

We record the mousedown xy coordinates and we also assign these values to the string CurrentLine, in Hex. Each Hex number is two characters long.

Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    Dim g As Graphics = Graphics.FromImage(bit)
    Dim myPen As Pen = New Pen(Color.Black, 2)

    If mdown Then
        g.DrawLine(myPen, lastx, lasty, e.X, e.Y)

        CurrentLine = CurrentLine & Hexit(e.X) & Hexit(e.Y)
        PictureBox1.Image = bit
        lastx = e.X
        lasty = e.Y

    End If
End Sub

For each MouseMove we add the new xy coordinates to the CurrentLine in Hex.

sig

Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    mdown = False
    If CurrentLine.Length > 4 Then
        If DrawLines = “” Then
            DrawLines = CurrentLine
        Else
            DrawLines = DrawLines & “,” & CurrentLine
        End If
    End If

End Sub

When we finish the line we are drawing we append the CurrentLine to DrawLines and separate each line with commas so we end up with a CSV line.

And add the following simple HEX conversion function to your project:

Private Function Hexit(ByVal v As Integer) As String
    Hexit = Hex(v)
    If Hexit.Length = 1 Then Hexit = “0” & Hexit
End Function

Add a textbox to your Form and make it multiline and add vertical scrollbars. And a single MenuItem:

Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
    TextBox1.Text = DrawLines
End Sub

That’s all it takes to capture a signature and convert it to an ascii string that is easy to understand, easy to transmit and is reasonably efficient in space. Oh and it runs fast too.