Export (0) Print
Expand All
Add Support for Digital Ink to Your Windows Applications
Power to the Pen: The Pen is Mightier with GDI+ and the Tablet PC Real-Time Stylus
Expand Minimize
0 out of 2 rated this helpful - Rate this topic

Adding Journal-like Functionality to Your Ink-Enabled Application

 

Bernd Helzer
Agilix Labs, Inc.

September 2004

Applies to
   Microsoft Tablet PC Platform SDK
   Microsoft Windows® XP Tablet PC Edition 2005
   Agilix InfiNotes

Summary: Adding ink-based note taking to your application creates user friendly Tablet PC applications. Now you can easily add inking experience similar to that of Windows Journal by incorporating the free Agilix InfiNotes control in your application. This article describes how you can integrate inking into your existing or new Windows Forms application.

Contents

Introduction
Building the Application
File Menu Commands
Edit Menu Commands
Paper Menu Commands
Finishing the Application
Conclusion

Introduction

Microsoft worked with Agilix to create an ink-note taking framework that you can freely integrate into your application. Agilix InfiNotes Standard Edition provides a common code base, which improves the consistency of the end-user experience across applications. It also allows you to focus on your specific business needs instead of building Windows Journal.

Those new to Tablet PC development may ask what advantages InfiNotes provides over the existing InkPicture control. The controls in InfiNotes implement many features beyond InkPicture including:

  • Undo/Redo – InfiNotes provides full undo/redo capabilities, which most people expect to find in editing controls.
  • Lasso selection – An optimized lasso selection ensures end-users experience selection as they naturally expect it.
  • Dynamic stationery – As the document grows, the underlying stationery also grows, so that the note page looks natural.
  • Pen buttons – InfiNotes controls automatically support the eraser and other buttons on your pen.
  • Background recognition –InfiNotes automatically recognizes ink as drawings and text and gives you programmatic access to the resulting converted text.
  • Clipboard formats – InfiNotes supports standard ink clipboard formats and implements drag-and-drop operations so you can drag and drop ink to other ink-enabled applications and accessories, such as Journal.
  • Toolbar – InfiNotes contains a plug-and-play toolbar with basic ink operations so end-users can easily create, edit, and format ink-notes.

If you have not already done so, download the control from www.infinotes.com. After installing the control, a new tab appears in your Visual Studio Toolbox, Agilix InfiNotes. The tab contains four controls: Doodle, Note, NoteToolBar, and NoteBox. Each control has a specific purpose:

  • Doodle – The Doodle control is a basic upgrade to the InkPicture control. The Doodle control supports inking with undo, redo, and lasso selection. The Yacht sample application—part of the supporting documentation for InfiNotes—uses this control.
  • Note – The Note control inherits from Doodle and adds scrolling, insert space, stationery, background recognition, and static rendering. Note also provides methods for saving and loading documents.
  • NoteToolbar – NoteToolbar is an ink-centric toolbar that provides basic note-taking commands. The toolbar can be used with one or more Note controls, as well as other controls.
  • NoteBox – NoteBox is a combination of Note and NoteToolbar. Using this powerful control, you can quickly create a Journal-like application.

Building the Application

This section describes how to build an application by using InfiNotes. For the note-taking application, we use the NoteBox control, which provides a note-taking control and a toolbar (all we need for a functioning note-taking application) in one easy-to-use control.

Creating the application

Create a new C# Windows application project in Visual Studio. Name the project NoteApp.

To use the Visual Designer to enable the NoteBox control:

  1. Drag the NoteBox control onto the form.
  2. Set the Dock property to Fill.

The basic application is now ready to run.

For those wanting to do it by hand, follow these two steps:

  1. Add a reference to the Agilix.Ink assembly.
  2. Add the NoteBox field and initialize it:
private Agilix.Ink.Note.NoteBox fNoteBox;
...
public NoteApp()
{
   ...
   // Create a NoteBox and assign to the form
   fNoteBox = new Agilix.Ink.Note.NoteBox();
   fNoteBox.Dock = DockStyle.Fill;
   Controls.Add(fNoteBox);
   ...
}

