インクルードやライブラリの追加、そして、openリソースをアプリケーションに埋め込むという準備ができれば、実際のソースの変更にとりかかる。Standard File Packageを使っている部分はいくつもあるのだが、まずは、FileメニューのOpenを選択したところから変更してみよう。ソースファイルのDoCommand.cにDoOpenCommandという関数があり、現在は以下のようになっている。標準的な標準ダイアログの利用を行っている。LoadFromFileはベースのソースに定義されいて、指定した文書ファイルをウインドウで開くサブルーチンである。
void DoOpenCommand() { StandardFileReply rep; SFTypeList myType; myType[0] = ’TEXT’; myType[1] = ’PICT’; //シングルクォーテーションは半角で入力して下さい myType[2] = myFileType; //ダイアログの一覧に表示するファイルのタイプを指定 StandardGetFile(0, 3, myType, &rep); //ファイルを開くときの標準ダイアログを表示 if(rep.sfGood) //OKボタンを押したのなら LoadFromFile(&rep.sfFile); //選択したファイルを開く }
まずは、同じような機能をNavigation Serviceで実現してみた(ソースプログラムは別の記事に記載)。これがおそらくいちばんシンプルな形式だと思われる。Standard File Packageとの大きな違いは、複数のファイル選択に対応しなければならないところだが、これはAppleEventのOpenDocumentsのプログラムを知っていれば、難しい手続きではない。DoOpenDocument関数を書き換えた。もともと短いとは言え、全面的に書き換える必要がある。この結果、ダイアログボックスの表示は次のようになった。まだ、この段階では、モーダルダイアログなのである。
◇表示されたNavigation Service対応のダイアログボックス
いちばんのキーになるAPIは、NavChooseFileだ。これは、開くファイルを選択するダイアログボックスを表示する。引数はたくさんあるが、とりあえず、最低限必要とするもの以外はNULLを指定しておいた。最初から2つ目の引数にはダイアログボックスの選択結果を得ることができる。3つ目の引数は表示するダイアログボックスに関する設定をあらかじめ指定しておく。そして、7つ目の引数にダイアログボックスに表示されるファイルのファイルタイプを指定する。
ダイアログボックスで表示されるファイルのファイルタイプを、openリソースから取得している。openリソースをロードすれば、それがそのまま引数に指定することができる。そして、変数のdialogOptions構造体には、ダイアログボックスに関するさまざまな設定を指定する。メンバのlocationには、Point型で場所を指定できるが、{-1,-1}を指定すると画面の中央に表示される。メンバのdialogOptionFlagsにはダイアログボックスの形式を記載する。文字列がいくつか指定できるが、今回の結果のように、タイトルバーがない場合には、タイトルバーは表示されない。ボタンや説明など、どのメンバがどこに表示されたかを実行結果で確認してもらいたい。また、この構造体に指定できる内容と動作については膨大な情報なので、ここではすべてを説明することは行わないので、ドキュメントで確認しておいてもらいたい。なお、NavGetDefaultDialogOptionsというAPIコールを利用すると、ここでのdialogOptions変数に既定の値をまとめて設定することができるので、この後に既定値から変更したいものだけを変えるということも可能だ。
ダイアログボックスを表示後、変数replyのメンバselectionに、AppleEventのディスクリプタのリスト形式で、選択したファイルが記録されている。AECountItemsでファイルの個数が分かり、AEGetNthPtrで選択したファイルへのFSSpec型データが得られる。それをもとに、ファイルを開いてウインドウに表示するLoadFromFileルーチンを呼び出している。AppleEvent処理と同じような感じだ。 ここでは、変数replyはNavDisposeReplyというAPIコールで構造体の破棄が必要になる。構造体のメンバから構造体につながっているなど複雑な構造なので、こうしたAPIを利用して確実にメモリをリリースしたい。replyはローカル変数だから構造体の破棄はいらないかと思うかも知れないが、メンバから構造体をポイントしているので、破棄は必要になる。逆に、ローカル変数に適用しても、問題なく動くAPIのようだ。 Navigation Serviceのドキュメントでは、実際にファイルを開く場合に、自分自身にAppleEventを送付するという手法も紹介されている。レコーダブルである必要があるなら、この手法も検討すると良いだろう。 |