CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

Tablet PC

  • Vista for the tablet PC

    This weekend I finally installed the final Vista on my tiny tablet. Which is an old notebook with (these days) unimpressive specs but just refuses to retire. Easy to carry, runs XP and VS 2005 quite well and so far behaved well under the Vista beta's. Beside Vista I installed the "Vista experience pack for Tablet PC and "Ink Desktop". Pen and ink integration were already quite good and now I have this:

    Some observations

    • Multilingual handwriting is installed by default. I run an English OS with regional settings set to Dutch. Both handwritings are recognized very, very well. I just wish my primary school teacher, with whom I had a continuing struggle on my handwriting, could see this. He was right, my handwriting is terrible. But Vista understands.
    • Switching recognition language is in the menu of the input panel. The input panel itself is a big improvement over the one in XP Tablet PC edition. The two way interaction with any text input control is great.
    • Ink desktop lets you scribble right on the desktop. The content is saved over sessions, no need for loose notes, just use the desktop itself.
    • The equation writer not only recognizes individual characters but also their relative position in the equation. It requires a tidier hand writer than the input panel, as recognizes on a character instead of a word base.
    • Vista requires a good graphics card. My old tablet does not have DX9 in hardware which shows off. No Aero is not the main point. The response of the machine is good but when it's busy the repaint of the desktop can lag behind for a very long time. The good thing is that Vista smoothly multitasks, the bad thing is that it really needs good graphic hardware.
  • Tidbits (Javascript and OOP ?)

    For the past few weeks I've been working fulltime on a big Javascript application. At first this did not look like any source for blog fodder at all. Having learned lots of new things I have changed my mind and am working on a big post on Object Oriented Programming in JavaScript. What is possible and what is not. Information on the web varies in a high degree. Feel free to make suggestions on what I should include and what not.

    It's not going to be a rant on why JavaScript sucks, I can't agree on that. It's not going to be a big praise on the language either, script remains script. JavaScript is just there, you cannot ignore it; better just make the best out of it.

    Two Dutch tidbits in the last  weeks:

    • After supporting the Frisian language, the Vista RC does include a (tablet) handwriting recognizer for Dutch! At last ! Saw it at work today on the MS Technet meeting. The default language of my OS is English. I'll look into installing multiple recognition languages and will come back on it.
    • My slightly deformed article in the Dutch .NET magazine has been reformatted and is available online here.
  • Working with .NET 3.0

    Over the last days I've been working with the .NET 3.0 framework (or whatever you want to call it). Starting from the perspective of a real world application, not a bunch of cool solutions looking for a problem. The idea was to create a WPF tablet PC inking app which stores and retrieves images through a WCF webservice. It worked out pretty well, of course with some beta bumps, and I would like to share some of my findings. These are based on the "official" Vista beta2 and the current CTP of WinFx..

    Which platform to use as development platform

    The 3.0 framework is the API to build apps for Vista. But using Vista as a development platform is a different ballgame. Building the presentation part works like a charm but building services on Vista is no fun. Vista is far stricter in rights than XP, to circumvent that you can start a program, including Visual Studio, as administrator. But whatever I tried I never managed to create a new service under Vista. The best result was a dialog like this.

    Which looks like old horror in a new coat. I gave up and went on using XP as a development platform. After all not a big deal. One of the nice things of .NET 3.0 is that it also runs on XP and server 2003. This separates the development and deployment of Vista applications from the Vista OS and does make the migration path easier.

    Hosting services

    There are several ways to host a service and the VS additions provide several templates for that. I used the WinFx website template which works pretty well. The template generates a skeleton service including a description of the configuration in the comments. You can also add a service to an existing Windows (WPF) or console application, in this scenario the application itself will host the service. The VS additions contain templates for these which spit out another variation of a skeleton service with another configuration in the comments. The configuration settings for a service have changed over the last releases of WCF, the bad thing is that the configuration settings generated for a self hosted service are those of a previous version. Nevertheless, after some fiddling  I managed to get a WPF hosted service up and running. The bad thing is that trying to generate a proxy to consume the service, I encountered a bunch of quite exotic error messages. MSN search was blank on them, Google found them in a couple of very deep digging MS blogs; all of them were security related. My conclusion was to stay from all of this till I have a huge amount of spare time or a new release of the framework. But the IIS hosted service worked well and was a pleasure to work with.

    WPF

    I can be quite short on WPF: it's a plain delight. The additions give you three views on a wpf-form: a visual designer, a XAML markup view and the code-behind. My advice is to forget about the visual designer. Dropping and dragging components from the toolbox will leave you with fixed layout forms and markup which is complete spoiled with unnecessary attributes. Imho WPF is a way to get rid of hard to design fixed layout winforms and brings the ease of flowing web-layout to Windows apps. Besides that the visual designer will give up on you sooner or later. When the markup needs members from the code-behind, for instance for a custom command, you have to add your assembly to the namespaces of the markup. The problem is that the designer is not able to find this assembly and will quit on you. The error message is nice though:

    Resharper has a similar problem with XAML. In the build process out of the XAML an assembly is generated. But in the code editor this assembly is not available yet, as a result Resharper will mark all xaml components in red and fails on code-completing the objects. But it doesn't crash.

    Tablet PC

    Tablet PC functionality is integrated in .NET 3.0. You no longer need to install the Tablet PC SDK to develop Ink aware applications, it's all in the InkCanvas control. Inking itself is also far better integrated into the runtime. You will notice this when drawing with a mouse. This is far smoother than the former, COM based, tablet runtime. Tablet code is not source code compatible with the old API. The architecture and spirit of the API is the same but a lot of methods have new overloads, encapsulating the old versions. Also the Ink property has disappeared, the collection of strokes itself is a main property of the InkCanvas.

    To conclude

    The result is an application which could have been built using classic asmx webservices and classic winforms. As a matter of fact I had already done that some time ago. But building the apps this way required less and clearer code. And the possibilities to add cool things to the app are enormous. For instance I would like to add peer to peer picture exchange using a self hosted service. Which would have been quite difficult to implement using the classic tools. Now it seems just a bug-fix away. I'm really looking forward to a next release.

  • Installing Vista build 5270 on a (tiny) Tablet PC

    Vista is coming. To us developers Vista is about new API's, to users Vista is about a new UI. As a developer you have to take a good look at that as well; that's how people will (want to) work with the software you make. The feel of Vista is different; I could try to list all the small and bigger differences but to get a feel yourself there is no other way than work with it yourself. The latest CTP is stable and does not require any hyper hardware as long as you don't install it in a virtual PC. Back to multi-boot. To get a full immersion I recently installed it on my tablet PC.

    Again the OS has many monikers

    • In the initial startup it's still Longhorn
    • On the desktop it's still beta2
    • According to the screen saver it is Windows Tablet PC edition
    • <Update> Build 5230 in my original post. Typo. Thanks Sander </update> 

    It is not the real beta2 yet. As I understand matters there will not be a distinct release labeled beta 2, but several CTP's instead. Working with build 5270  is a real pleasure. Build 5219 turned blue once in a while but this one keeps on running and running. And it's running well. Despite my machine's good but not great hardware specs (1Ghz Pentium mobile and 512 Mb RAM) it's smooth (smoother than XP tablet PC ed !) and very very usable. The tablet functionality is now fully integrated in the OS. Peter Wright has written some very good posts describing that.

    My personal favorite Vista feature is the magnifying glass. Here it is in full action

    It highlights another very specific feature of Vista which Frans will like. The date's description is no Dutch, not even double Dutch. New amongst the languages supported is Frysk. Which is one of the many dialects spoken in the Netherlands and the only one which made it getting a special status. In the province of Friesland official documents are bilingual, in Dutch and Frysk. To spell it correctly you need letters not part of the standard Dutch character set. The official name of the province is Fryslân. To type that you needed a French codepage or an international keyboard with dead keys. Vista has FY, the Frisian keyboard layout. An a circumflex (â) cannot be part of a domain name, which at the time led to some insulted Frisians. For them it is a serious matter, to the others in the country it is somewhat a source of amusement. Personally I would like Grunnegs added :)

    Developing software for Vista is going to be a different ballgame. VS 2005 installs and works well on Vista but doesn't open the Vista api's yet. New is  the Orcas CTP, which is actually just a new name for the WinFx CTP's. Vista is the platform on which WPF (the presentation part of winfx) will really shine. Orcas will install on XP and server 2003 as long as you also install the WinFx runtime on the machine. But I'm going for Vista. New OS, new UI, new languages, new stuff to play with. With VS 2005 up and running I need a future focus; learning just never stops.

     

  • Charles Petzold, WPF and the Tablet PC

    Charles Petzold's book Programming Windows is a classical masterpiece. Through his work a whole generation learned how to write programs for that new strange graphical operating system called Windows. As that grew in size over the years the new editions of the book got thicker. A copy of the fifth edition book is still a cornerstone under my daily work

    Being used to MS-DOS the Windows API was pretty complex. I have grown up with Delphi, whose VCL (Visual Component Library) is a framework which hides the Windows api itself. The VCL came with source code. In your programs you would use the components from the framework and in Petzold's book you would read what the code actually did. In the .NET framework the (presentation part of the) windows api is encapsulated in the System.Windows.Forms namespace. The .NET framework does not come with sourcecode. Petzold's book is still close at hand but these days mainly has a physical support task.

    The Window Presentation Framework (WPF) is the new presentation layer of the upcoming Vista OS. The best news is that Charles Petzold is writing a book on WPF and has a beautifull blog on that. Petzold's writings are very much into the heart of the matter. New projects in Visual Studio always contain an amount of generated code; Charles starts with an empty project and adds functionality line by line. Step by step you will understand how the technology really works. This is going to be the way to learn WPF.

    Just like me, CP has a weak spot for the tablet PC. There are not many books about the tablet, actually there is only one which matters when writing tablet code. But that book is not complete as it does not cover the real time stylus (RTS) api, which is going to be quite important in Vista. Quite recently CP has published a great article on the RTS for MSDN magazine.

    Besides being a great writer he is also a great presenter. Last year I've seen at WIndows anywhere feb 2005 his presentation Ink as a graphical medium, where he dances around with a tablet on his arm.

    Lovely show. Now I just have to see his mini-keynote Programming for Windows 1.0,  Once.

  • Installing Vista build 5219 (on a tablet PC)

    Recently I installed Vista beta 1 on my tablet. Not in Virtual PC but as dual boot. You need a dedicated partition for that, but it is the only way Vista can reach your machine's hardware functionality like DX or the digitizer tablet. The first install was nice but not really a tablet, after adding the TIP install it started feeling like the real thing. Despite my tablet having (relatively) meager specs it worked pretty well. I did have the occasional blue screens. As far as I can see these were caused by my external firewire CD drive and by me trying to do something which needs more memory than available; like loading a WPF application in VS 2005. Another way to blow up was trying to assign a read-only property of the InkCanvas in XAMLpad. Although you would expect Vista to fail gracefully in these scenarios......

    Since the PDC there's beta 2, build 5219. I downloaded it from MSDN the beta site. My MSDN product key was refused by the setup. Luckily I had already found an entry in Tim Sneaths blog which provided a product key which worked. Have taken that hurdle setup refused to load the DVD image. Starting the setup from XP, instead of booting form the DVD worked better. The setup itself rolls on unattended but does not install any network drivers;  just the one for the Infra red device. I wasted some time in the Install Supplemental drivers part of Vista. I'm not quite sure but that looks like a little messed up. First of all it was looking for a file DriverRepository.idx, the only thing available was driverre.idx (an 8.3 filename !). Having fed that to the driver installer it was still no success, kept complaining about failing to install. What did work was installing the drivers the classical way. Go to control panel/system/device manager. You can see the missing drivers there. Select update driver and tell Vista you will manually pick a driver from the list. Both my wired and wireless driver were in the list of compatible drivers and setup went perfect.

    Now I have a connected Vista tablet. It does include the InkBall game. Still very nice but it shows that you can get RSI with a pen s well. The tablet functionality in beta 2 is very good. For a good description and review of that I warmly recommend Collin Walker's article. The TIP (Tablet Input Panel) has had quite an overhaul since the first Vista preview. The two sym buttons have turned into a sym button which list quite an impressing list of symbols and a web button which now lists .nl and not .uk. In the control panel I set regional setting to the Netherlands, .nl is our top level domain. The only thing still missing is a handwriting recognizer for the Dutch language.

    There is a setting for touch screens, by default that is switched on. The real new thing for a classical tablet are the flick gestures; see Collin Walker's article for a good review of those. The 5219 build still occasionally produces blue screens on my machine (Acer CT 111) but is on the average smooth to work with; although it sometimes stalls in the TIP. Right now I'm installing the WPF SDK. I don't doubt the traditional ink apps still work, and now I want to see more. To be continued (in the next weekend :)).

  • A touching gesture

    I missed my chance to come to the PDC and hear this first hand, but blogs can fill the gap.

    Microsoft has announced it will license the current Tablet OS, Windows XP 2005 Tablet PC edition, to touch screen PC makers. Fujitsu already announced one for next month. A touch-screen is by long not as sophisticated as a digital digitizer, when it comes to handwriting you're lucky to reach some level of finger-painting. But the Tablet OS has some things which can do great things for touch-screens. My bets are on gestures. The Tablet OS has a built in gesture recognizer which recognizes movements of the pen (finger) like a circle or an arrow to the right.

    Everybody is used to pushing a button on a touch-screen, steering the mouse pointer by touching becomes stranger. Just imagine some of these possibilities :

    • Drag and drop with your finger
    • Finger stroke to the left, right, up or down. To manipulate or move something
    • Circle your finger around something to select it

    All without the need for any extra controls. With the Tablet OS and its SDK it's no big deal to build this into an application. In this post you can read an overview of and how to work with gestures in your code.

    In Vista tablet functionality has become an integrated part of the OS. Noteworthy are flicks, which is a new system-gesture (see this post for the difference between system and application gestures) intended for browsing, a flick would be the pen (finger) equivalent of the page down key. Vista will also have touch-screen support. Touch and pen support can be in conflict, it's hard to write on a screen without your hand resting on it, and thus touching it. But what about a machine with two screens ? A small one on the outside to list new messages and operate your mediaplayer. Touch would be fine. And a big one inside to write on.

    I'm going to stop before I drown in pure speculation. Just wish I was in LA.

  • Beta of the TIP for Vista Tablet PC

    Recently I installed the Vista Beta on my Tablet PC. It works, given the occasional blue screen, quite well; but didn't feel like a real tablet PC yet. The pen worked but the Tablet Input Panel (TIP) and the handwriting recognizers were still missing. There is good news: a beta of the TIP is now available to MSDN subscribers. The TIP does not make much sense without handwriting recognition; in the beta one for the English language is included. My first impressions are quite positive. XP Tablet Edition 2005 could keep up with my lousy handwriting and Vista has no problems either.

    There is no possibility to change the language. What also changed (or isn't included yet) compared to the XP version is context sensitive recognition of handwriting. When you want to scribble a web-address in XP Tablet PC's edition IE the recognition of url's is favored using factoids. Buttons with url specific words like http:// and .com automatically pop up. The Vista TIP has three special character pad's; but you have to select them yourself with a click. This is what the web-pad looks like

    <>

    Note the .uk button.

    The recognizer is also available to your own code. Again I tried my text-reco demo which was build with the tablet SDK (which was originally designed for VS 2003) and VS 2005.

    <>

    Like a charm. Now my Vista Tablet is a real Tablet.

  • Vista is a big push for the Tablet PC. But it's not a full tablet yet...

    My first install of Vista was on a Virtual PC. Nice but my main problem was that it's sluggish and unresponsive. Even if it has a 2.Ghz Hyperthreaded CPU and a full gigabyte of RAM at its disposal. The cause of that, as discussed here on Joel on Software is Virtual PC's graphics driver. Vista relies on DX and Virtual PC's emulated S3 doesn't support that. I decided to give Longhorn another spin on my Tablet PC. Not virtual but as a dual boot so it could work with some real hardware. You need an empty NTFS partition to install Vista and my tablet comes with FAT32. I'm not going to tell you the full story how I got two NTFS partitions (one to keep XP, one for Vista), it's something I would like to forget as  soon as possible. But I do want to thank my neighbour for salvaging things when it had really gone bad. After that installing Vista itself was no big problem, it just takes patience. I got the network (both fixed and wireless) up and running with the XP drivers.

    Vista running directly on the Tablet hardware behaves very well. Despite the machine's moderate specs (1 Ghz CPU and 512Mb's of RAM) it is responsive and a pleasure to work with. The good thing is that Vista does recognize the tablet pen straight out of the box. It is a pointer and click-and hold works fine. After installing the driver the logon button (which is by definition an equivalent of pressing ctrl-alt-del) did exactly what it's supposed to do. But the tablet input panel (TIP) is not a part of the beta; it is available to registered beta testers. I'm trying to get my hands on it.

    There are no tablet applications like Windows journal and the like included yet. To see what does work I set up development tools. Installing the VS 2005 beta had a small problem with MsXML. Dave Glover had several solutions at hand. The first one, to install the msxml6.msi by hand before installing VS worked like a charm. To start with the classical way of developing tablet apps the Tablet PC SDK came next. As a first test I took my sample on handwriting recognition. Which, after some small modifications, built fine. Running it shows the Tablet parts missing in Vista:

    Scribbling with the pen works, but there are no handwriting recognizers installed. Trying my gesture recognizer sample showed that also the gesture recognizer isn't part of Vista. But using the SDK is not really the way to go for Vista Tablet development. The API's have become part of the Avalon Presentation layer. Here comes XAML ! More on that later.

    The Beta 1 release Vista did also inspire several bloggers. To name the most interesting one's for developers :

    Subscribed !

    The Vista tablet is far from complete but looks very promising. I can't wait for the moment my Tablet will be single boot again. Just Vista..

  • Past, present and future (my favorite PDC sessions)

    Last PDC, the 2003 edition, was one big flood of new things. It was the first time Longhorn (now named Vista) and Whidbey (now named Visual Studio 2005) were presented to the developer community. The coming, 2005 edition, will be on the same, by now almost today's, tools. There is a searchable list of sessions online. The majority is on the same products but this time based on solid beta1 (Windows Vista) and beta 2 (Visual Studio 2005) versions. The goods we received in 2003 were more spectacular than the crystallized reality of today. Remember the WinFS and ObjectSpaces buzzwords ? Those concepts are still there, a further evolution of the ideas will be at the PDC 2005, but it takes some browsing to find them.

    The session summaries are of a diverse quality. Some are technical vague marketing babble but most are really promising. There is one on the tablet Windows Vista ("Longhorn") Tablet PC: Advances in Creating Ink Enabled Applications, co- presenter Shawn van Ness has a  blog post on what they are going to do there. And to get in the mood the tablet team has started a blog. Subscribed !

    When it comes to the future I pre-selected some sessions (titles in bold, snippets from the summary in italics). Despite the avalanche on rich applications I want to hear ASP.NET: A Sneak Peek at Future Directions in Web Development and Designer Tools.  Let's see what the future brings for me and my simple mortal users. My summit will be the next three, where the old buzzwords are back in a new form. This time as clear programming languages and API's : C#: Future Directions in Language Innovation from Anders Hejlsberg. Anders can talk in a very easy and understandable way about quite abstract ideas. In this session he will talk about the elements in the next C# to create powerful APIs for expressing queries and interacting with objects, XML, and databases in a strongly typed, natural way. What MS wants to do with these APIs will be told in The .NET Language Integrated Query Framework: An Overview. The APIs will not be restricted to C#, also in VB.NET you will be able to use them. Today you write your code in a language of choice and access data using a SQLadapter, XMLdocument or plain object. Each of them has a specific way of interacting with the data, and much of the complexity in today's applications is the result of these mismatches. The "Orcas" release of Visual Studio aims to unify the programming models through integrated query capabilities After the overview I am ready for Using the .NET Language Integrated Query Framework with Relational Data  Database-centric applications have traditionally had to rely on two distinct programming languages: one for the database and one for the application. That's what the query framework will bridge. Using these advances, database queries that previously were stored as opaque strings now benefit from static type checking, CLR metadata, design-time type inference, and of course IntelliSense. Sounds like dBase on steroids :) Back to the future.

    Will I be able to see all this live? It depends..

  • The fix for the Tablet PC's memory leak is (finally) there

    Microsoft has finally released the fix for the memory leak in the tablet PC. It's diguished as Windowx XP hotfix KB895953. Took a while. At the time (5 months ago !) I wandered how serious the bug really was for real life day to day tablet use, but the update shows it was quite fundamental. While updating you see tabtip.exe come flashing by, that's really a core componennt. What strikes me is that I had to read it in the Winfo newsletter, MS didn't even bother to send out a mailing to their tablet partners (yet ?).

  • Any Tablet PC sessions at the PDC ?

    The PDC 2005 frenzy is heating up, on Codebetter you'll find poetic as well as total geeky starters. The content of the PDC is also starting to materialize. I skimmed all session and tracks for "Tablet PC" but did not find a thing. So what's next ? Convert my Tablet  to a beer coaster and stuff myself with conference snacks ?

    To be serious: there will be a lot of tablet stuff on the PDC but you will not find it under the name Tablet PC. Recently I was wandering what direction the tablet is going to take. Some answers to that were already there on the PDC 2003. In the keynote of the PDC 2001 the tablet PC SDK was announced, tablet PC's themselves were available in 2002, about a year after that. The 2003 PDC was all about Longhorn and its presentation layer Avalon. Some bullet highlights from a 2003 presentation slide deck :

    Avalon support for Pen Input and Ink:
    • Stylus is a 1st Class Input Device
    • System Controls are pen-aware
    • Any Avalon element can support ink

    Improved Ink Recognition

    • Personalization
    • Ink Analysis
    • Support for more languages
    Native Avalon Input Device
    • Tightly Integrated into Avalon Input Manager and Events system
    • Rich Stylus Events

    Unified input stream for Stylus and Mouse

    • Stylus emulates mouse
    • Containment for promoted events in Avalon apps

    Ink will be a 1st class citizen of the WinFx framework:

    The presentation is almost two years old but still very worthwhile to study. You will recognize many parts of the tablet API as well as WinFx and the Longhorn programming model.

    This year, on the Windows HEC conference there was another interesting presentation. Longhorn plans go further than pen and ink, fingertip touch will be added. To quote some bullets:

    • In Longhorn we are planning to add Touch as a new mode for Navigation and Control
    • Great complement to Pen and Speech Input
    • All navigation with Pen also works with Touch but is more efficient and intuitive - no pen required
    • Mouse operations: Tap and Double tap with finger
    • Advanced gestures: Finger flicks
    • Longhorn plans to enable easy precision targeting with finger
    • Stylus still preferred for ink input

    To use touch requires a resistive digitizer type, to use a pen requires an ElectroMagnetic digitizer. Dual mode digitizers exist. From OS perspective there are two drivers; for the API touch is an extension on the Tablet's Ink API. The presentation has some great ideas how to overcome the problems of combined digitizers. Imagine resting your hand on the screen while writing with the pen. The first would fire of the resistive digitizer, the second the EM-digitizer.

    This is to be continued on the PDC 2005. If you're looking for tablet presentations, search for Avalon or straight for the functionality you're looking for. I.e. handwriting recognition. It's all becoming mainstream. Last february, Shawn van Ness, author the MS column mobile inkjots, has joined Microsoft as a PM to integrate the tablet API into Avalon to make it happen. I just wished he would blog a little more. As an MS employee he can't take part in bloggin' my way to the PDC. But I would read his scribbling anyway.

    <Update>Shawn just did post. On Ink and Avalon...</update>

  • Tablet PC input: recognizing gestures and creating strokes from code

    In my previous post on Tablet PC pen input I explored handwriting recognition. I explored how the language specific recognizers of the tablet API translated your scribbling into text, listed the possible alternatives and the confidence it had in the results. The Tablet API has another recognizer built in, this one recognizes gestures. In this post I will explore that a little further. My demo code will try to recognize some specific gestures and draw it's idealized form from strokes created in code.

    Again I have a simple Winform with a panel on it with a private InkCollector object. The collector is created in the form's constructor and disposed in the form's Dispose method. For the details on that check my previous post. By default an inkcollector object collects strokes. By setting it's CollectionMode property you change this. Here the collector is told to only check for gestures. The user can draw on the panel, but after a short lapse of time the strokes will disappear having been processed by the gesture recognizer. A gesture is a certain movement of the pen. For instance tapping the digitizer is a gesture. But also drawing a line, circle or even an arrow. These gestures fall into two categories. First come the system-gestures, which include tap, double tap and drag, a full list is is the SystemGesture enumeration. The second group are application gestures, a full list of of these is in the ApplicationGesture enumeration.

    In this story I will dive deeper into the latter. A system gesture is always recognized, but if you want your application to recognize an application gesture you must subscribe to it using the inkcollector's SetGestureStatus method. You can be a lazy coder by passing in ApplicationGesture.AllGestures but that is a bad habit. Recognizing gestures is a costly matter so please be economic when subscribing. When a gesture is recognized the InkCollector's Gesture event will fire. Add an event handler to inspect the gestures and do something with them.

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using Microsoft.Ink;


    namespace GestureSketcher
    {
        public class Form1 : System.Windows.Forms.Form
        {
            private System.ComponentModel.Container components = null;
            private System.Windows.Forms.Panel panel1;

            private InkCollector ic;

            public Form1()
            {
                InitializeComponent();
                ic = new InkCollector(panel1);
                ic.CollectionMode = CollectionMode.GestureOnly;
                ic.SetGestureStatus(ApplicationGesture.Scratchout, true);
                ic.SetGestureStatus(ApplicationGesture.Up, true);
                ic.SetGestureStatus(ApplicationGesture.Down, true);
                ic.SetGestureStatus(ApplicationGesture.Left, true);
                ic.SetGestureStatus(ApplicationGesture.Right, true);
                ic.SetGestureStatus(ApplicationGesture.Square, true);
                ic.SetGestureStatus(ApplicationGesture.Circle, true);
                ic.SetGestureStatus(ApplicationGesture.SemiCircleRight, true);
                ic.SetGestureStatus(ApplicationGesture.ChevronUp, true);
                ic.SetGestureStatus(ApplicationGesture.ArrowUp, true);           
                ic.Gesture +=new InkCollectorGestureEventHandler(ic_Gesture);
                ic.Enabled = true;
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                if( disposing )
                {
                    if (components != null)
                    {
                        components.Dispose();
                        ic.Dispose();
                    }
                }
                base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            private void InitializeComponent()
            {
                // just panel1

            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.Run(new Form1());
            }



            private void ic_Gesture(object sender, InkCollectorGestureEventArgs e)
            {
                // Get bounding box of strokes drawn
                Rectangle rcBounds = e.Strokes.GetBoundingBox();

                // Calculate bounding points
                Point rcBoundsTopLeft = new Point(rcBounds.Left, rcBounds.Top);
                Point rcBoundsTopMid = new Point((rcBounds.Left + rcBounds.Right) /2, rcBounds.Top);
                Point rcBoundsTopRight = new Point(rcBounds.Right, rcBounds.Top);   

                Point rcBoundsMidLeft = new Point(rcBounds.Left, (rcBounds.Top + rcBounds.Bottom) /2);
                Point rcBoundsMidRight = new Point(rcBounds.Right, (rcBounds.Top + rcBounds.Bottom)/2);

                Point rcBoundsBottomLeft = new Point(rcBounds.Left, rcBounds.Bottom);
                Point rcBoundsBottomMid = new Point((rcBounds.Left + rcBounds.Right) /2, rcBounds.Bottom);
                Point rcBoundsBottomRight = new Point(rcBounds.Right, rcBounds.Bottom);

                int gesturesRecognized = 0;

                for (int i=0; i< e.Gestures.Length;i++)
                {
                    bool curved = false;
                    Point[] pts = new Point[0];
                    Gesture gest = e.Gestures[i];

                    switch(gest.Id)
                    {                       
                        case ApplicationGesture.Down :
                            pts = new Point[2];
                            pts[0] = e.Strokes[0].GetPoint(0);
                            pts[1] = new Point(pts[0].X, rcBounds.Bottom);
                            break;
                        case ApplicationGesture.Up :
                            pts = new Point[2];
                            pts[0] = e.Strokes[0].GetPoint(0);
                            pts[1] = new Point(pts[0].X, rcBounds.Top);
                            break;
                        case ApplicationGesture.Left :
                            pts = new Point[2];
                            pts[0] = e.Strokes[0].GetPoint(0);
                            pts[1] = new Point(rcBounds.Left, pts[0].Y);
                            break;
                        case ApplicationGesture.Right :
                            pts = new Point[2];
                            pts[0] = e.Strokes[0].GetPoint(0);
                            pts[1] = new Point(rcBounds.Right, pts[0].Y);
                            break;
                        case ApplicationGesture.Square :
                            pts = new Point[5];
                            pts[0] = rcBoundsTopLeft;
                            pts[1] = rcBoundsTopRight;
                            pts[2] = rcBoundsBottomRight;
                            pts[3] = rcBoundsBottomLeft;
                            pts[4] = rcBoundsTopLeft;
                            break;
                        case ApplicationGesture.ArrowUp :
                            pts = new Point[5];
                            pts[0] = rcBoundsMidLeft;
                            pts[1] = rcBoundsTopMid;
                            pts[2] = rcBoundsBottomMid;
                            pts[3] = rcBoundsTopMid;
                            pts[4] = rcBoundsMidRight;
                            break;
                        case ApplicationGesture.ChevronUp:
                            pts = new Point[3];
                            pts[0] = rcBoundsBottomLeft;
                            pts[1] = rcBoundsTopMid;
                            pts[2] = rcBoundsBottomRight;
                            break;
                        case ApplicationGesture.SemiCircleRight :
                            pts = new Point[3];
                            pts[0] = rcBoundsBottomLeft;
                            pts[1] = rcBoundsTopMid;
                            pts[2] = rcBoundsBottomRight;
                            curved = true;
                            break;
                        case ApplicationGesture.Scratchout :
                            // erase last stroke drawn
                            ic.Ink.DeleteStroke(ic.Ink.Strokes[ic.Ink.Strokes.Count - e.Strokes.Count- 1]);
                            panel1.Invalidate();
                            break;

                    }

                    if (pts.Length > 0)
                    {
                        gesturesRecognized++;
                        // Create a stroke to draw form recognized
                        Stroke str = ic.Ink.CreateStroke(pts);
                        str.DrawingAttributes.FitToCurve = curved;

                        switch(gest.Confidence)
                        {
                            case RecognitionConfidence.Strong :
                                str.DrawingAttributes.Color = Color.Green;
                                break;
                            case RecognitionConfidence.Intermediate :
                                str.DrawingAttributes.Color = Color.Orange;
                                break;
                            case RecognitionConfidence.Poor :
                                str.DrawingAttributes.Color = Color.Red;
                                break;
                        }

                        if (gesturesRecognized == 1)
                        {
                            // Emphasize first recognizer result
                            str.DrawingAttributes.Width = str.DrawingAttributes.Width * 2;
                            str.DrawingAttributes.Height = str.DrawingAttributes.Height * 2;
                        }
                        // Draw stroke on panel
                        ic.Ink.Strokes.Add(str);
                    }
                }

            }
        }
    }
     

    All the fun stuff happens in the ic_Gesture method. In the parameters it receives an InkCollectorGestureEventArgs object, full of interesting information such as the strokes drawn and the gestures recognized. The strokes drawn have a bounding box. This is the rectangle which encloses them. Out of the 4 corner points I calculate the points half way the rectangle's sides. The events arguments also contain a list of gestures. This list is comparable with the list of words when recognizing handwriting, this is a list of the calculated guesses of the gesture. My code loops through these and checks for the id of the gesture.

    When the strokes have been analyzed by the recognizer they are discarded. The code will create a new stroke to draw a shape which corresponds to the gesture. You create a stroke out of an array of points. You get the coordinates of a stroke by using the Stroke.GetPoint method. The actual value of these coordinates is not in pixels but in HiMeteric format. The accuracy of a tablet digitizer is far more precise than the pixels of the screen, by using the HiMetric format this information is preserved.

    The simplest gestures are a simple line up, down, left or right. Drawing a line requires two points. The starting point is copied from the first point of the stroke drawn. As end point the stroke's bounding box provides the coordinates. The result is a stroke which will draw a perfectly straight horizontal or vertical line. Create a stroke from the array of (these two) points using the Ink.CreateStroke method. The stroke will be drawn by adding it to the inkcollector's Strokes collection. Before doing that I'll do some decoration by setting properties of the stroke's DrawingAttributes property. Each gesture has a recognition Confidence, I use this to set the color. The first gesture recognized will be drawn with a thicker line by setting Height and Width.

    A somewhat more complex gesture is a square. There are several ways to draw this gesture: in one stroke making a lot of turns or in two strokes, each with just one turn. There is a small lag between the last stroke drawn and the gesture recognizer firing. This lag makes it possible to have a gesture which consists of multiple strokes. To build a square from one stroke you need 5 points. The top left corner will be the first and the last point to get a (visual) closed structure. Actually it is one open stroke whose begin- and end-point overlap.

    When it comes to gestures pointing up the gesture recognizer is going to have a hard time. In the demo I have subscribed to the arrow-up, the chevron-up (this looks like the letter v upside down) and the semicircle-left gesture. Despite its name the latter is best recognized by drawing the upper half of a circle. When these gestures are recognized the strokes are constructed from the points calculated. A semicircle is a rounded shape. When you set the FitToCurve property of the stroke's DrawingAttributes a Bezier curve fitting the strokes point's will be drawn. Drawing these kinds of gestures you will see that the gesture recognizer will propose several alternatives, leading to several shapes been drawn. The color of the shapes tell the confidence the recognizer has. Even if it's pretty sure it will return alternatives. Just like text recognition.

    There are loads of things you can do with gestures. As a small example I have subscribed to the ScratchOut gesture. It will erase the last stroke drawn by our code. Strokes entered by the user are discarded when the recognizer has finished. Before that they are still in the Strokes collection of the InkOverlay. To find the last stroke drawn I have to count the user's strokes to get the right index in the strokes collection.

    Now I have a very simple sketcher. To expand it's possibilities just subscribe to the other gestures. If you want to subscribe to SystemGestures you have to add an eventhandler to the InkCollector's SystemGesture event. Another method, same idea. A special note deserves the Circle gesture. When it comes to drawing a circle things are going to get hard as there is no simple way to draw a circle using Bezier curves. This is something to address with a custom renderer. Something for a new post.

    Scribble away !

  • Recognizing handwriting on a Tablet PC: beyond Strokes.ToString()

    Having spent 3 solid days on doing a crash-course VS 2005 training it's time for a little diversion. Finally I made the time for another post on programming the Tablet PC.

    The tablet PC is very good in recognizing handwriting, it will even make sense out of the worst scribblings you can imagine, for instance my own handwriting.

    The image shows the Tablet Input Panel (TIP) which is part of the tablet OS. It shows the textual representation of the ink, clicking a word shows a list of alternative results from the recognizer. In this post I will demonstrate how to do that in your own code.

    I have a Winform with on it: a panel to scrible, a button to clear the panel, a button to recognize and a listbox to display the results of the recognition. Here's the code :

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.Ink;

    namespace TabletPCdemo
    {
       public class InkPad : System.Windows.Forms.Form
       {
          private System.Windows.Forms.Panel panel1;
          private System.Windows.Forms.ListBox listBox1;

          /// Required designer variable.

          private System.ComponentModel.Container components = null;
          private System.Windows.Forms.Button buttonRecognize;
          private System.Windows.Forms.Button buttonClear;

          [STAThread]
          static void Main()
          {
             Application.Run(new InkPad());
          }

          private InkOverlay ic;

          public InkPad()
          {
             InitializeComponent();
             ic = new InkOverlay(panel1);
             ic.Enabled = true;
          }

          protected override void Dispose( bool disposing )
          {
             if( disposing )
             {
                if(components != null)
                {
                   components.Dispose();
                   if (ic != null)
                      ic.Dispose();
                }
             }
          base.Dispose( disposing );
          }

          private void buttonClear_Click(object sender, System.EventArgs e)
          {
             // Wait for pen input to complete
             while (ic.CollectingInk);
             ic.Ink.DeleteStrokes();
             panel1.Invalidate();
          }

          private void buttonRecognize_Click(object sender, System.EventArgs e)
          {
             // Wait for pen input to complete
             while (ic.CollectingInk);
             // Any strokes drawn ?
             if (ic.Ink.Strokes.Count == 0)
             {
                MessageBox.Show("No ink written");
                return;
             }

             // Is this a tablet PC ?
             Recognizers myLanguages = new Recognizers();
             if (myLanguages.Count == 0)
            {
               MessageBox.Show("No recognizers isntalled !");
               return;
             }

             // Get the recognizer for en-us
             Recognizer myLanguage = myLanguages.GetDefaultRecognizer(0x0409);
             RecognizerContext myContext = myLanguage.CreateRecognizerContext();

             // Prefered results
             WordList myWords = new WordList();
             myWords.Add("Gekko");
             myContext.WordList = myWords;

             myContext.Strokes = ic.Ink.Strokes;

             RecognitionStatus myStatus;

             RecognitionResult myResult = myContext.Recognize(out myStatus);

             if (myStatus == RecognitionStatus.NoError)
             {
                RecognitionAlternates myAlternates = myResult.GetAlternatesFromSelection();
                listBox1.Items.Clear();
                foreach (RecognitionAlternate ra in myAlternates)
                   listBox1.Items.Add(string.Format("Result : {0}, Confidence: {1}", ra.ToString(), ra.Confidence.ToString()));
             }

             myContext.Dispose();

       }

    }

    It’s using the Microsoft.Ink namespace which is in the  Microsoft.Ink.dll

    In the constructor of the form a new InkOverlay object is created. This class has a large list of overloaded constructors. One of them takes a windows handle and another one accepts a windows control. It is important which constructor you are going to use as that will influence the level of code access security required to run the code. When you want to scrible on an ActiveX control there is only a windows handle available. When you want to scrible on a panel you should pass the control itself to the constructor. Your code will work just as well when you pass the panel’s handle but the rise in the cas will be enough to prevent your tablet code running in (the default security settings of) IE.

    The InkOverlay object is not a managed object so you have to clean up when finished with it. The Dispose method of the form invokes the Dispose  method of the inkoverlay. Now the inkoverlay is ready for use, having set it’s Enabled property you can scribble on the panel.

    The InkOverlay object has an Ink property which holds the strokes drawn by the pen. Clearing the panel is a matter of deleting the strokes, calling DeleteStrokes will do just that. Checking the CollectingInk property in a loop the code first waits untill all ink input is processed. Usually this is instantanious but sometimes you will see that there is a lag between the movement of your pen and the ink actually drawn. The loop will make sure the ink is ready. Having deleted the strokes you have to invalidate the panel so it will be redrawn. As an empty panel.

    When it comes to recognizing handwriting most tablet PC code examples show the oneliner:

    ic.Ink.Strokes.ToString();

    The Strokes class has overloaded the ToString method to return the most probable recognition result. The code given here will return all results, like the TIP.

    Before recognizing it performs two checks, to prevent exceptions. First of all there have to be some strokes to recognize. Makes sense, but you’ll get an exception trying to recognize an empty strokes collection. Next the code checks if there are any recognizers installed. You can install the ink assemblies on a non Tablet PC. Your app will work fine, using the mouse you can even scribble. But the recognizers are only installed on a real tablet. There are several recognizers available, for English, German, French, Chinese, a couple more and a couple more announced. The code has to pick the recognizer for a specific language using the GetDefaultRecognizer method. The parameterless overload checks for the language of the tablet the app is running on. But it does this in a (imho) buggy manner. Experimenting shows it checks for the regional settings and not the language settings. I’m running the English version of the Windows Tablet PC with my regional settings set to Dutch. The result is that GetDefaultRecognizer starts looking for a Dutch recognizer. Which is, alas, not (yet) available. To select the recognizer to use I pass in an LCID (locale ID) constant. This is a point where the COM base of the tablet API really shines through.

    To use the recognizer you need its context, which is created by the CreateRecognizerContext method. I want to steer the recognizer’s result and do so by adding a list of favored words to the context. Create a new WordList object and add your favorites; for the sake of demo I’ve only added “gekko” (the Dutch spelling of gecko) to mine. The strokes to be recognized are added to the context and a RecognitionResult object is created. Now all is set up and the Recognize method will perform the actual recognition, returning the result in the recognition object.

    Now I can read all recognition results, in order of probability, from the result using the GetAlternatesFromSelection method. Besides the text recognized also the Confidence the recognizer has can be read from the RecognitionAlternates. Don’t forget to dispose the context, it’s also an unmanaged resource.

    You can see that even if the recognizer got my bad writing right it does not have that much confidence. But my Gekko is favoured.

    Far better when I really do my best.

  • So what about that Tablet PC ?

    I’m a big fan of the tablet PC and have a category tablet PC on my blog. But havn’t blogged that much on the Tablet recently. I’ve been writing a lot of ASP.NET production code and didn’t have the time to care of my pet. Time for a little catchup.

    On the hardware front things are moving in a steady pace towards main stream adaption. Many brands have tablet models, for instance Toshiba now has a tablet Tecra and even IBM is said to work on one. The main problem was always the extra price but the difference is getting less and less. So your next notebook might as well have tablet capabilities. But you should see a tablet PC as more than just a notebook with added pen capabilities. Bill Gates’s pet, demonstrated at the WinHec keynote, is the Haiku. Which is smaller than a notebook and larger than a PDA. The main diffence between a PDA and a tablet are (at the moment) the screen and the OS. The PDA has a touch screen and the tablet a magnetic digitizer built into the screen. The PDA runs on Pocket PC and the tablet XP tablet PC edition (a superset of XP pro). These intermediate devices are no vaporware, at the moment you can install XP tablet edition on a Sony U750. That machine measures 17 by 11 cm (6.5” x 4.5”), does not meet all specs to be an official tablet, but it worked to full content of the owner.

    So the hardware is making good progress, but what about the software ? Windows XP tablet PC edition is cool and very usefull. MS has realeased a tablet experience pack with some cool add-ons. It includes a number of tools which had the status of Power tool and now are making thier way into the standard feature set of a tablet. My favourites are:

    • A slightly souped up version of the award winning ArtRage app, now dubbed InkArt. This is the app to show when you demonstrate a tablet. Oohs and ahhs from everybody.
    • The energy blue theme realy improves the readability of your screen. The digitizer in a tablet screen significantly reduces that, the theme compensates pretty well.
    • Ink desktop. As you might recall you can scribble on anything which has a windows handle, the Ink desktop lets you scribble right upon the desktop.

    A full review of the pack is on the windows supersite.

    And what’s there for the developers ? The easiets way to add inking to your apps is using the Infinotes suite. Very nice to include inkable notes to your applications, it’s MS journal on the toolbar of VS. But you cannot do things with the pen in combination with existing stuff in your apps. For that you need to explore the Microsoft.Ink namespace. This is a beautifull API, the basics are well described in the only real book on tablet programming. But it’s not the full story. A further step exploring the possibilities should have been the tablet game SDK, presented in the Arcs of Fire game. The beta was launched on the Windows Anywhere conference but since than their website seems to be in state of shellshock. The blog has been dead for months. There is really good stuff in there but you need to be familiar with the API basis to understand what they are trying to do.

    The future for the tablet lies in Longhorn. It’s not yet completely clear whether there will a separate tablet version of Longhorn or not. What is promised is that Ink Data will be a data type which every Longhorn installation can work with. Ink data is more than just the picture scribbeld; it does contain a lot of information how that picture was drawn: which pen strokes were drawn in what order, how do the strokes intersect, what is the local stroke thickness, etc. Under XP you can exchange ink data as ink or as a fortified GIF (and in xml). A fortified GIF is an image of the result and does also have all ink data in the image header. You can install the Microsoft.ink api on a non tablet PC after which you can read and manipulate the ink data on a non-tablet. You can even input ink on a non tablet using the mouse. Trying to do that is the best demonstration why a pen is such a lovely input device. The only thing which you cannot install on a non tablet is handwriting recognition. At the moment the tablet specific software part is quite modular. Fits Longhorn.

    The current Microsoft.Ink is non managed code. Internally it’s a load of COM (and can be used form VB6), for VS there’s a nice managed wrapper. I guess they are working on a native managed version for Longhorn ? Recently there has also been quit some talk on Longorn and a touch screen. At first sight using a pen or just your fingertips is pretty similar. For the hardware there is a big difference. You apply preasure on the screen with anything, for instance the nice goodie pen I got at the MS Windows Anywhere conference. Tablet PC’s use digitizers which respond to changes in the magnetic field caused by a special pen. In some of my previous posts I explored this world and found out that these pens are usually not interchangable. Using a magnetic pen you rest the palm of you hand on the tablet’s screen when writing. No problem. But a touchscreen will detect the palm of your hand and interpret it as a giant click. So there are some problems to bring these two worlds together.

    MS research is also working on pen and fingered input devices. There’s Xnav, a device you operate with just your thumb. In case you’re interested the technology can be licensed. MS says they just don’t have the time to work on this as well. Others research stiching, how to use pen gestures which span multiple displays.

    The tablet hardware is becoming mainstream, tablet software has the potential to change the mainstream. These days a computer is considered incomplete without a mouse. A pen does what a mouse does, far more accurate and has far more possibilities. Trying to look in the crystal ball I wouldn’t be surprised if the pen will take over. For the moment I just can’t wait to find some time to dive deeper into the pen-gestures API.

    Keep scribbling !

More Posts Next page »