2009年10月18日 星期日

WPF + Windows7 Multi-touch (Part 2)

WPF + Windows7 Multi-touch (Part 1) 這篇文章中, 我們可以透過 P/ Invoke 的方式來取得Windows 7 的手勢訊息, 並對物體作手勢操作.

不過當你用這個方法來取得觸控點的資訊時, 你會發現收不到WM_TOUCH 的訊息, 這個是因為WPF團隊還沒把這部分加進去(這篇
WPF Windows 7 Multi-touch.文章中, WPF團隊有回答此問題)

因此, 如果要在WPF程式中取得觸控點的資訊的話, 就必須採用下面步驟:

  • 新增一個"MicrosoftTabletPenServiceProperty"屬性到視窗上
             IntPtr hWnd = new WindowInteropHelper(this).Handle;
HwndSource src = HwndSource.FromHwnd(hWnd);
Win7TouchMethod.SetProp(src.Handle,
"MicrosoftTabletPenServiceProperty",
new IntPtr(0x01000000));

  • 新增StylusDown/StylusUp/StylusMove的事件, 來處理觸控的相關事件.

this.StylusDown += new StylusDownEventHandler(Window1_StylusDown);
this.StylusMove += new StylusEventHandler(Window1_StylusMove);
this.StylusUp += new StylusEventHandler(Window1_StylusUp);

下面的範例中, 我們會寫一個WPF的觸控應用程式, 當有觸控發生時, 畫面上會出現圓點(用來表示觸控點的位置)

source code如下:

<Window x:Class="WPFTouch.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="800">
<Canvas>
<Ellipse
Canvas.Left="0"
Canvas.Top="0"
Name="Touch1"
Stroke="Black"
Height="30"
Width="30"
Fill="Blue"
Visibility="Hidden"/>

<Ellipse
Canvas.Left="0"
Canvas.Top="0"
Name="Touch2"
Stroke="Black"
Height="30"
Width="30"
Fill="Green"
Visibility="Hidden"/>
</Canvas>

</Window>


using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using Win7TouchInterop;

namespace WPFTouch
{
public partial class Window1 : Window
{

private int Touch1ID = 0; // id for first touch contact
private int Touch2ID = 0; // id for second touch contact

public Window1()
{
InitializeComponent();

Loaded += new RoutedEventHandler(Window1_Loaded);

// Add StylusDown/StylusMove/StylusUp events to handle the touch related events
this.StylusDown += new StylusDownEventHandler(Window1_StylusDown);
this.StylusMove += new StylusEventHandler(Window1_StylusMove);
this.StylusUp += new StylusEventHandler(Window1_StylusUp);
}

void Window1_Loaded(object sender, RoutedEventArgs e)
{
IntPtr hWnd = new WindowInteropHelper(this).Handle;
HwndSource src = HwndSource.FromHwnd(hWnd);

Win7TouchMethod.SetProp(src.Handle,
"MicrosoftTabletPenServiceProperty",
new IntPtr(0x01000000));

}


void Window1_StylusDown(object sender, StylusDownEventArgs e)
{
Point p = e.GetPosition(this); // get the location for this contact


if (Touch1ID == 0)
{
// Show the touch point
Touch1.Visibility = Visibility.Visible;

Touch1ID = e.StylusDevice.Id;

// move the ellipse to the given location
Touch1.SetValue(Canvas.LeftProperty, p.X - Touch1.Width / 2);
Touch1.SetValue(Canvas.TopProperty, p.Y - Touch1.Height / 2);
}
else if (Touch2ID == 0)
{
Touch2.Visibility = Visibility.Visible;

Touch2ID = e.StylusDevice.Id;
// move the ellipse to the given location
Touch2.SetValue(Canvas.LeftProperty, p.X - Touch2.Width / 2);
Touch2.SetValue(Canvas.TopProperty, p.Y - Touch2.Height / 2);
}
}

void Window1_StylusMove(object sender, StylusEventArgs e)
{
Point p = e.GetPosition(this);
// determine which contact this belongs to
if (Touch1ID == e.StylusDevice.Id)
{
Touch1.SetValue(Canvas.LeftProperty, p.X - Touch1.Width / 2);
Touch1.SetValue(Canvas.TopProperty, p.Y - Touch1.Height / 2);
}
else if (Touch2ID == e.StylusDevice.Id)
{
Touch2.SetValue(Canvas.LeftProperty, p.X - Touch2.Width / 2);
Touch2.SetValue(Canvas.TopProperty, p.Y - Touch2.Height / 2);
}
}

void Window1_StylusUp(object sender, StylusEventArgs e)
{
if (e.StylusDevice.Id == Touch1ID)
{
Touch1.Visibility = Visibility.Hidden;

Touch1ID = 0;
}
else if (e.StylusDevice.Id == Touch2ID)
{
Touch2.Visibility = Visibility.Hidden;

Touch2ID = 0;
}
}
}
}


執行畫面如下:


[圖 1] WPF Touch Application

參考文章:
Windows 7 Multi-touch using WPF

2 則留言:

  1. 可以发完整的代码给我吗,非常需要,谢谢你啊
    veryfuns@gmail.com

    回覆刪除
  2. Casino Player Reviews - JtmHub.com
    Check out 태백 출장안마 the casino player feedback, find the 남원 출장마사지 best welcome bonus and 사천 출장샵 share your experience with our casino players. 문경 출장샵 Sign up now and start 정읍 출장샵 winning!

    回覆刪除