Welcome to MSDN Blogs Sign in | Join | Help

Ignite: Spatial BostonNo, Church Lady won’t be there, but a lot of folks interested in location-aware application development and analysis will be.

O’Reilly and sponsors The Open Planning Project (TOPP) and PlaceBlogger are holding an Ignite event with a special … er, spatial twist.  Speakers get five minutes with 20 slides - set to automatically transition after 15 seconds each - to chat on stage about some aspect of working with spatial data and applications. 

It’s kind of like the weather in New England, if you don’t like the topic, wait 5 minutes, and it will change.  Of course it’s also a great opportunity to network with like minded geeks in the very cool setting of Microsoft’s New England Research and Development Center.  Directions are left to the reader – after all, if you can’t figure out how to get here, is this particular event really up your alley? ;-)

The event is on December 2nd from 6:30 p.m. to 9:30 p.m. at NERD.  It’s free, but attendance is limited (only 16 ‘tickets’ are left as I’m writing this) – register at Eventbrite now!

SharePoint 2010 One of the highlights at PDC 09 was the availability of the SharePoint 2010 Beta.  Coming on the heels of that announcement is a great opportunity for the SharePoint community in the greater Boston area.

Microsoft is a Platinum Sponsor of the upcoming Gilbane Boston Conference at the Westin Copley in Boston on December 2nd and 3rd.  As part of this event, you can get a FREE Technology Showcase Pass, which includes access to the SharePoint 2010 Experience.

The SharePoint 2010 Experience provides a hands-on opportunity to walk though, learn, and understand the new content management capabilities of SharePoint 2010. If you stop by, you’ll have a chance to win a Microsoft Arc Mouse and up to $500 in American Express Gift Cards!

Register for the FREE Technology Showcase Pass.

Register for the full conference and workshops.

Northeast Roadshow As you know, Chris and I are in the middle of our Fall/Winter 2009 Northeast Roadshow, with four more stops scheduled for early December:

Now there’s even more incentive to attend!  In addition to the WIN7 code referenced in my previous blog post, we’re incorporating a “Bring a friend, get a book” promotion for the rest of our venues (our colleagues down the East coast are doing the same, by the way).  Here’s how to take advantage of the offer:

  1. Follow the registration link above for the desired venue

  2. For the referral code, enter the name of the friend you’re bringing along, OR if you’ve already registered, have your friend enter your name when she or he registers (see below).

     

    Referral Code 

  3. When you check-in at the event, we’ll hand each of you a copy of Laurence Moroney’s Introducing Microsoft Silverlight 3.

Obligatory Fine Print:

  • Government employees are not eligible for promotion
  • Both parties must be present to win
  • If onsite supply runs out, books will be mailed to recipients

One of the more popular exhibits on the Big Room floor at PDC 09 was the Azure IT PAC (Pre-assembled Container).  The IT PAC is the unit of deployment within Azure Data Centers, such as those in San Antonio and Chicago now, and those planning to open in 2010 in Dublin, Amsterdam, Singapore and Hong Kong.  The specific unit at PDC was an outdoor, Generation 4 model (as opposed to the older indoor units currently deployed in Chicago and San Antonio).

Check out the short video of the IT PAC I shot at PDC, after a quick tour from some of the Microsoft guys behind their deployment.

 

Get Microsoft Silverlight

 

Adjacent to the IT PAC at PDC was a short, professional-quality video playing that showed how the unit is put together from the ground up.  I’m told that video should appear shortly at Microsoft Showcase, joining the concept video available there now, so check back within the next week or so for that.

Lastly, Ina Fried has a great series of photos at the CNET site of the same container at PDC (clearly I need to upgrade from my Sony NSC-GC1!).  Also check out her recent coverage of the Chicago data center.

PDC

I got back from PDC yesterday and have managed to (mostly) make up for my sleep deficit.  Undoubtedly you’ve heard by now some of the major announcements at the conference (including the free multi-touch laptop that all the paying attendees received!):

Silverlight 4

Windows Azure availability

“Dallas”

Office 2010 Beta

If you haven’t already, be sure to listen to the two keynotes (Day 1 and Day 2) to see how far things have come since PDC 08 (as well as where we’re headed).  The sessions are also available on demand, so you can experience all of the content from the comfort of your own living room as well!

