Click here to Skip to main content
Click here to Skip to main content

Windows 7 Multitouch Application Development (Part - I)

By , 26 Aug 2009
 

Microsoft is going to launch the new Windows 7 operating system in October 2009. Currently the RC version is available online. As you know, Windows 7 came up with lots of goodies including better resource management, better performance, jumplist management, multitouch functionality & many more. Here I will discuss about developing a simple multitouch application using .NET 3.5 SP1.

Before doing anything, you have to download the Windows 7 Multitouch API. You can download it from here. Extract the downloaded zip file to your local hard drive. Be sure that you are using Windows 7 & you have a multitouch enabled screen to test it out.

Create a WPF application using Visual Studio 2008. This will automatically add an XAML file named Window1.xaml for you. Now add an image to your solution directory & insert it in the XAML. Now your Window1.xaml will look something like this:

<Grid>
<Image Source="images/Hydrangeas.jpg"/>
</Grid>

Add RenderTransform to the image so that we can scale or rotate the image properly. This will produce XAML similar to this:

<Grid>
<Image Source="images/Hydrangeas.jpg" RenderTransformOrigin="0.5,0.5" Width="400">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="trScale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="trRotate" Angle="0"/>
<TranslateTransform x:Name="trTranslate" X="0" Y="0"/>
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>

Use proper names when you are adding different types of transform to the transform group. It will be easier for you to handle it from the code behind file. Run your application. This will open up your Window with an image inside it. If you want to drag or rotate the image, this will not work because we haven’t integrated the functionality yet.

Add two project references, i.e. “Windows7.Multitouch” & “Windows7.Multitouch.WPF” from the extracted zip folder to your solution. These are the managed API codes for multitouch application development.

Go to your Window1.xaml.cs and be sure that the following namespaces are already included. You may have to add some of them.

using System;
using System.Windows;
using Windows7.Multitouch;
using Windows7.Multitouch.Manipulation;
using Windows7.Multitouch.WPF;

Create two private members inside your partial class:

// object of a .Net Wrapper class for processing multitouch manipulation
private ManipulationProcessor manipulationProcessor = 
		new ManipulationProcessor(ProcessorManipulations.ALL);

// boolean value to check whether you have a multitouch enabled screen
private static bool IsMultitouchEnabled = 
		TouchHandler.DigitizerCapabilities.IsMultiTouchReady;

Now inside the Window Loaded event, write the following lines of code:

