デスクトップのクラウディアさんが声で励ましてくれるプログラムを作る

2013年5月7日(火)
薬師寺 国安

言葉の表示されているリストボックスから言葉が選択された時の処理

wavListBoxの選択されたインデックスの値が0かそれより大きく、且つclaudiaListBoxの選択されたインデックスの値が0かそれより大きい場合、つまり、wavaListBoxから言葉が選択され、且つクラウディアが選択された場合は、[Save]アイコンの使用を可能にします。それ以外は使用不可とします。

  Private Sub wavListBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles wavListBox.SelectionChanged
    If claudiaListBox.SelectedIndex>= 0 AndAlsowavListBox.SelectedIndex>= 0 Then
      saveButton.IsEnabled = True
    Else
      saveButton.IsEnabled = False
    End If
  End Sub

[Save]アイコンがタップされた時の処理

Frameを表示状態にします。メンバ変数claudiaSelectedImageにclaudiaListBoxから選択された項目のインデックスに対応する要素の属性”Large”の値を取得して格納します。

メンバ変数wavSelectedFileにwavListBoxから選択された項目のインデックスに対応する要素の属性”wav”の値を取得して格納します。

Visual Basic の埋め込み式を用いて、ルート要素、その子要素としてを作成し、埋め込み式の構文であるを用いてメンバ変数claudiaSelectedImageの値とwavSelectedFileの値を指定します。これは ASP.NET で使用される構文と同じです。作成したXML文書を変数saveXmlに格納します。

XElemet.Parseメソッドで作成したXMLを文字列として読み込みます。読み込んだ結果XMLを変数resultに格納しておきます。

ピクチャライブラリにアクセスします。
CreateFolderAsyncメソッドでピクチャライブラリ内にclaudiaXMLというサブフォルダを作成します。
CreationCollisionOption.OpenIfExistsを指定すると、既に同名フォルダが存在する場合は、そのフォルダ名を返し、ない場合は新規に作成されます。
また、CreateFileAsyncメソッドでピクチャライブラリのclaudiaXMLサブフォルダ内にclaudiaInfo.xmlというファイルを作成します。
CreationCollisionOption.ReplaceExistingと指定し、既に同名のファイルがある場合は上書きします。

OpenAsyncメソッドで作成したclaudiaInfo.xmlを「読み取り/書き込み」モードで開き、入出力データへの、ランダムアクセスをサポートするIRandomAccessStreamインターフェース型のmyStreamで参照します。

データを出力ストリームに書き込む、新しいDataWriterのインスタンスをmyStreamで初期化し、writerオブジェクトを作成します。
出力ストリームのUnicode文字エンコードを設定する、UnicodeEncodingプロパティにUtf8を指定します。
Writeメソッドで出力ストリームにresult変数の値を書き込みます。
StoreAsyncメソッドでバッキングストアにバッファーのデータをコミットします。
[Folder]アイコンの使用を可能にし、ClaudiaShowPageに遷移します。引数には何も持たせません。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。

  Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
    claudiaSelectedImage = xmldoc.Descendants("Item")(claudiaListBox.SelectedIndex).Attribute("Large").Value
    wavSelectedFile = wavXmldoc.Descendants("Item")(wavListBox.SelectedIndex).Attribute("wav").Value
    
    Dim saveXml As XElement = <Claudia><Image><%= claudiaSelectedImage %></Image><Wav><%= wavSelectedFile %></Wav></Claudia>
    Dim saveXmldoc As XElement = XElement.Parse(saveXml.ToString)
    Dim result As String = saveXmldoc.ToString
    Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
    Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("claudiaXML", CreationCollisionOption.OpenIfExists)
    Dim myXmlFile As StorageFile = Await mySubFolder.CreateFileAsync("claudiaInfo.xml", CreationCollisionOption.ReplaceExisting)
 
    Using myStream As IRandomAccessStream = Await myXmlFile.OpenAsync(FileAccessMode.ReadWrite)
      Dim writer As DataWriter = New DataWriter(myStream)
      writer.UnicodeEncoding = UnicodeEncoding.Utf8
      writer.WriteString(result)
      Await writer.StoreAsync
    End Using
 
    openButton.IsEnabled = True
    myFrame.Navigate(GetType(ClaudiaShowPage), Nothing)
  End Sub

