小さな子ども向けの文字練習アプリ「もじのれんしゅう」を作る

2014年2月21日(金)
薬師寺 国安

次に、ソリューション・エクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

‘ Windows 8のインクシステムをサポートするクラスの含まれる、Windows.UI.Input.Inking名前空間をインポートします。
‘ インクストロークを描画する場合等に、この名前空間に含まれるクラスを使用します。
Imports Windows.UI.Input.Inking

‘ タッチ、スタイラス ・ ペン、マウス、およびキーボード デバイス等の入力をサポートするクラスの含まれる、
‘ Windows.UI.Input名前空間をインポートします。
Imports Windows.UI.Input

‘ ポインター、タッチ、マウス、およびキーボードを識別し、それらのデバイスに関する情報を取得するクラスの含まれる、
‘ Windows.Devices.Input名前空間をインポートします。
Imports Windows.Devices.Input

‘ 図形に関するクラスの含まれる、Windows.UI.Xaml.Shapes名前空間をインポートします。
Imports Windows.UI.Xaml.Shapes

Imports Windows.UI

‘ 最新の HTTP アプリケーションのプログラミング インターフェイスを提供するクラスの含まれる、
‘ System.Net.Http 名前空間をインポートします。
Imports System.Net.Http

Imports Windows.UI.Popups

Public NotInheritable Class MainPage
  Inherits Page

‘ ポインター入力位置のクライアント座標を取得して格納する、Point型のメンバー変数prevContactPointを宣言します
‘(ポインターデバイスが開始された時のポインター入力位置)。Pointクラスは、2 次元の座標系の点をカプセル化する
‘ クラスです。
  Private prevContactPoint As Point

‘ 入力、操作、および 1つ以上の(手書きの認識を含む)処理を管理するプロパティとメソッドを提供するクラスである
‘ InkManagerクラスのインスタンスである、メンバー変数myInkManagerを宣言します。
  Private myInkManager As New InkManager

‘ 入力ポインターの一意の識別子を取得して格納するメンバー変数myPenIDメンバー変数を宣言します。
  Private myPenID As UInteger

‘ ポインター入力位置のクライアント座標を取得して格納する、Pointクラス型のメンバー変数currentContactPointを
‘ 宣言します(ポインターが移動した時のポインター入力位置)。
  Private currentContactPoint As Point

‘ ポインターデバイスが開始された時のX、Y座標(x1,y1)、ポインターが移動した時のX、Y座標(x2,y2)を格納する
‘ Double型のメンバー変数を宣言しておきます。
  Private x1 As Double
  Private x2 As Double
  Private y1 As Double
  Private y2 As Double
‘ キャラクタに喋らす内容を格納するreadingTextメンバー変数を宣言します。
  Private readingText As String

ページがアクティブになった時の処理

AddHandlerステートメントで、要素内でプレスアクションを起こし、ポインターデバイスが開始された時に発生するPointerPressedイベントに、myCanvas_PointerPressedイベントハンドラを追加します。

AddHandlerステートメントで、要素内でポインターが移動した時に発生するPointerMovedイベントに、myCanvas_PointerMovedイベントハンドラを追加します。

AddHandlerステートメントで、要素内でプレス アクションを開始したポインター デバイスが離された時に発生するPointerReleasedイベントに、myCanvas_PointerReleasedイベントハンドラを追加します。

AddHandlerステートメントで、要素の領域からポインターが離れた時に発生する、PointerExitedイベントに、myCanvas_PointerReleasedイベントハンドラを追加します。

Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    AddHandler myCanvas.PointerPressed, AddressOf myCanvas_PointerPressed
    AddHandler myCanvas.PointerMoved, AddressOf myCanvas_PointerMoved
    AddHandler myCanvas.PointerReleased, AddressOf myCanvas_PointerReleased
    AddHandler myCanvas.PointerExited, AddressOf myCanvas_PointerReleased
  End Sub

要素内で、プレスアクションを起こし、ポインターデバイスが開始された時に発生するイベント

単一のマウス、ペン/スタイラス、またはタッチに関連付けられた入力のポインターを提供するクラスである、PointerPoint型の変数myPointerを宣言し、GetCurrentPointメソッドで、Canvasの現在のポインターを取得します。
PointerPointクラスのPositionプロパティで、ポインター入力の位置のクライアント座標を取得し、メンバー変数prevContactPointに格納します。

現在の、ポインターデバイスのPointerDeviceTypeを取得します。

ポインターデバイスのタイプがペンまたはマウス、またはタッチで、かつ、入力がマウスの左ボタン押下、またはその他の入力メソッドの左ボタン押下からだった場合の処理です。

