さて、いよいよ SoundPlayer の中核である、音を鳴らす処理を実装します。
が、実は前回も言ったとおり、「 .NET Compact Framework には音を鳴らすための機能がないんです!」さてどうしたものかというと、この場合は、開発者がPocketPC の持つ機能を直接呼場なければなりません。そのためには、Win32 という既存の書式にしたがって呼び出しをします。
一見すると、今のプログラムだって、開発者が直接コードを書いてPocketPC の機能(ファイルを開くダイアログを開くなど)を呼び出しているわけですが、このコードは開発者が簡単に書けるように .NET Compact Framework が提供してくれているものです。.NET Compact Framework なしにWin32 の書式で直接機能を呼び出すとなると、いささか手続きが面倒になります。とはいえ、その機能がないのであれば、そうするしかないのでがんばりましょうね。
尚、このあたりの詳しい話は、【Dev】 お気楽極楽モバイルプログラミングこぼれ話 第1話 「.NET って?」 で書いてありますので、興味があれば読んでみてください。
まずはWin32 宣言用のコード
では、説明よりも実際にコードを書いてみましょう。「Play」ボタンをダブルクリックしてコードを書きます。
[DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)] private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags); private void btnFileOpen_Click(object sender, EventArgs e) { } |
さて、いきなり関数の欄外にコードを書き始めています。音声の鳴らすための、Win32 の関数は PlaySound という関数があり、コレを利用します。この2行はその関数を使うための宣言だと思ってください。
"CoreDll.DLL"
これは、このPlayeSound 関数が実際に入っているDLLライブラリのファイル名です。使う関数によって必ず決まっています。
EntryPoint = "PlaySound"
これは、Win32 の関数の名前ですね。この宣言で PlaySound 関数を使う事をここで宣言しています。1つの関数ごとにこの宣言を1つづつ行わなければなりません。最後の SetLastError = true は特に気にせずこう書くもんだと思ってください。
private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);
ここで、新たに関数を宣言しておきます。WCE_PlaySound という関数を宣言していますが、この関数を呼ぶ事で、結果として Win32 の PlaySound 関数を呼ぶ事になるわけです。このとき、関数の引数 (string szSound, IntPtr hMod, int flags) は Win32 の PlaySound と同じ型で、同じ順で宣言しなければなりません。
次はオプション用のコード
Win32 の PlaySound 関数の3つ目の引数には、オプションのフラグを入れなければなりません。で、オプションのための宣言もしなければなりません。宣言のコードは以下のようになります。コメントは自由に(なしでもかまいません)
[DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)] private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags); private const int SND_ASYNC = 0x0001; // 非同期再生 private const int SND_FILENAME = 0x00020000; // ファイル名で指定 private void btnPlay_Click(object sender, EventArgs e) { } |
今回は、2つのオプションを使うので使うオプションだけを宣言してます。非同期のときのオプションは 0x0001、ファイル名で指定オプションは 0x20000 というのは決まった値ですので変えてはいけません。SND_**** という名前は自由に決められますが、ここは、わかりやすいように Win32 でのオプションの名前とあわせてあります。
で、ようやく音声を鳴らすコード
宣言が終わったので、ようやく音声を鳴らすためのコードを実装します。
[DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)] private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags); private const int SND_ASYNC = 0x0001; // 非同期再生 private const int SND_FILENAME = 0x00020000; // ファイル名で指定 private void btnFileOpen_Click(object sender, EventArgs e) { WCE_PlaySound( this.txtFile.Text, IntPtr.Zero, SND_ASYNC | SND_FILENAME ); }
|
音を鳴らすためには、先ほど宣言した関数 WCE_PlaySound を使います。引数の意味は、
1つ目が鳴らしたい WAVE ファイルのパス名を入れます。前回テキストボックスに入っているファイルのパス名を指定しています。
2つ目は 0 を入れておきます。が、ここの型は IntPtr 型ですので、IntPtr.Zero を入れておきます。訳わからないとは思いますが、そういうものだと思ってください。
3つ目は、この関数を呼ぶときのオプションです。今回は非同期オプションとファイル名指定オプションを指定します。オプションは先ほど宣言した名前を使います。ちなみに非同期オプションを使う事で、音声を鳴らしている間もほかの操作ができるようになります。マイヤヒー♪と鳴っている間何の操作も出来ないのも困ってしまいますからね。
ちょっとまとめてみる
Win32 の関数を使うには、以下の処理を実装しなければなりません。
- まずは使用する関数について調べる
- 使用する関数名を調べる:PlaySound
- 使用する関数が入っているDLL の名前を調べる:CoreLib.DLL
- 使用する関数の引数とその型を調べる:(string szSound, ...
- 必要に応じて使用するオプションとそのコードを調べる:SND_ASYNC = 0x0001
- そして宣言する
- 関数の宣言:[DllImort(" ...
- 必要に応じてオプションの宣言:private const int SND_ASYNC...
- Win32 の関数の作法に合わせて呼び出す
このあたりの処理の準備が.NET Compact Framework の中に入っている事が、お気楽極楽プログラミングの由縁と成ります。実際にコードを書くときも、引数に何を入れていいのか、インテリセンス(コードを書いていると、ピロッ と出てくるおせっかいヘルプです)もお気楽の大事な要素です。
自分が使いたいWin32 コードがわかったら、そのための情報を調べるいはどうしたらいいでしょう。ずばり、ググりましょう。実際には、MSDN Library に書いてあるところから自分で宣言するのですが、はじめは難しいです。ググれば、同じようなコードを書いているものがあると思うので、そこをコピペすれば簡単です。
一番の先生はいいサンプルですよね。
という事でテスト
さて、テストをして見ましょう。実行して、... ボタンを押してファイルを指定します。指定したら、Play ボタンを押して見ましょう。エミュレータでもちゃんと音が鳴るはずです。
次は
今回は、解説ばかりになってしまいました。しかし、これから同様の方法を使って実装するケースはたくさん出てきます。次以降は解説なしとなるのでわからなくなったら、この回を見直してみてください。
さて、次回は、もう少しアプリっぽくしましょう。リストボックスを使ってファイルを登録出来るようにしてみましょう。