Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Master the Pen Using Ink Controls in Your Tablet Applications : Page 3

Although you can treat Microsoft's new Tablet PC Ink Data like image data, the Ink controls and objects provide a much wider variety of options for incorporating pen input into your applications. Learn how to persist ink in many formats, depending on your needs.

Saving Ink to Files
Example 1: Creating a Stream Object

The btnSaveFile_Click method displays a Save As dialog box. Initially the code creates a Stream object and opens a file with it. The code passes the Stream object by reference (byRef) to the save subroutine that corresponds to the user's choice

Private Sub btnSaveFile_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btnSaveFile.Click 'This handler lets users specify a filename, ' location, and type of format to save as. 'Create a stream which will be used to save ' data to the output file Dim myStream As Stream 'Create the SaveFileDialog, and present to the user Dim mySaveDialog As SaveFileDialog = New _ SaveFileDialog() 'Set the filter to suggest our recommended extensions mySaveDialog.Filter = "Ink Serialized Format " & + "files (*.isf)|*.isf|XML files (*.xml)|*.xml|" & _ "HTML files (*.htm)|*.htm" 'If the dialog exits and the user didn't choose Cancel If mySaveDialog.ShowDialog = DialogResult.OK Then '(the try...catch section in this function ' handles the errors for the helper methods ' called.) Try 'Attempt to Open the file with read/write 'permission myStream = mySaveDialog.OpenFile() If Not myStream Is Nothing Then 'Change the filename to Lower Case Dim filename As String = _ mySaveDialog.FileName.ToLower() ' Get a version of the filename ' without an extension ' This will be used to save associated ' Ink Data Dim extensionlessFilename As String = _ Path.GetFileNameWithoutExtension(filename) 'Get the extension of the file Dim extension As String = _ Path.GetExtension(filename) ' Use the extension to determine what form ' to save the data in Select Case extension Case ".xml" SaveXML(myStream) Case ".htm", ".html" ' The two HTML cases require a ' filename for saving associated images SaveHTML(myStream, _ extensionlessFilename) Case Else ' If unfamiliar with the extension, use ' ISF, the most "native format" SaveISF(myStream) End Select Else ' Throw an exception if a null pointer is ' returned for the stream Throw New IOException() End If Catch excpt As IOException MessageBox.Show("File error") Finally ' Close the stream in the finally clause so it ' is always reached, regardless of whether an ' exception occurs. SaveXML, SaveHTML, and ' SaveISF can throw, so this precaution is ' necessary. If Not myStream Is Nothing Then myStream.Close() End If End Try End If 'End if user chose OK from dialog End Sub

Example 2: Saving to an ISF File

The SaveISF() method serializes the ink to ISF format and writes the result to the file using the InkCollector.Save() method, specifying ISF as the PersistenceFormat.

Sub SaveISF(ByRef s As Stream) ' This function saves the form in ISF format. Dim isf As Byte() ' Perform the serialization isf = myInkCollector.Ink.Save _ (PersistenceFormat.InkSerializedFormat) ' Write the ISF to the stream s.Write(isf, 0, isf.Length) End Sub

Example 3: Saving to an XML File

Figure 3: The application saves collected text data as XML along with the applicant's signature persisted in fortified .GIF format.
The SaveXML() method uses an XmlTextWriter object to create and write to an XML document. Calling the Ink object's Save() method with the PersistenceFormat.Base64InkSerializedFormat enumeration value as a parameter converts the ink to a Base64 encoded ISF byte array. Finally, the code converts that byte array to a string and writes it to the XML file. You could also write any ancillary text data from the form to the XML file if you wished. For example, the application you were contracted to write for "Bob's Mighty Mega Loans" accepts the entry of the applicant's name, address, income and social security number. When users have reviewed their application, they sign on the dotted line (on the ink control), and click the submit button (see Figure 3). The text data, along with the client's signature, is written to XML.

Sub SaveXML(ByRef s As Stream) ' This function saves the form in XML format. ' It uses the base64 encoded version of the ink, ' which is most suitable for use XML. ' This object will encode our byte data to ' a UTF8 string Dim utf8 As UTF8Encoding = New UTF8Encoding() Dim base64ISF_bytes As Byte() Dim base64ISF_string As String ' Create a new XmlTextWriter. Dim myXWriter As XmlTextWriter = _ New XmlTextWriter(s, System.Text.Encoding.UTF8) ' Write the beginning of the document including ' the document declaration. myXWriter.WriteStartDocument() ' Write the beginning of the "data" element. ' This is the opening tag to our data myXWriter.WriteStartElement("SerializationSampleData") ' Get the base64 encoded ISF base64ISF_bytes = myInkCollector.Ink.Save _ (PersistenceFormat.Base64InkSerializedFormat) ' Convert it to a String base64ISF_string = utf8.GetString(base64ISF_bytes) ' Write the ISF containing node to the XML myXWriter.WriteElementString("Ink", base64ISF_string) 'End the "data" element. myXWriter.WriteEndElement() 'End the document myXWriter.WriteEndDocument() 'Close the xml document. myXWriter.Close() End Sub

Example 4: Saving to an HTML File

The SaveHTML() method uses the bounding box of the Strokes collection to test for the presence of ink data. If any ink exists, the method calls Ink.Save() with the PersistenceFormat.Gif enumeration value to convert it to the fortified GIF format.