[文字認識]ボタンの使用を可能にします。InkManagerクラスのProcessPointerDownメソッドで、Canvasの、初期の接触位置と圧力、および傾きなどの接触点の位置や機能に関する情報を処理します。
InkManagerクラスは、入力、操作、および 1つ以上の(手書きの認識を含む)の処理を管理するプロパティとメソッドを提供するクラスです。PointerIdで、入力ポインターの一意の識別子を取得して、メンバー変数myPenIDに格納しておきます。

Private Sub myCanvas_PointerPressed(sender As Object, e As PointerRoutedEventArgs)
  Try
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      prevContactPoint = myPointer.Position
      Dim myPointerDevType As PointerDeviceType = e.Pointer.PointerDeviceType
      If myPointerDevType = PointerDeviceType.Pen Or myPointerDevType = PointerDeviceType.Mouse Or myPointerDevType = PointerDeviceType.Touch And myPointer.Properties.IsLeftButtonPressed = True Then
        myInkManager.ProcessPointerDown(myPointer)
        myPenID = myPointer.PointerId
        e.Handled = True
      End If
    Catch
      Exit Sub
    End Try
  End Sub

要素内で、ポインターが移動した時に発生するイベント

イベントデータを提供するPointerIdが、入力ポインターの一意の識別子と同じである場合の処理です。

GetCurrentPointメソッドで、Canvasの現在のポインターを取得します。
PointerPointクラスのPositionプロパティで、ポインター入力位置のクライアント座標を取得し、メンバー変数currentContactPointに格納します

メンバー変数x1に、ポインターデバイスが開始された時のX座標を指定します。
メンバー変数y1にポインターデバイスが開始された時のY座標を指定します。
メンバー変数x2に、要素内で、ポインターが移動した時のX座標を指定します。
メンバー変数y2に、要素内で、ポインターが移動した時のY座標を指定します。

新しいLineのインスタンスmyLineオブジェクトを作成します。
Line の始点の x 座標に変数x1の値を指定します。
Line の始点の y 座標に変数y1の値を指定します。
Line の終点の x 座標に変数x2の値を指定します。
Line の終点の y 座標に変数y2の値を指定します。Lineの太さを5に指定し、ラインの色を赤に指定します。

要素内で、ポインターが移動した時の、Canvasの現在のポインターをメンバー変数prevContactPointに代入します。
CanvasにAddメソッドでmyLineオブジェクトを追加します。
InkManagerクラスのProcessPointerUpdateメソッドで、最後のイベントポインターから現在のポインターイベントまでの、圧力と傾きなどの、位置と状態プロパティを更新します。

  Private Sub myCanvas_PointerMoved(sender As Object, e As PointerRoutedEventArgs)
    If e.Pointer.PointerId = myPenID Then
      recognizeButton.IsEnabled = True
      clearButton.IsEnabled = True
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      currentContactPoint = myPointer.Position
      x1 = prevContactPoint.X
      y1 = prevContactPoint.Y
      x2 = currentContactPoint.X
      y2 = currentContactPoint.Y
 
      Dim myLine As New Line
      With myLine
        .X1 = x1
        .Y1 = y1
        .X2 = x2
        .Y2 = y2
        .StrokeThickness = 5
        .Stroke = New SolidColorBrush(Colors.Red)
      End With
      prevContactPoint = currentContactPoint
      myCanvas.Children.Add(myLine)
      myInkManager.ProcessPointerUpdate(myPointer)
    End If
    e.Handled = True
  End Sub

要素内で、プレス アクションを開始したポインター デバイスが離された時に発生するイベント

イベントデータを提供するPointerIdが、入力ポインターの一意の識別子と同じである場合の処理です。

GetCurrentPointメソッドで、Canvas内の現在のポインターを取得します。

InkManagerクラスのProcessPointerUpメソッドで、ポインターの位置と圧力の傾きを処理します。このメソッドは ProcessPointerUpdateメソッドを呼び出した後で呼び出す必要があります。

入力ポインターの一意の識別子を取得していたメンバー変数myPenIDを0で初期化します。

  Private Sub myCanvas_PointerReleased(sender As Object, e As PointerRoutedEventArgs)
    If e.Pointer.PointerId = myPenID Then
      Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
      myInkManager.ProcessPointerUp(myPointer)
    End If
    myPenID = 0
    e.Handled = True
  End Sub
  • もじのれんしゅうアプリのサンプル

    『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第7回のサンプルプログラムです。
薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています