あまつぶ

7.7 【アイコンとエイリアス】

 連勝は4でストップ。ま、これからこれから。
 そういえばオールスターのファン投票はもう締め切られたそうな。投票しようと思っていたんだけど忘れてた(汗)。なんでもインターネットで投票できたらしいのだけど……。

 アイコンの取得について。8.5からはIconServicesライブラリがシステムに追加されたから簡単にアイコンを取得することができるのだが、それ以前のバージョンではそう簡単にはいかない。AppleEventでFinderに問い合わせるか、あるいはファイルについてはカスタムアイコンがあればそれを、なければデスクトップデータベースから検索、フォルダについてもカスタムアイコンをチェックして、なければそのフォルダがなにかを調べて……という感じになるのかな。
 AppleEventで問い合わせるのもそれほど簡単ではないけど、ファイルであるかフォルダであるか……とか考えずに素直に進んでいけばいいから流れ自体は簡単だ。が、スピードが遅い。また、呼び出すとまずいタイミングがある。逆に地道に自分で調べる方法では、スピードは速い反面、場合わけが多いから大変だ。一度作ってしまえばあとはたいしたことはないのだが。
 Phutでは、最初は8.5以降で動作可能でもいいかなと思っていたから迷わずIconServicesを使用していたのだが、せめて7.5以降で……と、AppleEventでアイコンを得るルーチンを追加した。が、Finderからファイルをドロップして追加……のタイミングにAppleEventを送信しようとするとシステムエラーが起こってしまうようなのだ。'open'イベントなどのイベントは送信可能だから、replyのあるイベントはだめということなのかもしれない。あるいは、アイコンの問い合わせがだめという可能性もあるが。
 そうすると、ドロップされたときはとりあえず保留しておいてあとでアイコンを取得するようにするか、地道な方法でアイコンを調べるかのどちらかの方法をとることになる。IconPartyでは、AppleEventを使わずに地道にアイコンを調べるルーチンを使っているから、そこから「ドロップされたとき用」として流用すればなんとかなるかもしれない。フォルダについては「カスタムアイコンがなければデフォルトのアイコン」にしていたのを、システムフォルダかどうかだとかチェックするルーチンを用意すればなんとかなりそうだ。フォルダチェックルーチンは、例えば、

OSErr	err;
short	vRefNum;
long	dirID,folderID;
Boolean	isDirectory;

err=FSpGetDirectoryID(theFolder,&folderID,&isDirectory);
/* システムフォルダ */
err=FindFolder(theFolder->vRefNum,kSystemFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kSystemFolderIconResource;
/* デスクトップフォルダ */
err=FindFolder(theFolder->vRefNum,kDesktopFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kDesktopIconResource;
/* ごみ箱 */
err=FindFolder(theFolder->vRefNum,kTrashFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kTrashIconResource;
/* プリントモニタ */
err=FindFolder(theFolder->vRefNum,kPrintMonitorDocsFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kPrintMonitorFolderIconResource;
/* 起動項目 */
err=FindFolder(theFolder->vRefNum,kStartupFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kStartupFolderIconResource;
/* 終了項目 */
err=FindFolder(theFolder->vRefNum,kShutdownFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kStartupFolderIconResource;
/* アップルメニュー */
err=FindFolder(theFolder->vRefNum,kAppleMenuFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kAppleMenuFolderIconResource;
/* コントロールパネル */
err=FindFolder(theFolder->vRefNum,kControlPanelFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kControlPanelFolderIconResource;
/* 機能拡張 */
err=FindFolder(theFolder->vRefNum,kExtensionFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kExtensionsFolderIconResource;
/* フォント */
err=FindFolder(theFolder->vRefNum,kFontsFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kFontsFolderIconResource;
/* 初期設定 */
err=FindFolder(theFolder->vRefNum,kPreferencesFolderType,true,&vRefNum,&dirID);
if (dirID == folderID) return kPreferencesFolderIconResource;

return kGenericFolderIconResource;


こんな感じか。補足。theFolderに調べたいフォルダのFSSpecへのポインタが入っていて、アイコンIDを返す。FSpGetDirectoryID()は、MoreFilesのルーチン。これを使ってディレクトリIDを調べ、FindFolderで得たものと比較を繰り返してアイコンのIDを得る。ん〜、地道だ……(笑)。あとは、指定フォルダがボリューム自体の場合はフロッピーのアイコンだとかハードディスクのアイコンだとかを取得してやらないといけないのだけど、、それはまあ保留。なにかカスタムアイコンをつけてくれていることを期待しよう(おいおい)。

 こんな地道なルーチンを書いていると、ふと、「エイリアスも同じやん」という気がしてくる。このルーチンをほぼそのままコピーして、返り値をエイリアスのファイルタイプにしてやればそれですむんじゃないか……。そんなわけで、次はエイリアス作成ルーチンを書く予定。本当は、それこそFinderにAppleEventを送って……がベストなのだけど、「make new alias file at ... to ...」っていうのがどのバージョンのFinderから使用可能なのかよくわからなくて……(汗)。

to July 6, 1999 ↑ to July index → to July 8, 1999