かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

タッチイベントを処理しよう

最近のスマートフォンは、タッチで操作するのが主流というか大多数というか全部と言っても過言ではないと思います。
ということでWindows Phone 7でもタッチを処理することが出来ます。

とりあえず、一番低レベルなAPIを使ってみようと思います。使うクラスは、以下になります。

  • System.Windows.Input.Touchクラス
  • System.Windows.Input.TouchPointクラス
  • System.Windows.Input.TouchPointCollectionクラス
  • System.Windows.Input.TouchFrameEventArgsクラス
  • System.Windows.Input.TouchAction構造体

TouchクラスがFrameReportedイベントを公開してるので、このイベントを処理することでタッチを処理できます。イベント引数のTouchFrameEventArgsクラスから色々情報を取得できます。
TouchFrameEventArgsクラスのメソッドは以下のようなものがあります。

  • TouchPoint GetPrimaryTouchPoint(UIElement):引数で渡したUIElementの相対座標で情報を返してくれます
  • TouchPointCollection GetTouchPoints(UIElement):引数で渡したUIElementの相対座標で全部のタッチポイントの情報を返してくれます

TouchPointクラスがタッチした点の情報を持っています。以下のプロパティをよく使うと思います。

  • TouccAction Action { get; }:タッチをしたのかタッチをした状態で動かしたのかタッチをやめたのかを表す構造体を返します。
  • Point Position { get; }:タッチの場所を返します。

ということで、さくっとこれらを使ってプログラムを作ってみようと思います。TouchHelloWorldという名前でプロジェクトを作ります。
今回はXAMLは触りません。MainPage.xaml.csを以下のように編集します。

namespace TouchHelloWorld
{
    using System;
    using System.Diagnostics;
    using System.Windows.Input;
    using Microsoft.Phone.Controls;

    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
            // タッチイベントを登録
            Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
        }

        private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            // タッチの情報を取得(nullを渡すと多分画面左上を起点とした座標を返してくれる)
            TouchPoint touchPoint = e.GetPrimaryTouchPoint(null);
            // タッチに関する情報を出力する
            Debug.WriteLine("***" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff") + "***");
            Debug.WriteLine("  " + touchPoint.Action);
            Debug.WriteLine("  " + touchPoint.Position);

            if (touchPoint.Action == TouchAction.Down)
            {
                // タッチされてる間はマウスイベントを無視するメソッド
                e.SuspendMousePromotionUntilTouchUp();
            }
        }
    }
}

説明してないSuspendMousePromotionUntilTouchUpメソッドを使ってますが、これはコメントにある通り、タッチを辞めるまではマウスのイベントを処理しないということをしてくれるメソッドです。Windows Phone 7にマウスあるのかな?と思いますが呼んでます。(これ必要なのか誰か教えてください・・・)

実行してエミュレータ上で適当にマウスをドラッグすると以下のような情報がデバッグウィンドウに出力されます。

***2010/12/09 22:48:19.328***
  Down
  207,320
***2010/12/09 22:48:19.488***
  Move
  205,320
***2010/12/09 22:48:19.506***
  Move
  204,323
・・・略・・・
***2010/12/09 22:48:19.848***
  Move
  195,511
***2010/12/09 22:48:19.865***
  Move
  214,529
***2010/12/09 22:48:20.004***
  Up
  214,529

単純なタッチを処理するだけなら、これでも十分そうですね。
次回は、もうちょっとリッチなタッチを扱うイベントを見てみようと思います。