// check to see whether multitouch is enabled
if (IsMultitouchEnabled)
{
     // enables stylus events for processor manipulation
     Factory.EnableStylusEvents(this);

     // add the stylus events
     StylusDown += (s, e) => 
     { 
          manipulationProcessor.ProcessDown
		((uint)e.StylusDevice.Id,      e.GetPosition(this).ToDrawingPointF()); 
     };
     StylusUp += (s, e) => 
     { 
          manipulationProcessor.ProcessUp
		((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); 
     };
     StylusMove += (s, e) => 
     { 
          manipulationProcessor.ProcessMove
		((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); 
     };

     // register the ManipulationDelta event with the manipulation processor
     manipulationProcessor.ManipulationDelta += ProcessManipulationDelta;

     // set the rotation angle for single finger manipulation
     manipulationProcessor.PivotRadius = 2;
}

Write your logic inside the manipulation event handler implementation block. Here I will do rotation, scaling & positioning of the image. Here is my code:

private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
     trTranslate.X += e.TranslationDelta.Width;
     trTranslate.Y += e.TranslationDelta.Height;

     trRotate.Angle += e.RotationDelta * 180 / Math.PI;

     trScale.ScaleX *= e.ScaleDelta;
     trScale.ScaleY *= e.ScaleDelta;
}

From the ManipulationDeltaEventArgs, you can get various values and depending upon them, you can implement your functionality in this block. TranslateTransform will position the image, RotateTransform will do the rotation and the ScaleTransform will resize the image. Run your project to test your first multitouch application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

_ Kunal Chowdhury _
Software Developer
India India
Member
Kunal Chowdhury is a Microsoft MVP (Most Valuable Professional) in Silverlight Technology, a Codeproject MVP & Mentor, DZone MVB (Most Valuable Blogger), Speaker in various Microsoft events, Author, passionate Blogger and a Software Engineer by profession.
 
He is currently working as a Software Engineer II in an MNC located at Pune, India. He has a very good skill over XAML, C#, Silverlight and WPF. He has a good working experience in Windows 7 application (including Multi-touch) development too.
 
He posts his findings in his technical blog. He also writes for SilverlightShow and Codeproject portal. Many of his articles were highlighted as "Article of the Day" in Microsoft sites.
 
He also has another website called Silverlight-Zone.com where he posts article links on Silverlight, Windows Phone 7 and XNA accumulated from various web sites to help the community grow on specified technologies.
 
You can reach him in his Blog : http://www.kunal-chowdhury.com
He is also available in Twitter : http://twitter.com/kunal2383

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMultitouch applicationmemberbhanuprakash00721 Sep '10 - 22:52 
Hi,
 
Iam working on multitouch applciation.My requirement is Iam using one image as background which should be static and other images are used to move on the Background image.
 
First i have downloaded your code and i saw that where ever i can touch the screen it is moving but i want when i touch the image then only it have to move. Can you suggest where i have to change the code so that it should move only when i touch the image on the screen.Please check once the below code
 

void Window1_Loaded(object sender, RoutedEventArgs re)
{
// check to see whether multitouch is enabled
if (IsMultitouchEnabled)
{
// enables stylus events for processor manipulation
Factory.EnableStylusEvents(this);
 
// add the stylus events
StylusDown += (s, e) => { manipulationProcessor.ProcessDown((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
StylusUp += (s, e) => { manipulationProcessor.ProcessUp((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
StylusMove += (s, e) => { manipulationProcessor.ProcessMove((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
 
// register the ManipulationDelta event with the manipulation processor
manipulationProcessor.ManipulationDelta += ProcessManipulationDelta;
 
// set the rotation angle for single finger manipulation
manipulationProcessor.PivotRadius = 2;
}
}
 
private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
trTranslate.X += e.TranslationDelta.Width;
trTranslate.Y += e.TranslationDelta.Height;
 
trRotate.Angle += e.RotationDelta * 180 / Math.PI;
 
trScale.ScaleX *= e.ScaleDelta;
trScale.ScaleY *= e.ScaleDelta;
 

 
tr1Translate.X += e.TranslationDelta.Width;
tr1Translate.Y += e.TranslationDelta.Height;
 
tr1Rotate.Angle += e.RotationDelta * 180 / Math.PI;
 
tr1Scale.ScaleX *= e.ScaleDelta;
tr1Scale.ScaleY *= e.ScaleDelta;
 

 
tr2Translate.X += e.TranslationDelta.Width;
tr2Translate.Y += e.TranslationDelta.Height;
 
tr2Rotate.Angle += e.RotationDelta * 180 / Math.PI;
 
tr2Scale.ScaleX *= e.ScaleDelta;
tr2Scale.ScaleY *= e.ScaleDelta;
 

 

}
}
QuestionMulitple Images on a background imagememberbhanuprakash00717 Sep '10 - 1:56 
Hi,
 
Iam working on multitouch applciation.My requirement is Iam using one image as background which should be static and other images are used to move on the Background image.
 
1. First i have downloaded your code and i saw that where ever i can touch the screen it is moving but i want when i touch the image then only it have to move.
 
2. I have used your code and modified according to my requirement.But no image is moving after doing the modifications.
 
Can you please help me regarding this.Below is my code
 
<Window x:Class="Win7MultitouchDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Windows 7 MultiTouch Demo" Height="600" Width="800" WindowState="Maximized">
<Canvas x:Name="holder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="300" Width="500">
<Canvas.Background>
<ImageBrush ImageSource="images/Water lilies.jpg" Stretch="UniformToFill" />
</Canvas.Background>
<Image Source="images/Hydrangeas.jpg" RenderTransformOrigin="0.5,0.5" Width="200" Canvas.Left="307" Canvas.Top="-1" Height="150">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="tr1Scale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="tr1Rotate" Angle="0"/>
<TranslateTransform x:Name="tr1Translate" X="0" Y="0"/>
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Image Source="images/Hydrangeas.jpg" RenderTransformOrigin="0.5,0.5" Width="200" Canvas.Left="309" Canvas.Top="148" Height="150" StretchDirection="Both">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="tr2Scale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="tr2Rotate" Angle="0"/>
<TranslateTransform x:Name="tr2Translate" X="0" Y="0"/>
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Canvas>
 
</Window>
 

 
Cs Code:
 
using System;
using System.Windows;
using Windows7.Multitouch;
using Windows7.Multitouch.Manipulation;
using Windows7.Multitouch.WPF;
 
namespace Win7MultitouchDemo
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
// object of a .Net Wrapper class for processing multitouch manipulation
private ManipulationProcessor manipulationProcessor = new ManipulationProcessor(ProcessorManipulations.ALL);
private static bool IsMultitouchEnabled = TouchHandler.DigitizerCapabilities.IsMultiTouchReady;
 
public Window1()
{
InitializeComponent();
 
this.Loaded += new RoutedEventHandler(Window1_Loaded);
}
 
void Window1_Loaded(object sender, RoutedEventArgs re)
{
// check to see whether multitouch is enabled
if (IsMultitouchEnabled)
{
// enables stylus events for processor manipulation
Factory.EnableStylusEvents(this);
 
// add the stylus events
StylusDown += (s, e) => { manipulationProcessor.ProcessDown((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
StylusUp += (s, e) => { manipulationProcessor.ProcessUp((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
StylusMove += (s, e) => { manipulationProcessor.ProcessMove((uint)e.StylusDevice.Id, e.GetPosition(this).ToDrawingPointF()); };
 
// register the ManipulationDelta event with the manipulation processor
manipulationProcessor.ManipulationDelta += ProcessManipulationDelta;
 
// set the rotation angle for single finger manipulation
manipulationProcessor.PivotRadius = 2;
}
}
 
private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
trTranslate.X += e.TranslationDelta.Width;
trTranslate.Y += e.TranslationDelta.Height;
 
trRotate.Angle += e.RotationDelta * 180 / Math.PI;
 
trScale.ScaleX *= e.ScaleDelta;
trScale.ScaleY *= e.ScaleDelta;
 

 
tr1Translate.X += e.TranslationDelta.Width;
tr1Translate.Y += e.TranslationDelta.Height;
 
tr1Rotate.Angle += e.RotationDelta * 180 / Math.PI;
 
tr1Scale.ScaleX *= e.ScaleDelta;
tr1Scale.ScaleY *= e.ScaleDelta;
 

 
tr2Translate.X += e.TranslationDelta.Width;
tr2Translate.Y += e.TranslationDelta.Height;
 
tr2Rotate.Angle += e.RotationDelta * 180 / Math.PI;
 
tr2Scale.ScaleX *= e.ScaleDelta;
tr2Scale.ScaleY *= e.ScaleDelta;
 

 

}
}
}
QuestionAPI For WIndows7memberbhanuprakash00714 Sep '10 - 4:34 
Hi,
 
I have seen the Windows7 multitouch API in your blog. I have downloaded it and I have done the application and it is working. But i want to know have you developed the Windows7 multitouch API API or we can download from MSDN also.If it is in MSDN can I know the link for that one.
 
Thanks,
bhanu prakash
AnswerRe: API For WIndows7mentorKunalChowdhury14 Sep '10 - 4:42 
Hi Bhanu,
 
Have a look into my another Article in CodeProject: Image Manipulation in Multitouch Development[^]. You can download the API from there.
 
bhanuprakash007 wrote:
But i want to know have you developed the Windows7 multitouch API API or we can download from MSDN also.If it is in MSDN can I know the link for that one.

 
The API was not developed by me. It can be downloaded directly from MSDN. I don't have the exact location. Do a search on net.
 
Cheers...


Regards - Kunal Chowdhury | Software Developer | Blog | Twitter | Silverlight Tutorial | Indian Forum

GeneralMultiple Images..memberchengteck907 Sep '09 - 5:30 
Hi there.. Smile | :)
Thanks for the guide..
What if I have multiple images?
If I have multiple images and when I use the rotate function on 1 image, all the images will rotate..
Can you help me?
This is my code..
The code below contains a media element and a image..
So if i rotate the media element, the image will also rotate..
How do I set the focus on an object..
For example, my finger is on the media element and I rotate it.. Only the media element will rotate..
Thanks Smile | :)
 
My codes below
 
MainWindow.xaml.cs
 public partial class MainWindow : Window
    {
        ManipulationProcessor _processor = new ManipulationProcessor(ProcessorManipulations.ALL);
 
        public MainWindow()
        {
            InitializeComponent();
 
            //if (!Windows7.Multitouch.TouchHandler.DigitizerCapabilities.IsMultiTouchReady)
            //{
            //    MessageBox.Show("Multitouch is not availible");
            //    Environment.Exit(1);
            //}

 
            Loaded += (s, e) => { Factory.EnableStylusEvents(this); };
            SizeChanged += (s, e) => 
                {
                    _image.Width = e.NewSize.Width / 4; _image.Height = e.NewSize.Height/4;
                    Canvas.SetLeft(_image, e.NewSize.Width * 0.375);
                    Canvas.SetTop(_image, e.NewSize.Height * 0.375);
                };
 

            StylusDown += (s, e) => { _processor.ProcessDown((uint)e.StylusDevice.Id, e.GetPosition(_canvas).ToDrawingPointF()); };
           StylusUp += (s, e) => { _processor.ProcessUp((uint)e.StylusDevice.Id, e.GetPosition(_canvas).ToDrawingPointF()); };
           StylusMove += (s, e) => { _processor.ProcessMove((uint)e.StylusDevice.Id, e.GetPosition(_canvas).ToDrawingPointF()); };
 
            _processor.ManipulationDelta += ProcessManipulationDelta;
            _processor.PivotRadius = 2;
            
        }
 
        private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            _translate.X += e.TranslationDelta.Width;
            _translate.Y += e.TranslationDelta.Height;
 
            _rotate.Angle += e.RotationDelta * 180 / Math.PI;
 
            _scale.ScaleX *= e.ScaleDelta;
            _scale.ScaleY *= e.ScaleDelta;
 
            _translate1.X += e.TranslationDelta.Width;
            _translate1.Y += e.TranslationDelta.Height;
 
            _rotate1.Angle += e.RotationDelta * 180 / Math.PI;
 
            _scale1.ScaleX *= e.ScaleDelta;
            _scale1.ScaleY *= e.ScaleDelta; 
        }
    }
 
MainWindow.xaml
<Window x:Class="mtWPFGesture.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="mtWPFManipulation" Height="300" Width="300" WindowState="Maximized" >
    
    <Canvas Name="_canvas">
        <MediaElement Name="_image" Source="C:\Users\Public\Videos\Sample Videos\Wildlife.wmv">
            <MediaElement.RenderTransform>
                <TransformGroup>
                    <RotateTransform x:Name="_rotate" Angle="0"></RotateTransform>
                    <ScaleTransform x:Name="_scale" ScaleX="1" ScaleY="1"></ScaleTransform>
                    <TranslateTransform x:Name="_translate" X="0" Y="0"/>        
                </TransformGroup>
            </MediaElement.RenderTransform>
        </MediaElement>
        <Canvas Name="_canvas1">
            <Image Name="_image1" Source="Guitar.JPG" Stretch="Fill" RenderTransformOrigin="0.5, 0.5">
                <Image.RenderTransform>
                    <TransformGroup>
                        <RotateTransform x:Name="_rotate1" Angle="0"></RotateTransform>
                        <ScaleTransform x:Name="_scale1" ScaleX="1" ScaleY="1"></ScaleTransform>
                        <TranslateTransform x:Name="_translate1" X="0" Y="0"/>
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
        </Canvas>
    </Canvas>
    
 
</Window>

GeneralRe: Multiple Images..memberKunalChowdhury7 Sep '09 - 6:29 
yes.... this thing is also possible.
 
u have to create your own class for that to manipulate the media object separately.
keep an eye to my blog. I will post that soon....
 
Regards,
- Kunal Chowdhury (My Blog)
 

GeneralRe: Multiple Images..memberchengteck907 Sep '09 - 14:52 
I see.. Thanks alot in advance.. Smile | :)
I will be looking forward to your coming guide.. Wink | ;)
GeneralRe: Multiple Images..memberchengteck907 Sep '09 - 15:43 
Just another suggestion..
Maybe you can do a guide like something in this video? Wink | ;)
http://www.youtube.com/watch?v=W43RVQqI6BU[^]
JokeRe: Multiple Images..memberKunalChowdhury7 Sep '09 - 18:17 
Thanks for all the suggestions.... Smile | :)
 
Regards,
- Kunal Chowdhury (My Blog)
 

GeneralRe: Multiple Images..memberchengteck907 Sep '09 - 20:09 
No problem.. Smile | :)
I will be looking forward to your coming guide.. Wink | ;)
AnswerRe: Multiple Images..memberKunalChowdhury8 Sep '09 - 19:59 
Hi cheng... Have a look into my recent blog post for the solution...
Windows 7 Multitouch Application Development (Part - II)[^]
Thanks for your comments... Smile | :)
 
Regards,
- Kunal Chowdhury (My Blog)
 

GeneralRe: Multiple Images..memberchengteck908 Sep '09 - 20:01 
Ok... Thanks alot.. Smile | :)
Mind uploading your Sample Application?
I notice the link is not working..
Download Sample Application
I want to try first and see how it work.. Wink | ;)
GeneralRe: Multiple Images..memberchengteck908 Sep '09 - 21:19 
Ok.. I have a rough idea of how it works.. Smile | :)
So for example, if I want to include pictures and videos in my application..
I need to add in 2 more classes which are the VideoTracker and VideoTrackerManager right? Wink | ;)
AnswerRe: Multiple Images..memberKunalChowdhury8 Sep '09 - 22:16 
chengteck90 wrote:
So for example, if I want to include pictures and videos in my application..
I need to add in 2 more classes which are the VideoTracker and VideoTrackerManager right?

 
Yeah, for time being you can use two different classes for picture & video. But I will suggest to use the same class by making it Generic. Generic classes will reduce your no. of class files & also they are easy to maintain.
 
Cheers... Thumbs Up | :thumbsup:
 
Regards,
- Kunal Chowdhury (My Blog)
 

GeneralRe: Multiple Images..memberchengteck908 Sep '09 - 22:35 
I see.. Wink | ;)
Thanks for you help.. Wink | ;)
I am looking forward to your third guide.. Wink | ;)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 26 Aug 2009
Article Copyright 2009 by _ Kunal Chowdhury _
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid