さて、ちょっと間が開いてしまいましたが、お気楽極楽プログラミング、新しいアプリを作ってみます。
今回はちょっとアプリといえないかもしれませんが、大事な要素をいくつか押さえたいと思います。今回の目的は以下のとおりです。
- ファイルを開くダイアログの使い方
- .NET では出来ないこと
- ちゃんとアプリっぽくするには
- ListBox の使い方
今回のアプリ
今回はサウンドプレイヤーを作ってみたいと思います。といってもGSPlayer に代表されるようなあんなかっこいいものではなくて、WAVファイル限定のものです。もう少しまっとうなアプリについてはいつかやりたいですね。
さて、どんなアプリかというと、[...] ボタンを押すとファイルを開くダイアログが現れ、そこで再生したいWAVファイルを選択します。ファイルを選択したら、[Play] ボタンで音を再生する、といった感じのものです。まずはそこから作ってみましょう。
プロジェクトの作成
まずは、プロジェクトの作成からです。Visual Studio 2005 を起動してプロジェクトを作成します。今回もC#で行きますので注意してくださいね。以下の設定で新規にプロジェクトを作成します。 そうそう、さくせいするときには(1.0) のほうで作成してくださいね。数字無しは2.0 で、Compact Framework 2.0 が必要になってしまいます。PCならともかく、インストールしなければならないものはできる限り減らしたいですからね。
| プロジェクトの種類 |
プロジェクトテンプレート |
プロジェクト名 |
| [Visual C#プロジェクト] |
[スマートデバイスアプリケーション(1.0)] |
SoundPlayer |
画面作成
ツールボックスから Label コントロール、TextBox コントロール, そして Button コントロールを2つフォームに配置します。

配置したコントロールは上の図のようにプロパティを設定します。赤字と緑の文字の部分が変更する内容です。コントロールID を帰るのは(name) のプロパティを変更すればOKです。
| コントロール |
コントロール ID |
プロパティ名 |
設定値 |
| Label |
Label1 |
Text |
"Select Wave File" |
| TextBox |
txtFile |
Font |
"No File" |
| Button |
btnFileOpen |
Text |
"..." |
| Button |
btnPlay |
Text |
"Play" |
「ファイルを開く」ダイアログを使うためのコントロール
また、今回は新しく OpenFileDialog コントロールも配置します。この OpenFileDialog コントロールはフォームに配置しても、表示される、下の図のように画面の欄外にコントロールとして表示されます。前回のラーメンタイマーでのタイマーコントロールと同じですね。

さて、ここで「ファイルを開く」ダイアログの設定をしてしまいます。このダイアログは何度も見たことがあるかとは思いますが、その際には画像ファイルとか、txt ファイルとか、はじめから指定された形で開きますよね?その設定をします。
設定は Filter プロパティで指定します。フィルタは
| フィルタ名(ドロップダウンリストに表示される名前)| *.拡張子; *.拡張子2 .. |
のパターンを繰り返します。最後にはユーザーが自由にファイルを選べるように「| すべてのファイル | *.* 」をつけておくようにしましょう。また、ダイアログを開いたときに、指定したパスを開くように InitialDirectory を設定しておきます。
| コントロール |
コントロール ID |
プロパティ名 |
設定値 |
| OpenFileDialog |
openFileDialog1 |
Filter |
"WAV ファイル | *.wav | すべてのファイル | *.*" |
| InitialDirectory |
"\windows" |
設定画面はこんな感じです。

プログラム 1:ファイルを開く
... ボタンをダブルクリックして、そこにコードを書きます。緑のコメント行はあくまでメモ書きですので、はじめの // 以降はどのように書いてもかまいません。
private void btnFileOpen_Click(object sender, EventArgs e) { // ダイアログを開いたときの戻り値用の変数 DialogResult result; // ダイアログを開いてファイル選択をさせる result = this.openFileDialog1.ShowDialog(); // OKを押したときは処理をする(Cancel のときは処理をしない) if (result == DialogResult.OK) { // テキストボックスに選択したファイル名を入れる this.txtFile.Text = openFileDialog1.FileName; } } |
ここでは何をしているかというと、ファイルを開くダイアログを開いて、そしてユーザーが選択したファイルのファイル名(ファイルのフルパス)を取得して、テキストボックスに書き込む処理をしています。
DialogResult result;
まずはじめの行では、ファイルを開くダイアログの結果を取得するための変数を用意します。ファイルを開くダイアログの結果というのは、たとえば、OKボタンを押したとか、Cancel を押したとか、という結果です。保存する変数ができたら、「ファイルを開く」ダイアログを表示します。2行目の ShowDialog() の関数(メソッド)がそうです。
result = this.openFileDialog1.ShowDialog();
ここの処理はユーザーがファイルを開いて、OKを押すか、Cancel するかしない限り先には進みません。つまりプログラムで次の行は、ダイアログが閉じた後の処理になります。
if (result == DialogResult.OK)
ダイアログが終了したら、まずはユーザーが、ファイルをちゃんと選んでくれたのか、とりあえず Cancel してしまったのか判別します。ユーザーがファイルを選んでOKボタンを押せば DialogResult.OK が、Cancel したなら、DialogResult.Cancel が変数に入っているので、判断します。
this.txtFile.Text = openFileDialog1.FileName;
きちんとファイルを選んでいたら、選ばれたファイルのパス名を取得します。パス名はopenFileDialog1 コントロールの FileName プロパティに格納されているので、そこから結果をいただきます。ファイル名は文字列として格納されているので、特に型の変換は必要ありません。
とりあえずテスト、あら?
まずはテストをして見ましょう。テストの仕方はこれも前回の「【Dev】 お気楽極楽モバイルプログラミング 第4回 「Hello World」 」の実行を参考に。ま、再生ボタンみたいな右向きの▲を押して、エミュレータを選ぶだけです。もちろんActiveSync でつないだWindows Mobile デバイスでテストをしてもOKです。今回は実記を使ってやったほうがいいかもしれません。
画面が表示されたら、... ボタンを押します。すると「ファイルを開く」ダイアログが出てきて、Wave ファイルを選択できるようになっているはずですが、そこには該当ファイルがありません。そもそもなぜかMyDocumentが開いています。これは Windows Mobile の標準ダイアログのせいで、Windows フォルダが開けないようになっています。これは困り者です。
Windows Mobile のファイルダイアログの問題
これは昔から、Windows Mobile で言われていたもので、これを回避するものはいくつかあります。gsGetFile などが有名ですが、これらは、標準のダイアログの代わりに使うものです。この場合はアプリケーション側から gsGetFile があればそちらを使うようにしなければなりません。(この対応方法はいつかやりたいと思っています)
で、一番簡単なのはほーみんさんが作られた FileDialogChanger を使って標準のファイルオープンダイアログをすり替えてしまう方法です。これならばプログラム側で対応する必要がないので、簡単です。
ただし、エミュレーターにこれをインストールするのがちょっと面倒なので、今回は実機でテストをしたほうがいいかもしれません、といったわけです。もしこれも面倒なら、エミュレータのファイルマネージャーを使って Windows フォルダにあるWave ファイルを MyDocument フォルダにいくつかコピーしておきましょう。
気を取り直してもう一度テスト
さてもう一度テストをして見ましょう。アプリケーションを実行して ... ボタンを押してファイルを選びます。そしてOK を押して、ダイアログを閉じれば、テキストボックスにファイルのパスが入っていることがわかります。
ファイルを開くダイアログでは、ドロップダウンリスとボックスで「すべてのファイル」を指定することもできます。
次は
いよいよ、音を鳴らすわけですが、ここで問題があります。というのも .NET Compact Framework には音を鳴らすための機能がないんです!
えー!
ということで続きは次回...