n_east_roadshow_120x120 Thanks to the folks in Burlington, Vermont, and Troy and Rochester, New York, for coming to the latest edition of the Northeast Roadshow last week.  Given the timing (PDC this week and the Thanksgiving holiday next week), Chris and I are on a short break before we resume the series on December 3rd.  There’s still room at all the remaining venues, AND we’ve got a special deal for you:

If you’re among the first seven at each venue to register with the code WIN7, we’ll hand you a copy of the MCTS Self-Paced Training Kit (Exam 70-536) Microsoft .NET Framework Application Development Foundation, Second edition at the event!

Given what I heard just today -- and PDC hasn’t officially started yet -- we’ll have a lot to talk about at the upcoming venues (I’m already contemplating a few updates to my presentations and demos!).  You can get the full agenda here, but the topics we’ll be discussing include

  • WCF
  • Model-View-ViewModel with Silverlight and Expression Blend
  • Avenues to get technical help on Microsoft technologies
  • LINQ fundamentals
  • ASP.NET Web Forms and Ajax

Register at the links below – looking forward to seeing you there!

Boston Business Intelligence User GroupI have yet another new user group to announce!  The Boston Business Intelligence User Group – starts meeting TOMORROW, Tuesday, November 17th, at 6:30 p.m. at the Microsoft Office on Jones Road in Waltham.  Thanks go out to Slava Kokaev, a familiar face in the local developer and BI community, for the initiative to establish and lead the group. 

Here’s the group’s charter, shamelessly lifted from the group’s website:

Welcome to BOSTON BUSINESS INTELLIGENCE User Group.
We have regular face-to-face with hands-on meetings including guest speakers. We located in the Greater Boston area. We meet first 3 Tuesday's of each month. This is a FREE study group for everyone interested in learning the latest Microsoft Business Intelligence Platform technology and tools and Languages as well as Client Side Data Analysis Applications.

To kick off the group, Brian Knight, SQL Server MVP and BI specialist, will present a remote Live Meeting session on an introduction to Business Intelligence.

NaviSite Microsoft and NaviSite are co-hosting a free event at the New England Research and Development (NERD) Center in Cambridge on December 9th, from 10 to 6.

php-med-trans During the day, you’ll get to hear about what’s new in the Microsoft Web Platform, including IIS, PHP on Windows,  the Web Platform Installer, and development and design tools like Visual Studio and Expression Studio.  NaviSite will also discuss their various hosting options and their involvement with the WebsiteSpark program.

You can register for the event at http://microsoftandnavisite.eventbrite.com/.  All attendees will be entered into a drawing to win one of the following:

  • Copy of Windows 7
  • XBox 360 Elite
  • Zune HD
  • 8GB Zune
  • FREE NaviSite Managed Hosting for 60 days

PDC I’m waiting for my last load in the dryer, so I can finish packing for my first PDC, in Los Angeles beginning tomorrow.  If you’re going to be there as well, hopefully we’ll catch each other among the other thousands of folks that will be there taking part in the workshops, 160+ technical sessions, Birds of a Feather discussions, hands-on labs, and other special events.

If you’re not going to LA though, you can still be part of the buzz and excitement happening there. 

  • Watch the two keynotes via Silverlight smooth-streaming from the comfort of your own office (or get a group of folks together over lunch).  Both keynotes begin at 11:30 Eastern time.

Day 1, November 17th, Ray Ozzie and Bob Muglia

Day 2, November 18th, Scott Guthrie, Kurt DelBene, and ???

  • Channel 9 will be broadcasting live (and unscripted) from the PDC Big Room each of the three days (beginning around 1:30 EST).  They’ll be interviewing presenters and attendees alike, and you can help drive the conversation by submitting your tweets to @ch9live.
  • Check out the Not@PDC site.  There’s nothing there at the moment I’m writing this post, but last year quite a few presentations were made available BY non-attendees FOR non-attendees.  You can follow their twitter feed as well via the hashtag #notatpdc
Visual Studio 2010 .NET Framework 4


You’re probably aware that the Beta 2 release of Visual Studio 2010 and .NET 4.0 became available a couple of weeks ago.  Did you know there’s a “Go Live” license?  … you can build and deploy your application even before Visual Studio 2010 is released next March. 

