最近的项目需要用到手写电子签名的功能,挑来挑去最后选择了蒙恬Write2Go这款手写板设备,因为手写板上面直接就有一块电子油墨显示屏,所写即所得,还可以看到写的笔迹
安装完蒙恬的驱动及自带应用程序之后,经过测试发现,其工作原理是利用了windows剪切板作为中间桥梁来交换图片数据,每次签名的时候首先需要启动蒙恬自带的一个叫做"蒙恬即写通"的程序:
毕竟手写的笔迹传到电脑上的时候走的还是手写板的电阻屏,所以笔迹效果肯定不如电子油墨屏上面显示的好看,按下设备上的发送按钮,笔迹会作为图片的形式保存到windows剪切板中,利用上一篇写到的windows剪切板内容监视方法,可以在自己的程序中调用到手写笔迹图片,具体实现起来涉及到下面几个技术点:
- 在程序中点击签名区域时调用蒙恬的"即写通"程序
- 监视windows剪切板,发现有图片数据更新到剪切板中时将其调用到自己的程序中的pictureBox控件里显示出来
- 把pictureBox控件中显示的签名笔迹image类型数据写入数据库中
- 从数据库中读取image类型数据并在winform的pictureBox控件里显示出来
Imports System.IO
Imports System.Data.SqlClient
Public Class clipboardMon
'------------------监视剪切板数据代码开始------------------
#Region " Definitions "
'Constants for API Calls...
Private Const WM_DRAWCLIPBOARD As Integer = &H308
Private Const WM_CHANGECBCHAIN As Integer = &H30D
'Handle for next clipboard viewer...
Private mNextClipBoardViewerHWnd As IntPtr
'API declarations...
Declare Auto Function SetClipboardViewer Lib "user32" (ByVal HWnd As IntPtr) As IntPtr
Declare Auto Function ChangeClipboardChain Lib "user32" (ByVal HWnd As IntPtr, ByVal HWndNext As IntPtr) As Boolean
Declare Auto Function SendMessage Lib "User32" (ByVal HWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Long
#End Region
#Region " Contructor "
Public Sub NewViewer()
'InitializeComponent()
'To register this form as a clipboard viewer...
Clipboard.Clear()
mNextClipBoardViewerHWnd = SetClipboardViewer(Me.Handle)
End Sub
#End Region
#Region " Message Process "
'Override WndProc to get messages...
Protected Overrides Sub WndProc(ByRef m As Message)
Select Case m.Msg
Case Is = WM_DRAWCLIPBOARD 'The clipboard has changed...
'##########################################################################
' Process Clipboard Here :)........................
'##########################################################################
SendMessage(mNextClipBoardViewerHWnd, m.Msg, m.WParam, m.LParam)
'显示剪贴板中的图片信息
If Clipboard.ContainsImage() = True Then
PictureBox1.Image = Clipboard.GetImage()
PictureBox1.Update()
End If
Case Is = WM_CHANGECBCHAIN 'Another clipboard viewer has removed itself...
If m.WParam = CType(mNextClipBoardViewerHWnd, IntPtr) Then
mNextClipBoardViewerHWnd = m.LParam
Else
SendMessage(mNextClipBoardViewerHWnd, m.Msg, m.WParam, m.LParam)
End If
End Select
MyBase.WndProc(m)
End Sub
#End Region
Private Sub clipboardMon_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
NewViewer()
End Sub
'------------------监视剪切板数据代码结束------------------
''' <summary>
''' 点击签字区域时自动运行蒙恬即写通程序
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click
'定位蒙恬即写通程序的位置路径
Dim writePath As String = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + "\PenPower Write2Go\Bin\PPStartupApp.exe"
Process.Start(writePath)
End Sub
''' <summary>
''' 保存当前picturebox中的图片到数据库
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim ms As New MemoryStream()
Dim bReturn() As Byte = Nothing
Me.PictureBox1.Image.Save(ms, Imaging.ImageFormat.Jpeg)
bReturn = ms.GetBuffer
ms.Close()
Using conn As New SqlConnection(My.Settings.piaojuConnectionString)
conn.Open()
Dim cmd As New SqlClient.SqlCommand()
cmd.Connection = conn
cmd.CommandText = "insert into paper_baozhangshenpidan(paperID,applySign) values('20160227',@img)"
Dim par As New SqlClient.SqlParameter("@img", SqlDbType.Image)
par.Value = bReturn
cmd.Parameters.Add(par)
Dim t As Integer = Integer.Parse(cmd.ExecuteNonQuery())
If t > 0 Then
MsgBox("Success")
Else
MsgBox("Faile")
End If
conn.Close()
End Using
End Sub
''' <summary>
''' 从数据库中读取image类型数据并显示在picturebox控件里
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim imgData(0) As Byte
Using conn As New SqlConnection(My.Settings.piaojuConnectionString)
conn.Open()
Dim cmd As New SqlCommand
cmd.Connection = conn
cmd.CommandText = "select * from paper_baozhangshenpidan where paperID='20160227'"
Dim sdr As SqlDataReader = cmd.ExecuteReader
sdr.Read()
imgData = sdr("applySign")
Dim mystream As New MemoryStream(imgData)
Dim img As Image = Image.FromStream(mystream, True)
Me.PictureBox1.Image = img
Me.PictureBox1.Refresh()
mystream.Close()
conn.Close()
End Using
End Sub
End Class
备注说明一下:
数据库中列'applySign'的数据类型为image,用来存放图片的byte数据