タイトル【Carbon化シリーズ】Navigation Serviceでファイル保存ダイアログ(2)カテゴリーCarbon/CF, Carbon化
作成日2000/6/28 0:49:13作成者新居雅行
文書ファイルのウインドウを閉じる時、修正結果を保存していなければ、保存するかどうかをたずねるダイアログボックスが表示される。ボタンが少しだけの簡単なダイアログボックスとは言え、従来のStandard File Packageの枠組みには用意されておらず、自分でダイアログのリソースを定義して作らなければならなかった。TextDrawでは、Alert関数でアラート表示を行うが、ParamTextで表示メッセージにファイル名などのパラメータを渡していいた。しかしながら、Navigation Servicesには、そのダイアログボックスも用意されている。従って、リソースを作ったりしなくても、ダイアログボックスは表示できる。だけども、Navigation Servicesの作法にのっとって作成しないといけないという点では、単なるダイアログボックスの表示よりも面倒と言えば面倒である。
Navigation Servicesの機能を使うと、プログラムにも、リソースにも、メッセージの文字列は含めなくてもよく、結果的にはOSで定義された文字列が表示される。つまり、どのアプリケーションでも同じ文面が表示されるというユーザにとっての均一化が1つのメリットとなる。また、複数の言語のOSで稼動させるアプリケーションの場合、うまくすれば、Navigation Service周りは一切手を加えなくても、稼動している言語にあわせたメッセージあるいはボタン名にもなる。そういったプラス面を見ることにして、保存するかどうかをたずねるダイアログボックスも、Navigation Serviceを利用してみることにする。

TextDraw IVでは、ファイルを保存する時、ファイル名を未指定ならダイアログボックスで指定して保存し、すでにファイル名を指定していればそのまま保存を行うという関数がもう作られている。それをもちろん利用するのであるが、今回の話題としているNavigation Servicesの機能は、ウインドウを閉じる時に利用する。しかしながら、ウインドウを閉じる時と、アプリケーションを閉じる時で、メッセージがやや違う。Navigation Servicesは何とそこまで対応しているので、TextDrawでもしっかり対応してみた。ウインドウを閉じるときには、クローズボックスやあるいはCommand+Wなどのイベントを経て、WindowSet.cというソースのCloseDocWindow関数が呼び出される。さらに、終了するときには、DoCommand.cというソースのDoQuitCommand関数が呼び出される。
DoQuitCommandは、内部的にはCloseDocWindowを呼び出し、その戻り値がfalseの場合には、終了をやめるようにしている。そういうわけで、CloseDocWindow関数では、今現在が終了処理中なのか、あるいはそうでないのかを判別したい。TextDrawでは、たとえば、AppleEventでの終了など多岐に渡るため、終了するかどうかの判断には、Boolean型グローバル変数のFinishを利用できるようにしている。Finish変数の機能を拡大させて、終了する場合だけでなく、終了のプロセスに入った場合にもtrueになるようにした。そのために、DoQuitCommand関数はいくらか書き直した。まずはFinishをtrueとするが、CloseDocWindowsがfalseを戻すと、終了プロセスは中断して、Finish変数の値をfalseにしておくということが行われるようにする。なお、ソースファイルのWindowsSet.cでは、グローバル変数のFinishを使うようには設定されていないので、関数定義の外部で、externで変数定義を追加しておく必要がある。

続いて、CloseDocWindow関数のプログラムを見ていこう。今回のテーマとなっているダイアログボックスを表示するためのNavigation ServicesのAPIコールはNavAskSaveChangesというものだ。いきなりその部分を見てもらいたい。1つ目の引数はおなじみのNavDialogOptions型構造体を指定する。ここで、構造体はやはりNavGetDefaultDialogOptionsで初期化するのであるが、それ以外に必ずやらないといけないのは、構造体のメンバsavedFileNameに、閉じるウインドウの文書ファイル名を指定することだ。ここは既定値だと空文字列になっており、そのままだと、NavAskSaveChangesでダイアログボックスは表示されないのである。
NavAskSaveChangesの2つ目の引数は、NavAskSaveChangesAction型となっているが、要は定義定数を指定する。ここでは、終了プロセス中かどうかによって、ダイアログボックスのメッセージを切り分けるが、終了プロセス中ならkNavSaveChangesQuittingApplicationという引数を指定し、単に1つのウインドウを閉じる時であればkNavSaveChangesClosingDocumentという定義定数を指定するのである。
NavAskSaveChangesの3つ目の引数は、ダイアログボックスでの選択結果を得るためのもので、これはNavAskSaveChangesResult型変数で得るが、これは後から分かるようにやはり定数と比較をするだけだ。通常のダイアログボックスと異なり、細かい情報は必要はなく、ユーザがどのボタンをクリックしたかさえ分かればよいということである。NavAskSaveChangesの4つ目、5つ目は、それぞれイベント処理プロシージャへのポインタと、ユーザデータを指定する。これも、NavGetFileなどと同じである。ここではモーダルダイアログでもいいので、イベント処理プロシージャはNULLにした。
表示されるダイアログボックスを見てみよう。単に閉じる時と終了するときで、メッセージの内容が微妙に違うのが分かる。また、これらのメッセージのうち、プログラムで指定したのは文書ファイル名だけであり、しかもTextDrawでは定数テキストではなく文書情報の構造体から取り出してある。従って、プログラムにも、リソースにも、文字列は1つもないということになる。つまり、必要なメッセージは、Navigation Servicesで自動的に組み立てられたということだ。

◇「テスト1」を閉じようとした時のダイアログボックス


◇アプリケーションを終了しようとした時のダイアログボックス


NavAskSaveChangesの終了後、NavAskSaveChangesResult型変数の値を既定義の定数と比較する。キャンセルボタンをクリックすれば、kNavAskSaveChangesCancelとなっており、保存ボタンをクリックすればkNavAskSaveChangesSaveとなるという具合だ。それに応じて処理は分岐されている。それ以後は、TextDrawのデータ処理のプログラムが続いている。

Navigation Servicesでは他に、編集結果を破棄してファイルに保存された状態に戻す時のNavAskDiscardChanges、保存するかどうかのダイアログボックスをカスタマイズ可能なNavCustomAskSaveChanges、変換して保存した場合の変換の完了を知らせるNavCompleteSaveといった、カスタムダイアログボックスを表示するAPIを用意している。こうしたサポート範囲が広がっていることも頭に入れて、再度プログラムの検討をする必要も出てくるかも知れない。
関連リンクInside Carbon: Navigation Services