あまつぶ

2.18 1:00 【続ResEditに託す】

 前回の補足。GetWMgrPortなどのプロトタイプは<MacWindows.h>にある。それから描画する前にクリップリージョンを変更してやらないといけない場合があるようだ。まず現在のクリップリージョンを保持しておいて表示したい範囲を設定、最後に元に戻すという形かな。

 ResEditの起動の続き。要は「アプリケーションを起動する」必要があるんだから、AppleEventに頼るんじゃなくてプロセスマネージャを使えばいいのか。LaunchApplicationというのがあるのは知っていたけどファイルを開くという指定ができるというのは知らなかった。この方法ならとりあえずKT7以降であればちゃんと動くはずだし。
 そんなわけで今回はその方法についてちょっと。まずIMのProcess Managerを読んで概要を理解したあとAppleのサイトからサンプルコードをダウンロードしてくればok。Snippetsの中からLaunchWithDoc2というサンプルがそれだ。LaunchWithDocってのもあるが、2の方はアプリケーションがすでに起動している場合を考慮してあるから、なんというか上位互換って感じかな(笑)。
 単にアプリケーションを起動させるだけならLaunchApplicationの使い方がわかればいいだけなんだけど、ファイルを開いてもらおうと思ったら自分で'odoc'イベントを作ってそれを変換してLaunchApplicationに渡してやる必要があるらしい。IMでは細かい方法が書かれていなかったのでどうやればいいのかわからなかったが、要はすでに起動している場合と同じようにAppleEventを作ってそれをAECoerceDescでtypeAppParameters(='appa')タイプのデスクリプタに変換、あとはそのデータ部分をキャストして渡してやればいいんだそうな。
 そうとわかればさっそくやってみるべし。すでに起動している場合でも起動していない場合でも'odoc'イベントを作ってやらないといけないからこれを共有するためにまず'odoc'イベントを作成するルーチンを別にわけた(サンプルコードでもそうなっている)。たいしたコードではないが、一応掲載。

/* 'odoc'イベントを作る */
OSErr MakeOpenDocumentEvent(ProcessSerialNumber *targetPSN,
		FSSpec *theIconFile,AppleEvent *odocEvent)
{
	OSErr		err;
	AppleEvent	aeEvent={typeNull,NULL};
	AEDesc		target={typeNull,NULL};
	AEDescList	fileList={typeNull,NULL};
	AliasHandle	fileAlias=NULL;
	
	/* ターゲットアプリケーションのデスクリプタを作成 */
	err=AECreateDesc(typeProcessSerialNumber,targetPSN,
				sizeof(ProcessSerialNumber),&target);
	
	/* AppleEventを作成 */
	err=AECreateAppleEvent(kCoreEventClass,kAEOpenDocuments,&target,
				kAutoGenerateReturnID,kAnyTransactionID,&aeEvent);
	
	/* 開くファイルのリストを作成 */
	err=AECreateList(nil,0,false,&fileList);
	
	/* リストにファイルを追加 */
	err=NewAlias(NULL,theIconFile,&fileAlias);
	if (err==noErr)
	{
		HLock((Handle)fileAlias);
		err=AEPutPtr(&fileList,1,typeAlias,(Ptr)*fileAlias,
				(*fileAlias)->aliasSize);
		HUnlock((Handle)fileAlias);
		DisposeHandle((Handle)fileAlias);
	}
	
	/* 作成したファイルリストをAppleEventのkeyDirectObjectパラメータに設定 */
	err=AEPutParamDesc(&aeEvent,keyDirectObject,&fileList);
	
	/* できたイベントを返す */
	*odocEvent=aeEvent;
	
	/* 作成したデスクリプタを破棄 */
	err=AEDisposeDesc(&target);
	err=AEDisposeDesc(&fileList);
	
	return err;
}


 AppleEventについては解説できるほど詳しくないので省略(苦笑)。AppleEventのことを詳しく知りたかったら「Macintosh プロフェッショナルプログラミング」って本がおすすめかな。例によってあまり新しい本ではないので最近ではもっといい本が出ているのかも知れないけど。ま、要は自分が'odoc'イベントを処理する時の逆をしてやればいいだけだからやっていることはなんとなくわかるんじゃないかと思う。
 基本的には、「ターゲットアプリケーションのデスクリプタ作成」「Appleイベントを作成」「作成したAppleEventにパラメータを設定」という流れになる。最初の2つはどんなイベントでも同じことだが(イベントクラスなんかは当然ながら違うが)、パラメータについてはイベントごとにまちまちだ。'odoc'イベントでは開くファイルのリストが必要で、それを「keyDirectObject(='----')」パラメータに設定してやる必要がある。
 ファイルリストのデスクリプタは、まずリストを作ってからそれぞれのファイルのエイリアスレコードを作ってAEPutPtrで追加していくという流れになる。タイプが定義されているものについてはこれを使えば勝手に変換してくれるから細かいことは考えなくてもいい。エイリアスレコードからデスクリプタを作成してAEPutDescで追加する方法もあるが(サンプルコードではそうしている)、この場合はAEPutPtrを使う方が楽だ。
 'odoc'イベントではパラメータを1つしか使わないのでパラメータの設定が終わればもうやることはない。アプリケーションに直接送る場合ならこれでできたイベントをAESendで送ってやるだけ。起動していない場合はLaunchApplicationを使うんだけど、、その方法については次回かな。

 他のイベントを送りたい場合も基本的には同じことなんだけどどのデータをどのパラメータに設定するのかというのを知らないとどうにもならない。Apple Event RegistryというドキュメントにRequired Suite、Core Suiteなどについて解説が書かれているのだが、、入手先どこだっけ……。Appleのどっかにあるはず(^^;; そういえば、このドキュメントはApple DocViewer形式のファイルになっているのだけど最近のOS(か、マシンか?)では正しく開くことができない場合があるみたい。一度古いOSで開いてやるといけるみたいなんだけど、なぜだろうなー。うちに開けるようにするパッチが作ってあるので、もし開くことができなくて困っている方がいたら言ってください(笑)。(※ 02.12.7追記:DocViewerで開くことができない件について、原因がStuffIt Expanderにあるのか元のアーカイブにあるのか不明だが、MindExpanderで解凍するとうまくいくようだ。もしこの問題が起こった場合は、一度試してみるといいと思う)
 これを入手したらやはり読んでおきたいのはFinder Suiteかな。ここを読めばFinderに「ファイルをコピーしてくれ」だとか「ごみ箱を空にして」なんて頼むことができるようになる。AppleScriptでFinderを操作するのも楽しいけど自分で作ったアプリケーションでFinderに指令を与えるというのもなかなか面白い。ただ、ドキュメントがちょっと古いので最近追加されたイベントについては書いていないのが難点だけど、載ってないものは今回の場合みたいに「以前のバージョンでは動かない」という可能性があるから考えて使わないといけないな。

to February 17, 1999 ↑ to February index → to February 19, 1999