// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: PaperForm.cs // PaperForm Ink Controls Sample Application // // This sample program demonstrates how the InkPicture control // can be used in conjunction with a DataSet to allow the user // to fill in a scanned form. The DataSet contains a reference // to the form image and the location of each element in the form. // The InkPicture control uses this information to display the // form and calculate recognition results for each form element. // // The features used are: InkPicture used in conjunction with // a DataSet to allow the user to write over a scanned form. // //-------------------------------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; using System.Data; using System.IO; using System.Text; // The Ink namespace, which contains the Tablet PC Platform API using Microsoft.Ink; namespace PaperForm { /// /// The PaperForm Sample Application form class /// public class PaperForm : System.Windows.Forms.Form { // DataSet containing the form's data private DataSet formData = null; // Declare the InkPicture control, which contains the scanned image private InkPicture inkPicture1 = null; // The name of the xml file containing the form data private String formDataFile = "formdata.xml"; #region Standard Template Code private System.Windows.Forms.MenuItem menuItem4; private System.Windows.Forms.MainMenu mainMenu; private System.Windows.Forms.MenuItem miInk; private System.Windows.Forms.MenuItem miRecognize; private System.Windows.Forms.MenuItem miClear; private System.Windows.Forms.MenuItem miExit; private System.Windows.Forms.MenuItem miMode; private System.Windows.Forms.MenuItem miPen; private System.Windows.Forms.MenuItem miEdit; private System.Windows.Forms.MenuItem miEraser; private System.ComponentModel.Container components = null; #endregion public PaperForm() { #region Standard Template Code // // Required for Windows Form Designer support // InitializeComponent(); #endregion } #region Standard Template Code /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.inkPicture1 = new Microsoft.Ink.InkPicture(); this.mainMenu = new System.Windows.Forms.MainMenu(); this.miInk = new System.Windows.Forms.MenuItem(); this.miRecognize = new System.Windows.Forms.MenuItem(); this.miClear = new System.Windows.Forms.MenuItem(); this.menuItem4 = new System.Windows.Forms.MenuItem(); this.miExit = new System.Windows.Forms.MenuItem(); this.miMode = new System.Windows.Forms.MenuItem(); this.miPen = new System.Windows.Forms.MenuItem(); this.miEdit = new System.Windows.Forms.MenuItem(); this.miEraser = new System.Windows.Forms.MenuItem(); this.SuspendLayout(); // // inkPicture1 // this.inkPicture1.Cursor = System.Windows.Forms.Cursors.Default; this.inkPicture1.InkEnabled = false; this.inkPicture1.MarginX = -1; this.inkPicture1.MarginY = -1; this.inkPicture1.Name = "inkPicture1"; this.inkPicture1.Size = new System.Drawing.Size(717, 975); this.inkPicture1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.inkPicture1.TabIndex = 4; this.inkPicture1.TabStop = false; // // mainMenu // this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miInk, this.miMode}); // // miInk // this.miInk.Index = 0; this.miInk.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miRecognize, this.miClear, this.menuItem4, this.miExit}); this.miInk.Text = "&Ink"; // // miRecognize // this.miRecognize.Index = 0; this.miRecognize.Text = "&Recognize"; this.miRecognize.Click += new System.EventHandler(this.miRecognize_Click); // // miClear // this.miClear.Index = 1; this.miClear.Text = "&Clear"; this.miClear.Click += new System.EventHandler(this.miClear_Click); // // menuItem4 // this.menuItem4.Index = 2; this.menuItem4.Text = "-"; // // miExit // this.miExit.Index = 3; this.miExit.Text = "&Exit"; this.miExit.Click += new System.EventHandler(this.miExit_Click); // // miMode // this.miMode.Index = 1; this.miMode.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.miPen, this.miEdit, this.miEraser}); this.miMode.Text = "&Mode"; // // miPen // this.miPen.Checked = true; this.miPen.Index = 0; this.miPen.RadioCheck = true; this.miPen.Text = "&Pen"; this.miPen.Click += new System.EventHandler(this.miPen_Click); // // miEdit // this.miEdit.Index = 1; this.miEdit.RadioCheck = true; this.miEdit.Text = "&Edit"; this.miEdit.Click += new System.EventHandler(this.miEdit_Click); // // miEraser // this.miEraser.Index = 2; this.miEraser.RadioCheck = true; this.miEraser.Text = "E&raser"; this.miEraser.Click += new System.EventHandler(this.miEraser_Click); // // PaperForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.AutoScroll = true; this.ClientSize = new System.Drawing.Size(719, 817); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.inkPicture1}); this.DockPadding.All = 2; this.Menu = this.mainMenu; this.Name = "PaperForm"; this.Text = "Scanned Paper Form Demo"; this.Load += new System.EventHandler(this.PaperForm_Load); this.ResumeLayout(false); } #endregion #region Standard Template Code /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new PaperForm()); } #endregion /// /// Event Handler from PaperForm->Load Event /// /// The control that raised the event. /// The event arguments. private void PaperForm_Load(object sender, System.EventArgs e) { String applicationPath = Path.GetDirectoryName(Application.ExecutablePath)+"\\"; // Initialize the form's dataset try { // read the form's data from the given xml file formData = new DataSet("FormData"); formData.ReadXml(applicationPath+formDataFile); // The overlay control's background image is referenced in the xml dataset inkPicture1.BackgroundImage = System.Drawing.Image.FromFile(applicationPath+ (string) formData.Tables["FormData"].Rows[0]["Image"]); } catch(FileNotFoundException error) { // If the xml or the scanned form image file are not available, // display an error and exit MessageBox.Show("A required data file was not found. Please verify "+ "that the file exists in the same directory as PaperForm.exe "+ "and try again." + Environment.NewLine + Environment.NewLine + error.ToString(), "PaperForm", MessageBoxButtons.OK); Application.Exit(); } // Enable ink collection for the ink picture control inkPicture1.InkEnabled = true; } /// /// Event Handler from Clear Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miClear_Click(object sender, System.EventArgs e) { // Delete the ink strokes and redraw inkPicture1.Ink.DeleteStrokes(inkPicture1.Ink.Strokes); inkPicture1.Invalidate(); } /// /// Event Handler from Recognize Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miRecognize_Click(object sender, System.EventArgs e) { // Get the handwriting recognition results Recognize(); } /// /// Event Handler from Exit Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miExit_Click(object sender, System.EventArgs e) { inkPicture1.Enabled = false; Application.Exit(); } /// /// Event Handler from Pen Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miPen_Click(object sender, System.EventArgs e) { UpdateEditMode(InkOverlayEditingMode.Ink); } /// /// Event Handler from Edit Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miEdit_Click(object sender, System.EventArgs e) { UpdateEditMode(InkOverlayEditingMode.Select); } /// /// Event Handler from Eraser Menu Item Click Event /// /// The control that raised the event. /// The event arguments. private void miEraser_Click(object sender, System.EventArgs e) { UpdateEditMode(InkOverlayEditingMode.Delete); } /// /// UpdateEditMode is a helper method to switch the InkPicture's /// editing mode and update the form accordingly. /// /// The new editing mode private void UpdateEditMode(InkOverlayEditingMode mode) { if (!inkPicture1.CollectingInk) { // Ink collection must be disabled before modifying the edit mode inkPicture1.InkEnabled = false; inkPicture1.EditingMode = mode; inkPicture1.InkEnabled = true; // Update the menu UI to the new state miPen.Checked = InkOverlayEditingMode.Ink == mode; miEdit.Checked = InkOverlayEditingMode.Select == mode; miEraser.Checked = InkOverlayEditingMode.Delete == mode; } else { // If user is actively inking, we cannot switch modes. MessageBox.Show("Cannot switch the editing mode while collecting ink."); } } /// /// Iterate through each row of the form data and /// display the recognition results /// private void Recognize() { // Check to ensure that the user has at least one recognizer installed Recognizers inkRecognizers = new Recognizers(); if (0 == inkRecognizers.Count) { MessageBox.Show(this, "There are no handwriting recognizers installed. You need to have at least one in order to perform the recognition."); } else { StringBuilder buffer = new StringBuilder(); // Iterate through the rows in the "FieldInfo" table foreach(DataRow row in formData.Tables["FieldInfo"].Rows) { // get the metadata for the field // Note that the DataSet contains a row for each field // in the form. It is assumed that the rows are in the // same order as the fields in the form. The DataSet // has the following columns: // Name: the field's name // Left, Top, Right, Bottom: the coordinates of the field (in pixels) string fieldname = (string) row["Name"]; Point pt1 = new Point((int) row["Left"], (int) row["Top"]); Point pt2 = new Point((int) row["Right"], (int) row["Bottom"]); using (Graphics g = CreateGraphics()) { // Convert to ink space units inkPicture1.Renderer.PixelToInkSpace(g, ref pt1); inkPicture1.Renderer.PixelToInkSpace(g, ref pt2); } // the rectangle for the region Rectangle rc = new Rectangle(pt1.X, pt1.Y, pt2.X-pt1.X, pt2.Y-pt1.Y); // find the strokes that intersect and lie inside of the rectangle Strokes strokes = inkPicture1.Ink.HitTest(rc,70); // recognize the handwriting if (strokes.Count > 0) { buffer.Append(fieldname + " = " + strokes.ToString() + Environment.NewLine); } } // Display the results if (buffer.Length > 0) { MessageBox.Show(this, buffer.ToString()); } else { MessageBox.Show(this, "There aren't any recognition results."); } } } } }