前回のBrowsing Mac OS Xの“Carbonアプリケーションでロングファイルネームに対応するには”で、Mac OS Xで動かすCarbonアプリケーションでのロングファイル名に非対応となる可能性を説明した。これまでに使われていたファイルを参照する構造体FSSpecはとりあえずはうまく動くのだが、31バイトに切り詰めたファイル名で処理を行う。ロングファイルネームをきちんと管理するにはFSRefという構造体を使うのが基本になる。なお、リソースフォームのやりとりをFSRefベースでできないということを書いたが、実際にはできるようなで、別掲の訂正記事を参照してもらいたい。
では、Carbonベースのアプリケーションで、FSSpecをシステムから取得していた部分について、それをFSRef化することを考えよう。一般的なアプリケーションでは、「ファイル」メニューの「開く」や「保存」を選択してNavigation Servicesのダイアログボックスを表示し、そこからユーザが指定したファイルのFSSpecを得ているだろう。まず、これが代表的な1つのケースだろう。もう1つは、AppleEventのOpenDocumentsで、システム側から開くファイルを伝達された場合に、どのファイルを開くのかをFSSpecで得ているという場合がある。これらは多くのファイルに組み込んでいるところだと思うが、前にも説明したように、今まで通りFSSpecベースでプログラムを組んでいても、とりあえずは動く。File Managerの各機能は、FSSpecで動作するように互換性があるからだ。しかしながら、そこで取得されるファイル名は、31バイトを超えるとFinderで見えるファイル名と違って切り詰められたものなのである。Mac OS 9までだとFinderで見えるファイル名とFSSpec構造体のファイル名は同一だったが、Mac OS Xでは違ってしまうと言う弊害が出ると言う次第だ。 ここで、Navigation ServicesとAppleEventと場面は違うのだが、プログラム的には同一であることは、実際にアプリケーションを組んだことがある方はよく御存じだろう。いずれも、AppleEventのディスクリプタリストとして得られたデータから、FSSpec構造体と指定してデータを取り出す。一般にはAEGetNthPtrというAPIコールを使うことが多いだろうが、その3番目のデータに、取り出すデータのタイプを指定する。以前まではここにtypeFSSという定数を指定していたが、そのかわりにFSRefを要求する定数typeFSRefを指定しなおせばいい。もちろん、取り出す構造体はFSSpec型ではなくFSRef型構造体に変更し、さらには取り出すデータのサイズもsizeof(FSSpec)ではなくsizeof(FSRef)にするなどの変更も必要である。 いずれにしても、ディスクリプタのリストから、FSRef型でデータを抜き出しさえすれば、指定したファイルのFSRef型構造体のデータが得られるというわけだ。おそらくシステムの内部で、ファイル参照の2種類の構造体間のタイプ変換機能が組み込まれているため、プログラムではどちらでも指定できるようになっているのだと考えられる。従って、プログラムのフロントエンドの部分は、変数の定義の変更等も必要ではあるが、大きく変更する必要はないのである。むしろ、大きく変更する必要があるのは、実際のファイル処理の部分となるが、それは次回に説明しよう。
なお、FSSpecのままで処理をした場合にどのようになるかは、StuffIt DeluxなどのStuffItシリーズで問題となる動作であることは前回紹介した。また、問題とはならないにしてもMac OS X 10.0に付属するInternet Explorer 5.1でもその影響が見られる。ファイル名でも、あるいはそのフルパス中にあるフォルダでもいいので、31バイトを超える場合のファイルを、IEにドラッグ&ドロップして開いてみよう。すると、アドレス欄にはFinderで見える名前のパス名ではなく、31バイトに切り詰めたファイル名のパスが得られる。おそらく、FSSpec構造体から獲た名前でフルパス名を構築しているのだろう。また、アドレス欄に入れるパスの文字列についても、file:///の場合でもFinderで見える名前のパスではなく31バイトに切り詰めた名前を使ったパスでなければならい。その意味では、きちんとファイルは参照できるのであるが、切り詰めたパス名をユーザに見せてしまう結果になるというわけだ。 |