PDC ‘09: Three Screens and a Cloud, Pt. 1 - Azure

Microsoft's 2009 Edition of the Professional Developers Conference is officially over. The theme this year was "Three Screens and a Cloud," with the three screens being desktop, web, and mobile, coupled with the Azure cloud-computing platform. Here are some takeaways from this year's announcements. To make it a bit easier to digest, I’ll break this into two posts. This first will focus primarily on Azure (the “cloud” part of the vision), with the next focused on Silverlight 4 (one of the three screens in the vision). There were other technologies shown, but Azure and Silverlight dominated PDC this year.

Before I dive into all the Azure Goodness, let me revisit the rumor mill I posted here:

  • Internet Explorer 9. We got to see a preview of IE9. No download available yet, but the ACID 3 results were discussed (they’re not perfect, but test scores went from 20/100 with IE8 to 32/100 with IE9). new features were demo’d (such as the new font rendering engine and Javascript engine).
  • Silverlight 4 This rumor was spot-on, but the announcement didn’t come until Day 2. A developer preview is now available here. Silverlight 4 seriously ups the ante against AIR and Flex, and further reduces the need for a full WPF application, now that a Silverlight app can extend beyond the browser sandbox, access local resources (such as USB, webcams, and microphones), and supports printing.
  • Windows Mobile 7. Well, we heard about Windows Mobile 7 in the keynote, but nothing specific was announced – we’ll have to wait for MIX 2010. There was a subtlety in one of the keynote slides, showing Silverlight spanning all three “windows” – so, I suspect we’ll see a sneak peek of Silverlight 4 running on WinMo 7 at MIX, along with WinMo 7 hardware requirements.
  • Azure. As you’ll see below, Azure dominated the first day of PDC, with a bunch of announcements.

 

Ok, time for Azure…

About a year ago (at PDC ‘08), Microsoft introduced Azure, their cloud computing platform. Since then, the tools and SDKs have gone through numerous revisions (including several SDK updates, new or updated APIs, and the occasional removal of in-flux features such as workflow, logging, and Live Mesh integration). This week, Microsoft announced the commercial availability of Azure, slated to go live in January, with customer billing commencing in February.

PDC’s Day #1 keynote and sessions were dominated by Azure. It was an avalanche of announcements:

  • Go-live and first-month free. Azure will be live starting January 1 2010. For the month of January, all usage will be free, and customers will receive a bill showing their usage and cost breakdown, to help project actual costs. Billing goes into effect February 1.
  • Codename Sydney. Sydney, arriving in 2010, provides a simple way to securely connect Azure services to on-premise resources, such as databases. Prior to Sydney, the Service Bus was the primary enabler for on-premise access.
  • Codename Dallas. Dallas is Microsoft’s new information marketplace, or “data as a service.” Data can be published to the cloud, and subscribers can easily consume this data. This service won’t be commercially available until some time in 2010. For now, the published data sources are free. The API is REST-based. Microsoft’s Dallas portal is now online.
  • Microsoft PinPoint. PinPoint is a new online catalog of companies that are available to help build applications and services. PinPoint is integrated into both the Azure portal and the Microsoft Partner network.
  • AppFabric. AppFabric is essentially the new brand name for .NET Services and incorporates features previously seen in Codename Dublin  and Codename Velocity (essentially a caching engine). It encompasses access control and service bus configuration. A beta release, installable on Windows Server 2008, provides a complete management interface built into IIS, that provides configuration and monitoring for WCF, Workflow, caching, multi-tenant, access control, and service bus.
  • Multiple Virtual Machine Sizes. Customers will now be able to deploy instances of their application to differnt VM sizes:
VM Size CPU cores
(1.6GHz)
Memory (GB) Local storage (GB) Cost (per service hour)
Small

1

1.7

250

$0.12

Medium

2

3.5

500

$0.24

Large

4

7.0

1000

$0.48

ExtraLarge

8

14.0

2000

$0.96

  • Custom Virtual Machines and Remote Desktop.  In 2010, Microsoft will provide a choice of Virtual Machines to provision. Customers may then tailor these VMs via Remote Desktop (with full admin privileges!), save a snapshot, and use the customized VM for future provisioning.
  • Visual Studio 2010 Integration. VS10 will ship with integrated Azure tools. The SDK may be downloaded now, which works with both Visual Studio 2008 and Visual Studio 2010. We were given a glimpse of an unreleased Azure Application Model project which allows existing applications and services to be easily added to Web Roles and Worker Roles just by dragging the project files to Web Role and Worker Role containers on the Application Model design surface (this was an amazing demo, and should really simplify the migration of apps to the cloud).
  • Azure language support. Azure apps are now supported in a broad set of tools and languages: PHP, FastCGI, Java, and MySQL just to name a few.
  • Azure monitoring. Microsoft System Center will now run in Azure, and will monitor Azure applications (SLA, availability, etc.). We’ll see this in 2010. There’s also an Azure Diagnostics Management API included in the Azure SDK.
  • Storage replication. Azure data will now be geo-replicated across pairs of data centers, going live in January: Chicago/San Antonio, Dublin/Amsterdam, Singapore/Hong Kong. All data centers are based on a container design.
  • Azure Data. Azure data storage received numerous enhancements, including entity group transactions, snapshots, block blobs, page blobs, leases, shared access signatures, custom domain names, and content delivery network. A new site, OddlySpecific.com, is an example of a site running in Azure, based on Azure blob storage and SQL Azure.
  • Azure X-Drives. Probably the biggest announcement around Azure data: the ability to mount an X-drive storage blob as an NTFS volume.
  • SQL Azure. SQL Azure is the new name for Azure’s cloud-based relational database. There’s now support for T-SQL, ADO.NET, PHP, JDBC, Excel, for example. While still in CTP, a few customers are now officially live, including Automatic, the makers of WordPress. Their WordPress platform is now Azure-hosted.

I think that covers the bulk of Azure announcements.

PDC '09: What will we learn?

I'm camped out just outside West Hall A in the Los Angeles Convention Center. Behind me, there are already at least a hundred people lined up to get into the hall, which doesn't open for another hour. The rumor-mill is buzzing with speculation about what we'll see this week.

I'll post updates here as the keynotes today and tomorrow unfold. However, I do want to mention three four product announcement rumors that are gaining legs:
  • Internet Explorer 9
  • Silverlight 4
  • Windows Mobile 7
  • Azure (ok, not really a rumor - this is scheduled to be launched today)
I attended a pre-conference party last night where several Microsoft employees were present. Funny how nobody there could confirm nor deny any of these announcements. However, I did run into someone in the hotel lobby last night (a UK-based Mobile developer) who insisted I keep the faith, and that Windows Mobile 7 is "going to rock!"

Usability and Touch

With the additions of the Windows Touch API into Windows 7, a developer now how has a brand new way of soliciting input into his or her application. However, there are usability considerations which are needed. Some UI designs which make sense in a keyboard / mouse world will need to be adjusted for touch scenarios, and I’ll attempt to address some of them below.


Are the controls big enough?
When putting controls on your form or canvas, remember that your user’s fingers have to be able to touch it without accidently activating the wrong control. Consider the following screenshots of a music player.



image image(the height of the picture was altered to fit better in the post).



Notice how the buttons are too close together. I can say first-hand that touching the pause button often misses and accidently skips to the next track. A better approach for touch would be make the buttons larger and perhaps space them out a little more. Also notice the scroll bar width. It is not really wide enough for a user to easily scroll through options.



Is there too much ‘stuff’ on the screen?
It is very easy to fall into the trap of trying to make an application have a tremendous amount of functionality and putting it in as little space as possible. Many times, this is done to minimize the number of ‘clicks’ a user needs to do. In doing this, we tend to forget is that the purpose of minimizing clicks is to make an application easier to use. Users will often be more than happy to perform another click (or touch in our case) if it makes the application more intuitive. Make sure that the screens in your touch application don’t have too much ‘stuff’ on each one and to present information in a way readable to your average user.


Are extra visual clues needed?
One technique designers use to follow the “less is more” principle is to hide functionality until it is needed. In the screenshot below, the column resizing markers are hidden until the mouse pointer is hovering over the column resizing row.



image



In a touch screen, hardware might not be present to simulate “hover” functionality. This leaves the user to use trial-and-error in order to find where to resize the column. That is, if they’re aware they can resize it in the first place! (See the little lines between the heart and the MP3 player icon? That's the column resizing area. Now imagine trying to touch a screen to resize it!) This issue can be minimized in touch programs by not using hover-based (mouse over) functionality. Alternatively, provide an alternative means to do the same thing.



Can less traditional controls be used?
Maybe there are better ways of handling application function by using less of the traditional controls. Here are some examples of this technique.


image image



Note how the application allows for buttons at the bottom (stylized like a DVR remote control), but also has touchable album art which yields more information. Although it is hard to see from the image, there is plenty of space for someone to touch the desired action, with much less chance of accidently touching the wrong area.


Can the user touch where they need to?
A user often can’t touch areas right at the edge of the screen. With the TouchSmart tablet I use, there is an area of plastic around the screen which makes it difficult to touch the Close Window icon (X in the upper right hand of a window) along with any vertical scroll bars usually placed on the right hand side of a window. Make sure to provide extra space to compensate for physical limitations.


These are just some basic questions that should be considered when making an application which uses touch functionality. Additionally, be sure to review the Windows User Experience Interaction Guidelines when designing your application as well. By following these steps and using common sense, you can provide a pleasant, enjoyable, and above all, usable application for your end users.

Hosting WCF Services in Windows Azure

So you want to host a Windows Communication Foundation (WCF) service in Windows Azure? Here’s how you do it. This post will describe the steps you need to get your WCF service up and running in Windows Azure. This walkthrough assumes you are already familiar with the basics of WCF services. Hosting your services in Windows Azure has the benefit of you not having to provide the hardware for hosting your service and you can instead rely on Microsoft providing that capability for you.

Be sure you have the latest version of the Azure CTP installed and are running Windows Vista or Windows 7. Spin up Visual Studio 2008 in Administrator mode. You’ll want to be sure be sure the latest version of the CTP is installed. In this case I will be using the July 2009 CTP.

Begin by creating a Cloud Service solution. For the purpose of this demo, we’ll name it ‘AzureHostedWCF’.



When the dialog prompts you to create a new cloud service project, add a new ASP.NET Web Role project:

The web role is required as part of the cloud service.

Next, add a new Item to the web role project, namely a WCF Service item, called ‘TestWCFService’. For the purpose of this demonstration, we’ll augment the service interface as follows:

using System;

using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WebRole1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string TellUserCurrentTime(string name);

}
}

The implementation looks like this:

using System;

using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WebRole1
{
public class Service1 : IService1
{
public string TellUserCurrentTime(string name)
{
DateTime now = DateTime.Now;
return string.Format("Hi {0}. Currently it is {1} {2}.",
name, now.ToShortDateString(), now.ToShortTimeString());
}
}
}

