Introduction & Background

This page tries to highlight the differences between the two current versions of the .NET multi touch APIs: Surface SDK (v1.0) and Surface Toolkit for Windows Touch (v1.5).

Microsoft released the Surface product back in 2007 and along with it, the Surface SDK to allow development on it. When Windows 7 was released, with it's built in support for multi touch hardware, they also added multi touch support in the .NET platform (in release 4.0). Surface is only supported to run on .NET 3.5 but Microsoft has ported parts of the API to .NET 4 in the Surface Toolkit giving .NET 4/Windows7 developers access to some of the surface multi touch controls.

Controls in the surface version of the SDK and their Win7 counterparts:

(this list assumes you use Blake.NUI's SurfaceTouchDevice to re-route contact events to Win7 touch events)
  • SurfaceElementMenu - closest match in standard .NET is the context menu, but it's not touch optimal.
  • SurfaceUserControl - Use normal UserControl
  • SurfaceContentControl - Use normal ContentControl
  • TagVisualizers - No match in the Win7 API
  • SurfaceTextBox - Use normal text box, but this requires you to manually open the virtual keyboard on the surface device (using the static methods in the Microsoft.Surface.Core.SurfaceKeyboard class)
  • SurfaceShell and its related functionality (notifications, app orientation etc.) - no match in the Win7 APIs. As these are hardware specific, just put this code in the surface specific project and not in the common assembly.

Drag and Drop

  • BeginDragDrop returns SurfaceDragCursor instead of a bool. It will return null if drag drop failed, so it's still possible to emulate the old behavior. If you want the same code to support both API's at the same time, the following code can be used:
// We have to resort to reflection, since the JIT/runtime will complain (at runtime) about missing method if we just call it. 
var m = typeof(SurfaceDragDrop).GetMethod("BeginDragDrop");
object ret = m.Invoke(null, new object[] { ... /* insert all arguments to BeginDragDrop here, in order */ });
bool startDragOk;
if (ret == null)
    // Surface 1.5 API: null return means failed to start
    startDragOk = false;
    if (ret.GetType() == typeof(bool))
        // Surface 1.0 API: return type is boolean indicating success status
        startDragOk = (bool)ret;
        // Surface 1.5 API: return object is a Cursor
        startDragOk = true; // 'ret' was not null, so it was started ok
  • BeginDragDrop on the 1.0 API only accept Cursor or MouseDevice in the list of devices (see issue 11845)
The following code can be used to handle this difference without the need of compile time conditionals
private static InputDevice GetRealTouchDevice(InputDevice device)
    PropertyInfo info = device.GetType().GetProperty("Contact");
    if (info != null)
        return (InputDevice)info.GetGetMethod().Invoke(device, null);
        return device;

and then to use it
List<InputDevice> devices = new List<InputDevice>();

  • SurfaceDragCursor has different method signatures for the GetOrientation (old, new) and GetPosition (old,new) making it fail at runtime. The difference is that the new API expects an IInputElement while the old API wants a UIElement. In practice, there's no difference since typically the argument you specify is both an UIElement as well as a IInputElement, but the runtime is very picky about knowing the exact signature (and it should be!). The result is an exception during runtime. Fortunately, the solution is simple. The new dynamic functionality can rescue us here since it defers resolving the method signature until runtime:
dynamic cursor = e.Cursor;
Point pos =cursor.GetPosition(myControl);
double orientation = cursor.GetOrientation(myControl);

Other Differences

  • ContactHoldGesture and ContactTapGesture - no equivalent in the current Win7 .NET APIs. In Blake.NUI there is a gesture mechanism for both tap, double tab and hold events. See Gestures for more information
  • Manipulation and Inertia - The win7 controls have built in support for this - no need to create your own processors. Also, the new .NET 4 processors handle changes in two dimensions (x & y) allowing better natural response to user input.

Last edited Oct 7, 2010 at 10:27 AM by isaks, version 12


No comments yet.