fortifiedGif = myInkCollector.Ink.Save(PersistenceFormat.Gif)

The code writes the GIF produced to a file using the GIF extension. To an application that is not ink-enabled, there is no difference between a fortified GIF and a normal GIF. An IMG tag in HTML must reference the fortified GIF. The HTML generated by the .SAVE method is in Office Clipboard format (CF_HTML), making the HTML available and visible to other applications even if they are not ink-enabled. Ink-enabled applications can evaluate the HTML and determine if the .GIF is fortified.

The following examples refer to a fortified GIF by using HTML tags:

<img href="MyInk.gif" />


<IMG src='test4_files\\myInk.gif'/IMG> Sub SaveHTML(ByRef s As Stream, ByVal nameBase As String) ' This function saves the form in HTML format. ' It also creates an ink fortified GIF which is ' referenced by the HTML. ' It is not possible to save an empty .gif, so ' ensure that the ink ' has a bounding box (i.e. the ink is not empty). ' Use bounding box for this check instead of ' checking if the stroke count is zero, since the ' ink could still be empty if the strokes ' don't contain any points. If (myInkCollector.Ink.Strokes.GetBoundingBox() _ .IsEmpty) Then MessageBox.Show("Unable to save empty ink in " & _ "HTML persistence format.") Else Dim gifFile As FileStream Dim fortifiedGif As Byte() Dim html As String Dim htmlBytes As Byte() ' This object will encode our byte data to a ' UTF8 string Dim utf8 As UTF8Encoding = New UTF8Encoding() ' Create a directory to store the ' fortified GIF which also contains ISF ' and open the file for writing Directory.CreateDirectory(nameBase + "_files") gifFile = File.OpenWrite(nameBase + _ "_files\\myInk.gif") ' Generate the fortified GIF representation ' of the ink fortifiedGif = myInkCollector.Ink.Save _ (PersistenceFormat.Gif) ' Write and close the gif file gifFile.Write(fortifiedGif, 0, fortifiedGif.Length) gifFile.Close() ' Create the HTML output ' Note that the names are stored in HTML ' tags, rather than custom properties, so that ' these properties can be easily retrieved from ' the HTML. html = _ "<HTML><HEAD></HEAD><BODY>" & _ "<P>Ink Save Test: " & nameBase & "</P>" & _ "<P><IMG src='" & _ nameBase + "_files\\myInk.gif" & _ "'/IMG></P>" & _ "</BODY></HTML>" ' Convert the HTML to a byte array for ' writing to the stream htmlBytes = utf8.GetBytes(html) ' Write the HTML to the stream s.Write(htmlBytes, 0, htmlBytes.Length) End If End Sub

Example 5: Saving to a SQL Server Database.

The btnSaveDB_Click() method also creates a Stream object; however, instead of a FileStream Object, the code uses a MemoryStream object. The SQL Server Image datatype is a binary datatype and is perfect for holding ink data. You have to convert the ink to an array of bytes using the InkCollector.Ink.Save() method. The following example uses the exiting "Picture" table in the northwinds sample database.

Private Sub btnSaveDB_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btnSaveDB.Click ' The SQL Server Image datatype is a binary datatype. ' To save it to the database we must convert the ink ' to an array of bytes. We will use ' MemoryStream with the inkCollector.Ink.Save method. Dim Filename As String Dim isf As Byte() If inkEdFileName.Text.Length = 0 Then MessageBox.Show("You must enter a file name.", _ "Missing File Name", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Else ' Perform the serialization isf = myInkCollector.Ink.Save _ (PersistenceFormat.InkSerializedFormat) 'append the .ink extension to denote .INK data inkEdFileName.Text = _ Trim(inkEdFileName.Text) & ".ink" Filename = inkEdFileName.Text Dim isConnecting As Boolean = True While isConnecting Try Dim northwindConnection As _ New SqlConnection(connectionString) Dim strSQL As String = _ "INSERT INTO Picture (Filename, Picture)" & _ "VALUES (@Filename, @Picture)" myCmd = New SqlCommand(strSQL, _ northwindConnection) With myCmd ' Add parameters required by SQL ' statement. 'PictureID is an ' identity field so only pass values for 'the two remaining fields. .Parameters.Add(New SqlParameter _ ("@Filename", _ SqlDbType.NVarChar, 50)).Value _ = Filename .Parameters.Add(New SqlParameter_ ("@Picture", SqlDbType.Image)).Value _ = isf End With ' Open the connection, execute the command, 'and close the connection. northwindConnection.Open() myCmd.ExecuteNonQuery() northwindConnection.Close() ' Data has been successfully submitted, 'so break out of the loop isConnecting = False MessageBox.Show(Filename & _ " saved to the " & _ "database.", _ "Ink Save Status", MessageBoxButtons.OK, _ MessageBoxIcon.Information) Catch sqlExc As SqlException MessageBox.Show(sqlExc.ToString, _ "SQL Exception Error!", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit While Catch exc As Exception ' Unable to connect to SQL Server MessageBox.Show("Error connecting " & _ "to Database.", _ "Connection Failed!", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) End Try End While End If End Sub

Now that you know how to save ink in the various file formats, the next step is learning how to retrieve it.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date