戻る(←)アイコンがタップされた時の処理

Frameを非表示にします。

  Private Sub backButton_Click(sender As Object, e As RoutedEventArgs) Handles backButton.Click
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed
  End Sub

[Folder]アイコンがタップされた時の処理

Frameを表示して、ClaudiaShowPageに遷移します。

  Private Sub openButton_Click(sender As Object, e As RoutedEventArgs) Handles openButton.Click
    myFrame.Visibility = Windows.UI.Xaml.Visibility.Visible
    myFrame.Navigate(GetType(ClaudiaShowPage), Nothing)
  End Sub
End Class

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

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

リスト5 (ClaudiaShowPage.xaml.vb)

Option Strict On
Imports Windows.Storage
Imports Windows.Storage.Streams

Public NotInheritable Class ClaudiaShowPage
  Inherits Page

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

ピクチャライブラリにアクセスします。CreateFolderAsyncメソッドでピクチャライブラリ内にclaudiaXMLというサブフォルダを作成します。
CreationCollisionOption.OpenIfExistsを指定すると、既に同名フォルダが存在する場合は、そのフォルダ名を返し、存在しない場合は新規に作成されます。

GetFileAsyncメソッドでclaudiaXMLサブフォルダ内のclaudiaInfo.xmlを取得します。
OpenAsyncメソッドでclaudiaInfo.xmlを「読み取り」モードで開き、入出力データへの、ランダムアクセスをサポートするIRandomAccessStreamインターフェース型のmyStreamで参照します。
読み込んだXMLファイルと文字コードで初期化された新しいStreamReaderクラスのインスタンスreaderオブジェクトを作成します。
ReadToEndeメソッドでXML文書を末尾まで読み込み変数resultに格納します。

XElement.Parseメソッドで変数resultの値を文字列として読み込みます。
ClaudiaImageのSourceプロパティに画像を配置しているms-appx:///Images/フォルダと、要素の値を連結して指定します。これで、クラウディアの画像が表示されます。

MediaElementのSourceプロパティに音声ファイルを配置しているms-appx:///WAV/フォルダと要素の値を連結して指定します。選択されていた言葉が喋られます。

非同期処理で行われるためメソッドの先頭にAsyncを追加します。

  Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    Dim result As String
    Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary
    Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("claudiaXML", CreationCollisionOption.OpenIfExists)
    Dim myFile = Await mySubFolder.GetFileAsync("claudiaInfo.xml")
    Using myStream As IRandomAccessStream = Await myFile.OpenAsync(FileAccessMode.Read)
      Using reader As StreamReader = New StreamReader(myStream.AsStream, System.Text.Encoding.UTF8)
        result = reader.ReadToEnd
      End Using
    End Using
    Dim doc As XElement = XElement.Parse(result)
    ClaudiaImage.Source = New BitmapImage(New Uri("ms-appx:///Images/" &doc.Descendants("Image").Value))
    MediaElement1.Source = New Uri("ms-appx:///WAV/" &doc.Descendants("Wav").Value)
  End Sub

[Play]アイコンがタップされた時の処理

再生を開始し、[Play]アイコンを使用不可にして[Stop]アイコンの使用を可能にします。

  Private Sub playButton_Click(sender As Object, e As RoutedEventArgs) Handles playButton.Click
    MediaElement1.Play()
    playButton.IsEnabled = False
    stopButton.IsEnabled = True
  End Sub

[Stop]アイコンがタップされた時の処理

再生を停止し、[Stop]アイコンを使用不可にして[Play]アイコンの使用を可能にします。

  Private Sub stopButton_Click(sender As Object, e As RoutedEventArgs) Handles stopButton.Click
    MediaElement1.Stop()
    stopButton.IsEnabled = False
    playButton.IsEnabled = True
  End Sub
End Class

今回はここまでです。ありがとうございました。

筆者からのお知らせ

筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。

  • クラウディアのプログラムサンプル

薬師寺国安事務所

薬師寺国安事務所代表。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メルマガ会員のサービス内容を見る

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