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