Either way, you may want to increase the default size of the application or your notes look like 3x5 cards. Now compile, run, and enjoy. You have just built your first note taking application using InfiNotes!

Before adding more features, change the application to use the new XP style for the toolbar. You can do this with a .config file or by adding these lines to the Main method:

[STAThread]
static void Main()
{
   // Use the XP style, make sure you call these before creating any forms
   Application.EnableVisualStyles();
   Application.DoEvents(); 

   Application.Run(new NoteApp());
}

File Menu Commands

The sample application we built in the previous section lacks the ability to load and save data. Let's add a File menu with menu choices (and their underlying implementation) Load and Save.

Before we start that, it is important to understand a little more about class organization. The class Agilix.Ink.Note.Document contains the data for the note. There are two classes that give a visible view of the data, Agilix.Ink.Note.Note and Agilix.Ink.Note.Renderer. We already discussed the Note class as one of the main classes in the assembly. The Renderer provides a static view of the data for use in printing or previews.

The Document class is thread safe, and InfiNotes takes advantage of that to perform background ink division and recognition. The Note class on the other hand is a Windows Forms control and, like all such controls, its methods and properties should always be accessed from the thread that created it.

Add a File menu to your application that includes New, Open, and Save:

public NoteApp()
{
   // Adding a menu for the application
   System.Windows.Forms.MainMenu menu = new MainMenu();
   menu.MenuItems.Add("File",new MenuItem[] 
   {
      new MenuItem("New",new EventHandler(File_New)),
      new MenuItem("Open...",new EventHandler(File_Open)),
      new MenuItem("Save...", new EventHandler(File_Save)),
      new MenuItem("Exit", new EventHandler(File_Exit))
   });
   this.Menu = menu;
   // Add any other initialization here
}

To create a new note, create a new instance of the Document class.

private void File_New(object sender, EventArgs e)
{
   fNoteBox.Note.Document = new Agilix.Ink.Note.Document();
}

The Document class has a Load and Save method that operates on streams. You can use FileStream as in this example, or use a database LongText or Blob field.

private void File_Open(object sender, EventArgs e)
{
   OpenFileDialog dialog = new OpenFileDialog();
   dialog.Title = "Open Agilix NoteTaker File";
   dialog.CheckFileExists = true;
   dialog.Filter = "Agilix NoteTaker files (*.ant)|*.ant|";
   if (dialog.ShowDialog(this) == DialogResult.OK)
   {
      using (FileStream fs = new FileStream(dialog.FileName,
                              FileMode.Open, FileAccess.Read))
      {
         Document document = new Document();
         document.Load(fs);
         fNoteBox.Note.Document = document;
      }
   }
}
private void File_SaveAs(object sender, EventArgs e)
{
   SaveFileDialog dialog = new SaveFileDialog();
   dialog.OverwritePrompt = true;
   dialog.CheckPathExists = true;
   dialog.DefaultExt = "ant";
   if (dialog.ShowDialog(this) == DialogResult.OK)
   {
      using (FileStream fs = new FileStream(dialog.FileName,
                     FileMode.Create, FileAccess.ReadWrite))
      {
         fNoteBox.Note.Document.Save(fs);
      }
   }
}

Edit Menu Commands

Next, let's examine the editing commands—such as cut, copy, and paste—you can use in the Note control. The Toolbar communicates with the Note control through the ICommandTarget interface, which has these methods: Update, Execute, and HasSelection. You can reuse the Toolbar with other controls in your application by implementing this interface and acting on the commands.

The Note control contains methods for common edit actions, such as cut, copy, and paste. The control also contains methods such as CanCut, CanCopy, and CanPaste, for determining whether the edit actions should be enabled. You call these methods when responding to ICommandTarget requests.

Add the Edit submenu, like the File menu, and register for the Popup event. In the Popup event handler enable or disable the menu items by using state information from the Note control, as in this sample:

private void EditMenu_Popup(object sender, EventArgs e)
{
// Enable the items based on the state of the control
   MenuItem editMenu = Menu.MenuItems[1];
         
   editMenu.MenuItems[0].Enabled = fNoteBox.Note.CanUndo();
   editMenu.MenuItems[1].Enabled = fNoteBox.Note.CanRedo();
   // -
   editMenu.MenuItems[3].Enabled = fNoteBox.Note.CanCut();
   editMenu.MenuItems[4].Enabled = fNoteBox.Note.CanCopy();
   editMenu.MenuItems[5].Enabled = fNoteBox.Note.CanCopy();
   editMenu.MenuItems[6].Enabled = fNoteBox.Note.CanPaste();
   editMenu.MenuItems[7].Enabled = fNoteBox.Note.CanDelete();
   ...
}

The Click event handlers for most of these edit menu items are trivial, like this Edit_Undo event handler:

private void Edit_Undo(object sender, EventArgs e)
{
   fNoteBox.Note.Undo();
}

The handler for FormatInk is more complex. It opens a dialog, allows the end-user to choose the format, and then applies the format to the current selection. The InfiNotes assembly exposes several common ink dialogs that you can use. These include the DefinePen, ConvertInkToText, and FormatInk dialogs. The following example shows the use of FormatInk. We initialize the FormatInk.WritingInstruments property from our NoteToolbar so that current toolbar states are reflected in the FormatInk dialog.

The FormatInk dialog exposes a FormatCommand object, which we set to the current state with Update. After dismissing the dialog, we use FormatCommand to set the new state of the strokes.

private void Edit_FormatInk(object sender, EventArgs e)
{
   // Use the FormatInk dialog from Agilix.Ink.Dialogs
   Agilix.Ink.Dialogs.FormatInk dialog = new Dialogs.FormatInk();
   // Specify the pen collection
   dialog.WritingInstruments = fNoteBox.Toolbar.WritingInstruments;
   // Specify the colors to use
   dialog.Colors = fNoteBox.Toolbar.ColorCollection.ToArray();

   // Keep the selection visible while we show the dialog
   fNoteBox.Note.HideSelection = false;

   // Get the current state
   fNoteBox.Note.Update(dialog.FormatCommand);
   // Show the dialog
   if (dialog.ShowDialog(this) == DialogResult.OK)
   {
      // The dialog creates a command we all the changes
      // We just need to send it to the Note to execute 
      fNoteBox.Note.Execute(dialog.FormatCommand);
   }

   // Set HideSelection to the normal mode again
   fNoteBox.Note.HideSelection = true;
}
Note   All the commands performed are automatically added to the Undo buffer, so that you can perform Undo/Redo on any operation whether it originates from the end-user or from the program.

Paper Menu Commands

InfiNotes comes with dynamic paper stationery. The stationery grows when the paper grows. The stationery is fully configurable, and you can let the user create the stationery they want, or just use some of the predefined stock stationery by using CreateStockStationery or CreateStockStationeryWithTitle. For this application, create a new Paper menu for stationery, like the File and Edit menus, and simple Click event handlers such as this:

private void Paper_Grid(object sender, EventArgs e)
{
   fNoteBox.Note.Stationery = 
      Stationery.CreateStockStationery(StationeryStockType.Grid);
}

Finishing the Application

We have now described how to build a fully functional ink note-taking application. Figure 1 shows an example of what your application may look like:

Figure 1. Sample application screenshot.

There are additional features you can add. The code for the sample application is good starting point for these features.

Printing

We mentioned earlier that the Document class contains the data for the note. The Note class is a dynamic, editable view of the Document, and the Renderer is a static view of the Document. Use the Renderer for printing or drawing the Document. Check the code in the sample application, available with the InfiNotes download, for more details.

Toolbar

Using ICommandTarget, you can separate the Toolbar from the Note control. You can share the Toolbar with multiple note controls, and even other controls such as edit boxes. Or you can implement your own Toolbar, using the 16x16 pixel images, provided in the Images classes.

Conclusion

Using InfiNotes Standard Edition, you can easily integrate ink note taking into your application. The InfiNotes Professional Edition suite of controls extends the basic functionality with features such as text, multiple pages, images, flags, and shapes. The Professional Edition is royalty free and you can download a trial at www.infinotes.com.

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.