プログラム・コード(MainWindow.xaml.vb)

では、次にプログラム・コード(MainWindows.xaml.vbファイル)を見ていきましょう。

コードは4回のコードと似通っている部分については割愛します。4回のコード説明を参照してください。異なる部分のみ解説します。

名前空間の読み込み

「Imports Leap」と「Imports System.Windows.Ink」名前空間だけを読み込みます。

クラスの定義

ImageInfoというクラス内に、文字列型の「画像名」プロパティを定義します(リスト2)。

リスト2 ImageInfoクラス

Public Class ImageInfo
  Public Property 画像名 As String
End Class

メンバー変数の宣言

次にメンバー変数を宣言します。

今回もWin32 APIを使用するためにWin32 APIの宣言も行います。4回と同じWin32 APIを使用しています。しかし、定数メンバー変数は、
「Private Const MOUSEEVENTF_LEFTDOWN = &H2」
だけを宣言します。他の定数メンバー変数は不要です。

「leap」、「touchIndicator」、「touchPoint」、「windowWidth」、「windowHeight」、「tx」、「ty」、「FingersCount」等のメンバー変数については4回と同じのため、そちらの記事を参照してください。今回は「x」と「y」のメンバー変数の宣言は不要です。これ以外に、XML要素を表すXElementクラス型のメンバー変数xmldocと、ImageInfoクラス型の新しいリストであるImageListメンバー変数を宣言します(リスト3)。

リスト3 メンバー変数の宣言

・・・・コード略・・・
  Private xmldoc As XElement
  Private ImageList As New List(Of ImageInfo)
・・・コード略・・・・

MainWindow_Loadedメソッドの処理

XML文書を(Photo.xml)を読み込んで、ListBoxに表示し、15pxのタッチ・ポイントを表示するDataShowメソッドを実行します(リスト4)。

リスト4 MainWindow_Loadedメソッド

  Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    DataShow()
  End Sub

DataShowメソッドの処理

XElememt.LoadメソッドでPhoto.xmlファイルを読み込みます。さらにDescendantsメソッドですべての子孫要素「<画像名>」の内容を、変数「result」に格納しながら、以下の処理を行います。

<画像名>要素の値と、文字列“Images/”を連結した文字列値を、ImageInfoクラスの「画像名」プロパティに指定してImageInfoクラスの新規インスタンスを作成し、それをImageListオブジェクトにAddメソッドで追加していきます。

ListBox1のItemsSourceプロパティにImageListオブジェクト指定します。これで、読み込まれた画像がListBox1に表示されます。なお、ListBox1にはWrapPanelのテンプレートを適用しているので、画像は右端で折り返して表示されることになります(リスト5)。

~以下は第4回目と同じ処理の解説になるので割愛します。~
但し、4回目では円の大きさは20pxだったのを、今回は15pxとしています。

リスト5  DataShowメソッドの実装内容(MainWindow.xaml.vb)

Private Sub DataShow()
  Dim xmldoc As XElement = XElement.Load("Photo.xml")
  Dim query = From c In xmldoc.Descendants("画像名") Select c

  Dim myImageInfo As New List(Of ImageInfo)
 
  For Each result In query
    myImageInfo.Add(New ImageInfo With {.画像名 = "Images/" & result.Value})
  Next
  ListBox1.ItemsSource = myImageInfo
・・・・4回と同じのためコード略・・・・
  End Sub

Updateメソッドの処理

4回と同じにつき割愛します、4回を参照してください。

次にLeap Motionのタッチ処理になります。タッチのイメージは次の図8のようなイメージです。

Updateメソッドの処理(ホバー処理)

手前側が「ホバー状態(hovering)」、奥側が「タッチ状態(touching)」を表します。空間の範囲は前後「1」~「-1」となっています。

図8:Leap Motionのタッチ検出イメージ(Leap Motion SDKのAPIドキュメントから引用)(クリックで拡大)

まずホバーの場合は、画面に表示されている指の数をleap.Frame.Fingers.Countプロパティで取得して、メンバー変数「FingersCount」に格納しておきます(リスト6)。

リスト6 ホバー時の処理(MainWindow.xaml.vb)

For Each Pointable As Pointable In leap.Frame.Pointables
  ……コード略(前述)……
  If Pointable.TouchDistance > 0 AndAlso Pointable.TouchZone <> Global.Leap.Pointable.Zone.ZONENONE Then
          touchIndicator.Color = Colors.Blue
          FingersCount = leap.Frame.Fingers.Count ' 表示されている指の本数を取得して、メンバー変数FingersCountに格納しておく
      ……コード略(続きは後述)……
  End If
Next

次にタッチした処理になります。タッチした場合は、表示されている円が赤に変わります。

Updateメソッドの処理(タッチ処理)

指が1本認識されている場合は、SetCursorPos(touchPoint.X, touchPoint.Y)と指定して、タッチ・ポイントとカーソルの位置を同じ位置に表示します。

「apimouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)」
と指定して、マウスの左ボタンを押した処理を行います。

指が5本表示された場合は、ListBoxに再度画像を表示するDataShowメソッドを実行します。

タッチ以外の処理ではタッチ・ポイントの色がGoldになり、何も発生しません。

具体的にはリスト7のコードになります。

リスト7 タッチとタッチ以外の処理(MainWindow.xaml.vb)

If Pointable.TouchDistance > 0 AndAlso Pointable.TouchZone <> Global.Leap.Pointable.Zone.ZONENONE Then
  ……コード略(前述)……
  ElseIf Pointable.TouchDistance <= 0 Then
   touchIndicator.Color = Colors.Red
  If FingersCount = 1 Then
          SetCursorPos(touchPoint.X, touchPoint.Y)
          apimouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) ' タッチした場合の処理
        End If
 
        If FingersCount = 5 Then ' 指を5本表示させてタッチすると、ListBoxに画像が再描画される。
          DataShow()
        End If
        ' タッチ対象外
      Else
        touchIndicator.Color = Colors.Gold
      End If
    Next
  End Sub

※注意
今回紹介したサンプルコードを動かす際には、「LeapCSharp.NET4.0.dll」や「LeapCSharp.dll」、「Leap.dll」を読者自身のフォルダ内にあるDLLファイルに指定し直さなければ動かない可能性があるので、動かない場合は再指定してください。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30