That’s even more reason to not delay and get a head start diving into the new features and technologies.  Our friends at DevelopMentor are hosting a free series of .NET 4.0 Webcasts in the coming weeks, including the following:

  • Introducing MVC
    Presenter: Brock Allen
    Thursday November 12th, 12 noon- Register Here

  • Building Modern Websites in ASP.NET Webforms
    Presenter: Michael Kennedy
    Monday November 23rd, 12 noon - Register Here

  • Meet The New Workflow: WF4
    Presenter: Maurice De Beijer
    Tuesday December 1st, 12 noon - Register Here


Don’t forget too the 10-4 series on Channel 9, with 35 episodes thus far presenting overviews of specific new features that are coming with the new release of Visual Studio.

It’s going to be a busy week in the capital area of New York next week, and a great time to get knee deep in all things technical!

Trojan Horse Tech Valley Code Camp – Saturday, Nov. 7th at SUNY Albany

There’s 20 sessions and over 100 signed up thus far!  I hope to see you there as I deliver my “7 on 7” spiel.

Tech Valley User Group – Tuesday, Nov. 10th at VersaTrans in Latham

For the group’s monthly meeting, Rob Fisch, Director of Global Technology at Kaz, Inc, is speaking on Getting Started with Reporting Services.

Northeast Roadshow – Thursday, Nov. 12th at RPI

Chris and I are bringing you the “Don’t Fear the Coder” tour with topics including Silverlight and MVVM, ASP.NET, LINQ, and WCF.  (We’re taking the show to six other venues as well!)

With all the talk about Windows Azure and hosting your application in the “cloud”, it’s easy to forget that somewhere there’s a computer, or perhaps thousands, that are actually running your application.

There’s a fascinating write-up and photo series on CNET about the new Microsoft data center in Chicago.  Here are some of the cool facts I lifted from the article (with some help from Wolfram Alpha) followed by a video interview featuring Daniel Costello and Christian Belady of Microsoft.

 

Thanks to my New York Metro colleague, Peter Laudati, for pulling all of these events together in one place.  While Chris and I are rather partial to the Northeast Roadshow :), we realize a number of you prefer the warmer climes this time of year, and so we wanted you to be aware of all great work being done up and down the East coast. 

Across the board, this is a pretty amazing opportunity for deep technical content -and, of course, unique brands of humor courtesy of your local developer evangelist(a)s.  For the price of FREE, it’s definitely a few of your hours of your day well spent.

Note, PDC is happening in the middle of our series (say hi to Chris and me if you’re coming to LA), so we are primed for last minute updates at our December talks as well!

Psst… register with the code WIN7 and you may receive one of seven free copies of the MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework Application Development Foundation.


n_east_roadshow_120x120

MSDN Northeast Roadshow: ”Don’t Fear the Coder”
Piloted by Chris Bowen & Jim O’Neil

Cities & Dates:

metro_roadshow_120x120

MSDN Metro Roadshow
Piloted by Peter Laudati & Asli Bilgin

Cities & Dates:

  • 11/12/2009 – Parsippany, NJ
  • 12/10/2009 – East Windsor, NJ
  • 12/15/2009 – New York, NY
mid_atl_roadshow_120x120

MSDN Mid-Atlantic Roadshow
Piloted by G. Andrew Duthie, Dani Diaz, and
     Dave Isbitski

Cities & Dates:

  • 11/12/2009 – Pittsburgh, Pa
  • 12/1/2009 – Harrisburg, Pa
  • 12/3/2009 – Reston, Va
  • 12/8/2009 – Roanoke, Va
  • 12/10/2009 – Malvern, Pa
s_fried_roadshow_120x120

MSDN Southern Fried Roadshow
Piloted by Brian Hitney & Glen Gordon

Cities & Dates:

  • 11/4/2009 – Greensboro, NC
  • 11/5/2009 – Raleigh, NC
  • 11/6/2009 – Columbia, SC
  • 12/8/2009 – Atlanta, GA
  • 12/9/2009 – Montgomery, AL
tiki_roadshow_120x120

MSDN Tiki Hut Roadshow
Piloted by Joe Healy & Russ Fustino

Cities & Dates:

  • 11/30/2009 – Tampa, FL
  • 12/2/2009 – Fort Lauderdale, FL
  • 12/14/2009 – Orlando, FL


 

 

Here’s a one-stop shopping spot for the 7 on 7 blog series from the past week (each image leads to a post on a specific technology).  Hopefully, the series has given you great ideas on how to start leveraging the new Windows 7 features in your own applications.  And if you’re doing something especially cool with Windows 7, drop me a line; I’d love to hear about it.

7 on 7 Intro Post

7 on 7 Code Camp Presentation Links

XP Mode Taskbar Federated Search Extended Linguistic Services Direct2D and DirectWrite Sensor and Location API Multitouch

Windows 7Windows Multitouch, in my opinion, is the most emotive new feature of Windows 7.  From the kids at home to the audiences to whom I’m demoed Windows 7, there’s something fresh and fun about being able to manipulate an application with simple hand gestures. 

We’ve all used touch screens in some form before, whether it be a tablet PC, your ATM, or a mall kiosk, but generally you’re just substituting your finger for a mouse.  Multitouch is different; it mimics the way we work with physical objects and as such opens up a new world of user interaction scenarios.

When characterizing existing or new applications running on a multitouch device, three categories of the user experience emerge: good, better, and best.  As we examine those categories in this post, you should get a good idea of the technical aspects that enable these experiences as well.

 

The Good Experience

Legacy applications will automatically provide a touch experience on touch devices, even though those applications were not designed for the Windows 7 touch capabilities.  Basic interactions like panning with one or two fingers, resizing using a pinch gesture, and right clicking with a tap-and-press gesture are automatically translated by Windows 7 into analogous mouse messages, such as WM_VSCROLL and WM_HSCROLL.  As a result, applications like Microsoft Word 2007 will ‘do the right thing’:  when you pan the document, it scrolls; when you use the resize gesture, it changes the zoom factor as if you’d used the slider at the bottom right or the ribbon’s Zoom option.

You may want to check out the MSDN article Legacy Support for Panning with Scroll Bars for additional guidance to ensure your legacy application works well with the ‘out-of-the box’ touch capabilities.  Troubleshooting Applications also has good tips for diagnosing unexpected behaviors in touch-enabled applications; for example, disabling flicks is generally recommended.

 

The Better Experience

Windows 7 introduces three new notifications and messages to support touch-enabled applications; two of these notifications (WM_GESTURENOTIFY and WM_GESTURE) form the basis of “the better experience” for multitouch.  To respond to these new messages, managed developers need to include code in WndProc since the the .NET Framework classes do not include explicit touch events. Additionally be sure to filter these message up the chain, via DefWindowProc (unmanaged) or a call to the WndProc of the base class in managed code.

WM_GESTURENOTIFY is your opportunity to indicate which of the built-in gestures that your application supports.  Respond to this message via a call to SetGestureConfig, passing in an array of GESTURECONFIG structures that detail which gestures your application will recognize.   There are five specific gestures:

 

Gesture ID Behavior Gesture Diagram
GID_ZOOM 3 zoom Zoom gesture
GID_PAN 4 pan / scroll Pan gesture
GID_ROTATE 5 rotate Rotate gesture
GID_TWOFINGERTAP 6   Two-finger tap gesture
GID_PRESSANDTAP 7 right click Press-and-tap gesture

 

The ID numbers in the chart above refer to the dwID field of the GESTUREINFO structure, which you would retrieve via the GetGestureInfo method as part of the message processing loop.  Two other ID values, GID_START (1) and GID_END (2), complete the list and enable detecting the beginning and end of a long-running gesture, like panning across a document.   The GESTUREINFO structure contains additional fields (ptsLocation and ullArguments) that store data pertinent to a specific gesture, like the center point of a rotation or the distance between two fingers.

Putting this all together, below is a bit of code from the MTGestures sample provided with the Windows 7 SDK.  The two cases for the WndProc function (lines 8 and 22) handle the two new notifications for gesture handling.  Here, the application subscribes to all of the gestures (line 13), and defers the gesture handling to the DecodeGesture method (line 23).  Each gesture has its own case within the switch statement (lines 46, 49, 52, 80, 102, 127, and 132) where gesture-specific code accesses the additional information in ptsLocation and ullArguments to carry out the processing.

 

   1:  protected override void WndProc(ref Message m)
   2:  {
   3:      bool handled;
   4:      handled = false;
   5:   
   6:      switch (m.Msg)
   7:      {
   8:          case WM_GESTURENOTIFY:
   9:              {
  10:   
  11:                  GESTURECONFIG gc = new GESTURECONFIG();
  12:                  gc.dwID = 0;    
  13:                  gc.dwWant = GC_ALLGESTURES; 
  14:                  gc.dwBlock = 0;
  15:   
  16:                  bool bResult = SetGestureConfig( Handle,  0,   1, 
  17:                       ref gc,  _gestureConfigSize);
  18:              }
  19:              handled = true;
  20:              break;
  21:   
  22:          case WM_GESTURE:
  23:              handled = DecodeGesture(ref m);
  24:              break;
  25:   
  26:          default:
  27:              handled = false;
  28:              break;
  29:      }
  30:      base.WndProc(ref m);
  31:   
  32:      if (handled)
  33:            m.Result = new System.IntPtr(1);
  34:  }
  35:   
  36:   
  37:  private bool DecodeGesture(ref Message m)
  38:  {
  39:      GESTUREINFO gi;
  40:      gi = new GESTUREINFO();
  41:      gi.cbSize = _gestureInfoSize;
  42:      GetGestureInfo(m.LParam,ref gi)
  43:   
  44:      switch (gi.dwID)
  45:      {
  46:          case GID_BEGIN:
  47:              break;
  48:   
  49:          case GID_END:
  50:              break;
  51:   
  52:          case GID_ZOOM:
  53:              switch (gi.dwFlags)
  54:              {
  55:                  case GF_BEGIN:
  56:                      _iArguments = (int)(gi.ullArguments & 
ULL_ARGUMENTS_BIT_MASK);
  57:                      _ptFirst.X = gi.ptsLocation.x;
  58:                      _ptFirst.Y = gi.ptsLocation.y;
  59:                      _ptFirst = PointToClient(_ptFirst);
  60:                      break;
  61:   
  62:                  default:
  63:                      _ptSecond.X = gi.ptsLocation.x;
  64:                      _ptSecond.Y = gi.ptsLocation.y;
  65:                      _ptSecond = PointToClient(_ptSecond);
  66:                      Point ptZoomCenter = new Point(
                               (_ptFirst.X + _ptSecond.X) / 2,
  67:                          (_ptFirst.Y + _ptSecond.Y) / 2);
  68:                      double k =  (double)(gi.ullArguments & 
                               ULL_ARGUMENTS_BIT_MASK) / 
  69:                          (double)(_iArguments);
  70:   
  71:                     _dwo.Zoom(k, ptZoomCenter.X, ptZoomCenter.Y)
  72:                      Invalidate();
  73:   
  74:                      _ptFirst = _ptSecond;
  75:                      _iArguments = (int)(gi.ullArguments & 
                               ULL_ARGUMENTS_BIT_MASK);
  76:                      break;
  77:              }
  78:              break;
  79:   
  80:          case GID_PAN:
  81:              switch (gi.dwFlags)
  82:              {
  83:                  case GF_BEGIN:
  84:                      _ptFirst.X = gi.ptsLocation.x;
  85:                      _ptFirst.Y = gi.ptsLocation.y;
  86:                      _ptFirst = PointToClient(_ptFirst);
  87:                      break;
  88:   
  89:                  default:
  90:                       _ptSecond.X = gi.ptsLocation.x;
  91:                      _ptSecond.Y = gi.ptsLocation.y;
  92:                      _ptSecond = PointToClient(_ptSecond);
  93:   
  94:                      _dwo.Move(_ptSecond.X - _ptFirst.X, 
_ptSecond.Y - _ptFirst.Y);
  95:                      Invalidate();
  96:   
  97:                      _ptFirst = _ptSecond;
  98:                      break;
  99:              }
 100:              break;
 101:   
 102:          case GID_ROTATE:
 103:              switch (gi.dwFlags)
 104:              {
 105:                  case GF_BEGIN:
 106:                      _iArguments = 0;
 107:                      break;
 108:   
 109:                  default:
 110:                      _ptFirst.X = gi.ptsLocation.x;
 111:                      _ptFirst.Y = gi.ptsLocation.y;
 112:                      _ptFirst = PointToClient(_ptFirst);
 113:   
 114:                      _dwo.Rotate(
 115:                          ArgToRadians(gi.ullArguments & 
                                            ULL_ARGUMENTS_BIT_MASK)
 116:                          - ArgToRadians(_iArguments),
 117:                          _ptFirst.X, _ptFirst.Y
 118:                      );
 119:   
 120:                      Invalidate();
 121:   
 122:                      _iArguments = (int)(gi.ullArguments & 
ULL_ARGUMENTS_BIT_MASK);
 123:                      break;
 124:              }
 125:              break;
 126:   
 127:          case GID_TWOFINGERTAP:
 128:              _dwo.ToggleDrawDiagonals();
 129:              Invalidate();
 130:              break;
 131:   
 132:          case GID_PRESSANDTAP:
 133:              if (gi.dwFlags == GF_BEGIN)
 134:              {
 135:                  _dwo.ShiftColor();
 136:                  Invalidate();
 137:              }
 138:              break;
 139:      }
 140:   
 141:      return true;
 142:  }

 

The Best Experience

Gestures (“the better experience”) are limited in that they cannot be combined, so while you can rotate or zoom, you can’t rotate and zoom.  Additionally, you can’t manipulate more than one object at a time, like say drag two pictures on a photo album application.  To ratchet up the experience another level, applications need to opt into handling the raw touch messages, namely WM_TOUCH, by registering each window subject to touch treatment via the RegisterTouchWindow method.

As with the WM_GESTURE message, WM_TOUCH messages should be intercepted in the WndProc and the GetTouchInputInfo method used to return information about the current touch event.  That information is returned within an array of TOUCHINPUT structures, in much the same way as the GESTUREINFO structure was leveraged above, but this time returning information about multiple touch points.

Below is some code from the MTScratchPadWMTouch example from the Windows 7 SDK.  Similar the above code sample, DecodeTouch is used to extract information from the WM_TOUCH message and carry out appropriate actions.  In lines 15 though 20, the dwFlags information for each touch point is consulted and an associated event handler assigned: Touchdown if the touch message indicates a touch was initiated; Touchup if a finger was removed from the screen; and TouchMove if a finger was moved.  Once the action is complete (handlers are executed in line 39), the touch handle, which comes from the LPARAM of the WM_TOUCH message, must be closed (line 44).
 

   1:  private bool DecodeTouch(ref Message m)
   2:  {
   3:      int inputCount = LoWord(m.WParam.ToInt32()); // # of inputs
   4:      TOUCHINPUT[] inputs;
   5:      inputs = new TOUCHINPUT[inputCount];
   6:   
   7:      GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize);
   8:   
   9:      bool handled = false;
  10:      for (int i = 0; i < inputCount; i++)
  11:      {
  12:          TOUCHINPUT ti = inputs[i];
  13:   
  14:           EventHandler<WMTouchEventArgs> handler = null;  
  15:          if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0)
  16:              handler = Touchdown;
  17:          else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0)
  18:              handler = Touchup;
  19:          else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0)
  20:              handler = TouchMove;
  21:   
  22:          if (handler != null)
  23:          {
  24:              WMTouchEventArgs te = new WMTouchEventArgs();
  25:   
  26:              te.ContactY = ti.cyContact/100;
  27:              te.ContactX = ti.cxContact/100;
  28:              te.Id = ti.dwID;
  29:              {
  30:                  Point pt = PointToClient(
                                          new Point(ti.x/100, ti.y/100));
  31:                  te.LocationX = pt.X;
  32:                  te.LocationY = pt.Y;
  33:              }
  34:              te.Time = ti.dwTime;
  35:              te.Mask = ti.dwMask;
  36:              te.Flags = ti.dwFlags;
  37:   
  38:   
  39:              handler(this, te);
  40:              handled = true;
  41:          }
  42:      }
  43:   
  44:      CloseTouchInputHandle(m.LParam);
  45:      return handled;
  46:  }

 

This example is a simple paint application, so the events track individual strokes on a canvas.  Touchdown, for instance, initiates a stroke and assigns it a color.  Touchup removes the stroke for a collection of active strokes, and TouchMove draws the stroke corresponding to the given touch point on the canvas.   Below is the code for the TouchMove handler:

 

   1:  private void OnTouchMoveHandler(object sender, 
   2:        WMTouchEventArgs e)
   3:  {
   4:      // Find the stroke in the collection of the strokes in drawing.
   5:      Stroke stroke = ActiveStrokes.Get(e.Id);
   6:      Debug.Assert(stroke != null);
   7:   
   8:      // Add contact point to the stroke
   9:      stroke.Add(new Point(e.LocationX, e.LocationY));
  10:   
  11:      // Partial redraw: only the last line segment
  12:      Graphics g = this.CreateGraphics();
  13:      stroke.DrawLast(g);
  14:  }

 

Manipulations and Inertia

While WM_TOUCH provides all the low level details, the jump from translating individual touch messages to end-user interactions like rotating and resizing may seem a bit overwhelming.  That’s where the manipulation and inertia processors come in.

The manipulation processor (IManipulationProcessor and _IManipulationEvents) takes as input the raw WM_TOUCH messages and converts them into 2-d affine transformations, combining scale, rotation, and translation, essentially providing a superset of the more basic gesture support.  IManipulationProcessor exposes a number of methods depending on the source gesture.  For instance, you’d call ProcessMoveWithTime to feed the manipulation processor information on the movement of a finger on the screen as reported by one of the WM_TOUCH messages. 

As you’re feeding raw touch information into the processor, it’s firing events defined on the _IManipulationEvents interface, namely ManipulationStarted, ManipulationDelta, and ManipulationCompleted.  The ManipulationDelta event gives you access to the affine transformation, so you can carry out whatever update is required to the object being manipulated.

Most high-end touch applications will also want to take advantage of inertia mechanics.  As users interact with objects on the screen in a tactile fashion, they expect objects to behave with similar physics to the real world.  Flick a photo across the screen, and you expect it to move fast at the start and then slow down, and you may expect it to bounce gently off the edge of the screen if it reaches the perimeter of the display.   That’s where the inertia processor (IInertiaProcessor) comes in.

Similar to the manipulation processor (with which is shares the _IManipulationEvents interface), you instantiate a reference to the processor and invoke the Process or ProcessTime method to carry out the physics calculations and raise the ManipulationDelta or perhaps ManipulationCompleted event, just as the manipulation processor does.

 

WPF 4 and the Evolution of Multitouch

The touch capabilities in Windows 7 are obviously implemented at the core operating system level, namely via COM objects.  Managed code developers tend to want to operate at a higher level of abstraction, and currently, if you’re using WPF, you would likely do so by integrating with the Real-Time Stylus interface.  For example, the MTScratchpad I described above has an alternative implementation in the SDK as well, one using stylus events and other functionality enabled by the IRealTimeStylus3 and ITablet3 interfaces.

You may also be familiar with Microsoft Surface, the multi-touch, multi-user tabletop device that you’ve seen on Extra Entertainment, Boston's Channel 7, or perhaps in the Sheraton Boston lobby.  The Surface is based on Windows Vista and the .NET Framework 3.5, and its touch capability is provided via a Surface-specific SDK and controls.  On the traditional computing end, Windows 7 provides a native touch API, and WPF 3.5 can tap into it via either interop or the real-time stylus functionality. In pictures, it’s something like the following; the key point to take away is that a touch application for Surface will not run on Windows 7 and vice-versa… today, anyway.
 

Multitouch scenario today

 

With .NET 4 and the next iteration of Microsoft Surface, there will be considerable interoperability.  The architecture changes from the above to what you see below.  Most notably, both devices will be built on a core of Windows 7.  Additionally, WPF 4 has been enhanced to support touch events directly on the core UI classes, UIElement and UIElement3D, so implementation via interop or the stylus events will no longer be necessary.  Of course, Surface will still deliver additional functionality and controls relevant for that device’s use and form factor, but presuming you confine your application to core .NET 4 (and WPF 4) functionality, you should have nearly seamless interoperability.

 

Multitouch scenarios post .NET 4


If you’re considering building multitouch capabilities into your WPF applications, there’s no time like the present.  You can download the Beta 2 release of Visual Studio 2010 and .NET Framework 4 now (it was just released last week), and there is a go-live license!

 

More Hands-On (pun intended!) Information

Windows Touch (MSDN)

Troubleshooting Applications (MSDN)

Windows Touch: Developer Resources (CodeGallery)

MultiTouch Capabilities in Windows 7 (MSDN Magazine)

Windows Touch Pack for Windows 7

Where the Multitouch Devices Are (Channel 10 blog)

More Posts Next page »
 
Page view tracker