This service is very barebones for the purpose of this demonstration. Compile to make sure there are no errors. Right click on the cloud project (‘AzureHostedWCF’) and ‘Set as Startup Project’. Start the project in debug mode. In the browser window that opens, add ‘Service1.svc’ to the URL (the full URL in my case is http://127.0.0.1:81/Service1.svc ). This will show you that the service has been successfully created and hosted in the Azure development fabric. The development fabric simulates the Windows Azure fabric on your development machine for testing before you code is deployed.


Now that we have confirmed that the service is working in the development fabric, we are ready to publish the service to Azure. Right-click on the cloud project (‘AzureHostedWCF’) and select ‘Publish’. You will notice two things happen. First, a browser window is opened for the Windows Azure portal. Second, an explorer window is opened showing the package file and the configuration file for the cloud service. What we need to do is upload that package to Azure so it can be deployed.

Create a new hosted service in Windows Azure, we’ll call it AzureHostedWCF. Provide a description if you choose, then click the ‘Next’ button.



On the following screen a public service name needs to be provided, which is globally unique. Again, we’ll use AzureHostedWCF for the public name of the service. This can be anything you like.

Also, a region needs to be selected. For the purpose of this demonstration, we will select the ‘North Central US’. A discussion of Azure regions is beyond the scope of this demonstration. Once you have entered the information, click the ‘Create’ button.



Next, we are presented with a screen to deploy the service. Click the ‘Deploy’ button in the middle of the screen. Earlier in the Azure CTP, packages first had to be deployed to staging before they could be pushed to production. That process can now be bypassed and packages can be directly deployed to Production. Clicking on the left-facing arrow below highlighted in red will show the staging environment deployment.



On the following screen you are asked to select the application package and the configuration settings files. These are the same files that opened in the explorer window above. Locate the files and select them. You also need to add a deployment label for this service. We will use 1.0 for the purposes of this demo. Click ‘Deploy’ when you are ready.



It will take a couple of minutes for the package to deploy in Azure. When completed, you will be presented with the following screen:



Click the ‘Run’ button to start the service. Again, the package will take a few minutes to be deployed. The progress indicator under the web role name will go from a blue dot indication of ‘Stopped’, to a yellow dot indication of ‘Initializing’ and finally to a green checkmark of ‘Ready.

Once the service is ready, click on the web site URL. When the URL opens in the browser, add the service name to the end of the URL. In this case, the URL will be: http://azurehostedwcf.cloudapp.net/Service1.svc. You’ll notice the service page is now displayed.

Now we want to test that the service is properly hosted and can be consumed from Azure. Create a console test project. Add a service reference to the URL. Notice that it can’t be done. Click on the WSDL link in the above screenshot. Again, it doesn’t appear to work. There is a known bug with Azure where a proxy cannot be created from the Azure hosted service. The workaround is to create the service reference using the service hosted in the development fabric, then change the URL reference to point to the service hosted in Azure. So, go back to the ‘AzureHostedWCF’ solution, start debugging and open the service in a browser window. Now go back to test project and add a reference to the local service providing whatever namespace you choose. The code to call the service should look something like this:

using System;

using ConsumeAzureHostedWCFR.AzureHostedWCFService;

namespace ConsumeAzureHostedWCF
{
class Program
{
static void Main(string[] args)
{
Service1Client client = null;

try
{
client = new Service1Client();
string time = client.TellUserCurrentTime("Greg");

Console.WriteLine(string.Format("The service responded with: {0}", time));
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(string.Format("{0}\n{1}", e.Message, e.StackTrace));
}
finally
{
if (client != null)
client.Close();
}
}
}
}

Finally, go into the web.config of the test project and update the address of the service endpoint to http://azurehostedwcf.cloudapp.net/Service1.svc. The node in the web.config file will look like this:

<client>

<endpoint address="http://azurehostedwcf.cloudapp.net/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="AzureHostedWCFService.IService1"
name="BasicHttpBinding_IService1" />
</client>

The output of the service call looks something like this:

This is a very simply example of an Azure hosted WCF service. More complicated services are deployed to Azure in much the same way. Go forth and deploy your WCF services to Azure!



Web application load testing: My interview with LoadStorm

Scott Price, a founder of LoadStorm, recently interviewed me about my thoughts on web application load testing. The interview can be seen here.

Using Windows Touch Gestures with .NET (Part 2: Retrieving Gestures)

In the previous posting, the means of configuring Gestures with the Windows Touch API was discussed. This post will show how to retrieve Gesture information from the Windows Touch API in Windows 7 from the .NET Framework.


Structures and P/Invoke Setup


Once you have configured your Windows Touch application to use Gestures (See Link For Blog Posting On Configuration), we now have to get the information about the gesture from the API. This, too, will require a platform invoke (p/invoke) and a structure, with the key difference being we are receiving information from the API instead of sending information.


The GESTUREINFO structure is container which holds all of the information we need. However, we also need a structure which will return the various points about the touch. This structure will hold the X and Y values of the area of the gesture.


public struct POINTS
{
public int x;
public int y;
}


private struct GESTUREINFO
{
public int size;
public int flags;
public int id;
public IntPtr windowhandle;
public POINTS location;
public int instanceid;
public int sequenceid;
public Int64 arguments; // Needs to be 8 bytes
public int extraarguments;
}


GESTUREINFO has nine different variables in it:



  • size – This is the size of the GESTUREINFO structure

  • flags – Information involving the gesture’s state.

    • The state can be begin, end, or inertia. Only the last state should be handled by your app (inertia).

  • id – The ID that determines the Gesture type (see here for more information)

  • windowhandle – the Handle of the Window which generated the gesture

  • location – the location of the gesture.

  • instanceid – an internal ID of the gesture.

  • sequenceid – an internal number that identifies the sequence of the gesture

  • arguments – holds the arguments for the Gesture

    • This is mostly set to 0, except for the PAN and the PRESSANDTAP gestures. In the case of PAN, if the inertia flag was set, then the inertia vectors are included in this field. In the PRESSANDTAP gesture, it holds the distance between the two points.

  • extraarguments – the byte size of the extra arguments involved with this gesture.

The p/invoke declaration is set up in the class you are using by doing a DllImport to the user32.dll. It will look like this:


[DllImport("user32")]
private static extern bool GetGestureInfo(IntPtr gestureinfohandle, GESTUREINFO gestureinfo);


Remember to include the using / import statement for System.Runtime.InteropServices.


Obtaining the Gesture Information


From here, you’ll call the GetGestureInfo() function from the overridden WndProc() function. This should only be called when the WM_GESTURE message is sent. A switch statement is ideal for this, with the added benefit of being able to add additional message captures as new functionality is needed. If the GetGestureInfo() function returns false, we didn’t capture any Gesture information. Otherwise, anther switch statement is needed. The branching is done the id field of the GESTUREINFO structure returned. The id determines when a gesture begins, ends, and what type of gesture is being captured.


// Constants
private const int WM_GESTURE = 0x0119; // Defined ID for an incoming Gesture


// Gesture IDs
private const int GID_BEGIN = 1;
private const int GID_END = 2;
private const int GID_ZOOM = 3;
private const int GID_PAN = 4;
private const int GID_ROTATE = 5;
private const int GID_TWOFINGERTAP = 6;
private const int GID_PRESSANDTAP = 7;


Putting It All Together


You have learned how to set gesture configuration within a .NET application and to consume those gestures when they’ve occurred. At this point, you should refer to the MSDN Library for more information, including instructions on how to use the other fields within GESTUREINFO structure and how to close the Gesture handle to avoid memory leaks.


I’ll include the source code for a small reference application below. It is up to the reader to create the project and add the appropriate controls to a form to see the results. The app does set the configuration for the gestures to block any horizontal pan gestures and needs to be adjusted if that gesture direction needs to be handled. Lastly, this app is not meant to be a solid design – it is meant only to be used as a reference for gestures.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


using System.Runtime.InteropServices;


namespace BasicGestures
{
public partial class Form1 : Form
{


private struct GESTURECONFIG
{
public int id;
public int want;
public int block;
}


private struct GESTUREINFO
{
public int size;
public int flags;
public int id;
public IntPtr windowhandle;
public POINTS location;
public int instanceid;
public int sequenceid;
public Int64 arguments;
public int extraarguments;
}


public struct POINTS
{
public int x;
public int y;
}


// Constants
private const int WM_GESTURE = 0x0119; // Defined ID for an incoming Gesture
// Gesture IDs
private const int GID_BEGIN = 1;
private const int GID_END = 2;
private const int GID_ZOOM = 3;
private const int GID_PAN = 4;
private const int GID_ROTATE = 5;
private const int GID_TWOFINGERTAP = 6;
private const int GID_PRESSANDTAP = 7;


[DllImport("user32")]
private static extern bool GetGestureInfo(IntPtr gestureinfohandle, ref GESTUREINFO gestureinfo);


[DllImport("user32")]
private static extern bool SetGestureConfig(IntPtr window, int reserved, int ids, ref GESTURECONFIG config, int size);


public Form1()
{
InitializeComponent();
}


private void Form1_Load(object sender, EventArgs e)
{
GESTURECONFIG info = new GESTURECONFIG()
{
id = 0x00000004,
want = 0x00000002,
block = 0x00000004
};


if (SetGestureConfig(this.Handle, 0, 1, ref info, Marshal.SizeOf(info)) == true)
{
lblConfigSet.Text = "Config Setting Successful";
}
else
{
lblConfigSet.Text = "Config Setting Unsuccessful";
}
}


protected override void WndProc(ref Message m)
{
bool ishandled = false;


switch (m.Msg)
{
case WM_GESTURE: // Gesture Has Been sent to the window


GESTUREINFO gestureinfo = new GESTUREINFO();
gestureinfo.size = Marshal.SizeOf(gestureinfo);


if (GetGestureInfo(m.LParam, ref gestureinfo) == false)
{
ishandled = false;
}
else
{
lblGestureDetected.Text = "Gesture Info Received.";


txtX.Text = gestureinfo.location.x.ToString();
txtY.Text = gestureinfo.location.y.ToString();


switch (gestureinfo.id)
{
case GID_BEGIN:
lblGestureDetected.Text = "Gesture Begun";
ishandled = true;
break;


case GID_END:
lblGestureDetected.Text = "Gesture Ended.";
txtX.Text = "0";
txtY.Text = "0";
ishandled = true;
break;


case GID_PAN:
lblGestureType.Text = "Pan Gesture";
ishandled = true;
break;


case GID_PRESSANDTAP:
lblGestureType.Text = "Press And Tap Gesture";
ishandled = true;
break;


case GID_ROTATE:
lblGestureType.Text = "Rotate Gesture";
ishandled = true;
break;


case GID_TWOFINGERTAP:
lblGestureType.Text = "Two Finger Tap Gesture";
ishandled = true;
break;


case GID_ZOOM:
lblGestureType.Text = "Zoom Gesture";
ishandled = true;
break;


default:
lblGestureType.Text = "Unknown Gesture Type";
ishandled = true;
break;
};
}
break;


default:
break;
};


base.WndProc(ref m);


if (ishandled == true)
{
m.Result = new System.IntPtr(1);
}


}
}
}

Using Windows Touch Gestures with .NET (Part 1: Configuration)

The last two posts discussing Windows Touch gave a high level view of using the Windows Touch SDK in Windows 7 with the .NET Framework. In this post, I’d like to go into more detail on using Gestures. Remember from the first post – Gestures cannot be used when the RegisterTouchWindow() has been called.

Configuration – Where to Configure

In the Windows Touch SDK, Gesture messages are sent by default to all windows, without any kind of configuration settings. However, configuration is needed to fine-tune what gestures are sent and which ones are ignored. This is done via a p/invoke of the SetGestureConfig() function in user32.dll in one of two places: in the Load event or when the WM_GESTURENOTIFY message has been sent. Ideally, the Load event is the place to set the configuration, unless the configuration parameters will be changed multiple times.

Structures and P/Invoke Setup

When setting up the configuration for using the Windows Touch SDK with .NET, you’ll need to declare the structure needed to hold the configuration. You’ll also need to declare the external functions (p/invoke) for setting the configuration, along with the values needed for each configuration option.


The Configuration Structure (GESTURECONFIG) is pretty straightforward, with only three ints in the structure. It is good to note that more than one GESTURECONFIG structures can be sent, as this allows specific settings for each individual gesture.

The GESTURECONFIG can be declared as follows:

private struct GESTURECONFIG
{
public int id;
public int want;
public int block;
}

The id field determines which gesture for which you are setting the configuration. (See Here For Gestures And Their IDs). The Want and Block fields determine which features (specified by a flag) within a specific gesture are wanted or blocked. Most Gestures only have a feature flag of ID 0x0000001, as the gesture has only one feature (like Zoom). Pan has five gesture flags: 0x0000001 (All gestures), 0x00000002 (vertical pans with one finger), 0x00000004 (horizontal pans with one finger), 0x00000008 (Pan with a ‘gutter’), and 0x00000010 (Pan with Inertia).

So, a new GESTURECONFIG for activating just a vertical pan would be:


GESTURECONFIG config = new GESTURECONFIG(){
id = 0x00000004, // This is the ID for PAN
want = 0x00000002, // We want to have vertical PAN
block = 0x00000004 // We want to block the horizontal PAN
};


The p/invoke declaration is set up in the class you are using by doing a DllImport to the user32.dll. It will look like this:


[DllImport("user32")]
private static extern bool SetGestureConfig(IntPtr window, int reserved, int ids, ref GESTURECONFIG config, int size);

Remember to include the using / import statement for System.Runtime.InteropServices.

Setting the Configuration

At this point, we have set up all the prerequisite information for setting the Gesture Configuration. The SetGestureConfig() function takes in five different parameters:

  • hWnd – The Handle to the Window that we’re using to capture gestures.
  • Reserved – This is reserved for future use and needs to be set to 0.
  • IDs – This is how many GESTURECONFIG structures that are being in passed into SetGestureConfig().
  • config – An array of GESTURECONFIG structures containing the configuration information.
  • size – the size of the array passed in.

Once called, SetGestureConfig() return a zero if it is unsuccessful in setting the gesture configuration and a nonzero value if successful.

bool result = SetGestureConfig(this.Handle, 0, 1, ref config, Marshal.SizeOf(config));

Putting It All Together

If we were to set the PAN Gesture to only accept vertical gestures, we’d put the previous code snippets together into a single form. It would look something like this:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


using System.Runtime.InteropServices;


namespace VerticalPanOnly
{
public partial class frmGestures : Form
{
private struct GESTURECONFIG
{
public int id;
public int want;
public int block;
}


[DllImport("user32")]
private static extern bool SetGestureConfig(IntPtr window, int reserved, int ids, ref GESTURECONFIG config, int size);

public frmGestures()
{
InitializeComponent();
}

private void frmGestures_Load(object sender, EventArgs e)
{
GESTURECONFIG config = new GESTURECONFIG(){
id = 0x00000004, // This is the ID for PAN
want = 0x00000002, // We want to have vertical PAN
block = 0x00000004 // We want to block the horizontal pan
};

int size = Marshal.SizeOf(config);


bool result = SetGestureConfig(this.Handle, 0, 1, ref config, Marshal.SizeOf(config));
}

}
}

In another post, I’ll demonstrate how to obtain gesture information from the Windows Touch API in .NET once a gesture has occurred.

Touch and Gestures

When programming using Windows Touch (The Windows 7 Touch API), it is important to determine the best method to use. Windows Touch has three main ways of implementing Touch functionality.

  1. Touch Input
  2. Gestures
  3. Legacy

Touch Input

Touch input allows for fine-grained control over the input digitizer. In order to do this, you’ll need to register the window you’re working with to the Windows Touch API via the RegisterTouchWindow() function, located in the user32.dll. If you’re using .NET, this will have to be done through a p-invoke. Once this is done, you’ll need to override the WndProc function and switch on a WM_TOUCH message being passed. From there, you’ll find that that you’ll be able to grab all sorts of information related to the touch in question.

Message FlagFunctionality
MoveDetermines if the touch is movement (as opposed to a touch-down event).
DownA new touch contact has been made.
UpThe touch contact has been broken.
In RangeAllows to determine if the touch message comes from a “hover”, meaning the user has their finger over the screen, instead of on it. Not all hardware supports this.
PrimaryDetermines if this is the first contact point.
PalmDetermines if this is the contact was made by the users palm.

This is in the TOUCHINPUT Structure. It also includes information such as X/Y coordinates, source ID, TouchPointID, Time Stamp, width/height of the actual touch contact, and a few other items.

Gestures

Gestures are the ‘default’ way of handling touch within the Windows Touch API. if you’ll note in the Touch Input section of this post, there is an explicit call to the API to register a window as Touch. This isn’t needed for gestures: WM_GESTURE is always sent to your window unless you call the RegisterTouchWindow() function. Implementing Gestures is done in a similar manner to Touch Input: override the WndProc function and branch on the WM_GESTURE message. From here, the Gesture ID will tell you what gesture is being performed, along with related information.

Gestures are defined as a specific action performed with one or more fingers on a touch screen. This can be something as simple as a single touch on the screen to a more complex task of rotating two fingers in opposite directions.

GestureGesture How-ToGesture IDIs Single-Touch?Is Multi-Touch?
PanTouch the screen with one or two fingers. Drag the fingers up or down.4YesYes
Press and TapTouch the screen with a finger and hold. While holding, touch the screen in a different spot with another finger.7NoYes
ZoomTouch the screen with two fingers and hold. Move the fingers away from each other, or bring them together.3NoYes
RotateTouch the screen with two fingers and rotate them.5NoYes
Two Finger TapTouch the screen briefly with two fingers and let go.6NoYes
FlicksTouch the screen and quickly drag up, down, left, or right. N/AYesYes

To capture a straight-forward single touch / tap to the screen, handle the Click event of your window.

Legacy

If you want only a the simplest form of Touch support, this method is, by far, the easiest to implement. No work at all is required to use the API. The downside of this, however, is that only four different gestures are supported. These four gestures map back to Windows messages that we’re all familiar with.

GestureGesture How-ToMapping
PanTouch the screen with one or two fingers. Drag the fingers up or down.Scroll up / down
Press and HoldTouch the screen with a finger and hold. Wait until a circle is drawn around your finger and then let go.Right Click
ZoomTouch the screen with two fingers and hold. Move the fingers away from each other, or bring them together.Mouse Wheel
TapTouch the screen briefly and let go.Left Click

In conclusion, Windows Touch offers flexibility for simple and complex development tasks. Windows Touch offers basic support for beginners and extended functionality for experts. By planning your application well, and implementing the appropriate touch strategy, you can greatly enhance your user experience and make your apps highly desirable.

Come learn about SketchFlow!

On Saturday, November 7, I'll be presenting an introduction to SketchFlow at the Central Maryland Association of .NET Professionals (CMAP) Code Camp in Columbia, Maryland.

A bit more info on my talk:
Microsoft's Expression Blend 3 has a baked-in tool called SketchFlow, targeted directly at prototyping your WPF and Silverlight applications. In this talk, I'll walk through building a prototype and exercising several SketchFlow features available out-of-the-box. I'll also show how easy it is to distribute a prototype and get back annotated feedback from your reviewers.

A bit more info about the code camp (from cmapcodecamp.org): The Code Camp will run from 8:30am - 5:30pm with 20-25 awesome sessions covering a wide range of database, software and portal development topics. It's totally free. No gimmicks. No sales pitches. Enjoy breakfast and lunch at no charge while you mingle with your peers. To register for this event, visit here.



For even more info, visit http://www.cmapcodecamp.org/.

Starting To Use The Windows 7 Touch API in .NET

I don’t know about you, but I’ve been really looking forward to the touch features built into Windows 7 (also known as Windows Touch). Now that we’ve hit general availability for Windows 7, I took a look at how I might be able to start using the Windows Touch in my .NET applications.


After a little review, it turns out that it is not as simple as you’d think. Windows Touch is not a .NET native, and a platform invoke (p-invoke) is needed to really reap the full benefits. I say full benefits, because Windows Touch sends some events to applications, without doing anything at all. It’s pretty much what you’d expect: a single touch sends a Click event to the form/control in question, holding a touch to the screen will send a RightClick to the form. But in order to do the really neat stuff, you need to use p-invoke.


A basic example of how to perform a platform invoke is creating a simple form which determines the touch capabilities of the client running your application. While this doesn’t use the touch API, it does provide a basic example of how access the user32.dll.


Start off by creating a form in .NET. Be sure to include an imports / using statement which accesses System.RunTime.InteropServices. Next, in the form you’ve created, be sure to add a DLL Import of user32.dll for the GetSystemMetrics() function. This is what we’ll use to determine what touch features are available. It will look something like this:


PInvoke


Next, we’ll need to create some constants to handle the value returned from the GetSystemMetrics function.


TouchConstants


These constants are AND-wise compared with returned value to see all of the capabilities available. This is needed, because a computer might well have an integrated pen and an external pen. The AND-wise compare looks like this.


CheckTouchCapabilities


In case you are wondering, the 94 submitted to the GetSystemMetrics() function is a ‘magic number’ that tells the function to bring back just the Windows Touch-related capabilities. You can reference the Windows API and see other kinds of metrics (How many buttons are on the mouse, whether or not the call is being performed in a Terminal Services environment, whether you’re running a “Starter” edition, etc..)


In conclusion, this is a good start for getting your feet wet in using platform invoke and to determine how to what touch capabilities your computer is capable of. In another post, I’ll describe how to register a touch window in .NET with p-invoke and how to get information from the Windows Touch API.