タイトル【小池邦人のプログラミング日記】2000/8/18<Mac OS Xへの道 Carbon対応の実際(5)>カテゴリーCarbon/CF, 小池邦人のプログラミング日記
作成日2000/8/18 16:41:18作成者小池邦人
既存のソースコードをCarbon APIに対応させ、Mac OS X環境でも起動できるアプリを作るための工程のうち、今回は(7)のMac OS Xメニューモデルへの変更について解説します。

(7)Mac OS Xメニューモデルへの変更

Mac OS X環境ではファイルメニューの一番下から「Quit」(アプリケーション終了)のアイテムが外されてしまいました。多分、アプリ終了はファイル処理とは関係ない項目であると言うAppleの判断からだと思います。Mac OS Xでは、Quitはアプリケーションメニュー(以前にAppleメニューがあった場所)の一番下へ移る予定です。それに伴い、ユーザからの終了指示を受ける処理はMac OS X側の仕事となり、そのメッセージはAppleEvent(ハイレベルイベント)として対象アプリケーションへ配信されます。ですから、アプリケーション側がkAEQuitApplicationタイプのAppleEventに対応していないと、Mac OS Xではメニューからアプリケーションを終了することができなくなってしまいます。

Mac OSから送られてくるAppleEventに対応するには、イベントループへ入る前にAppleEvent Handlerを登録しておく必要があります。こう書くと、なんだか難しそうですが、要は以下のようにkAEQuitApplicationタイプのAppleEventを処理するルーチン(イベントハンドラ)を作り、AEInstallEventHandler()で登録するだけです。下の例の終了処理ルーチンはExitToShell()を実行するだけの簡単な処理ですが、一般的なアプリケーションの場合には、編集済みドキュメントの保存をユーザに尋ねる処理(アラートダイアログ表示する)や、変更されたアプリケーションの初期設定を保存する処理などがここに追加されるはずです。

void setUpHiEvent(void)
{
  AEEventHandlerUPP qtptr;

  qtptr=NewAEEventHandlerUPP( (AEEventHandlerProcPtr)hiQuitApp );
  AEInstallEventHandler( kCoreEventClass,kAEQuitApplication,qtptr,0L,0 );
}

pascal OSErr hiQuitApp(AppleEvent *event, AppleEvent *reply, long refcon)
{
  ExitToShell();
}

構築するファイルメニューは、最初から「Quit」(終了)を外しておけばよいかと言うと、そうではありません。なぜなら、CarbonLib対応のアプリケーションはMac OS 8/9でも起動されるかもしれないからです。Mac OS 8/9では、今まで通りQuitがあるファイルメニューが必要です。よって、ファイルメニューに関してのみ‘MENU’(メニュー)リソースを2種類用意します。例えば「終了」項目を持っているID=129のファイルメニューと、持っていないID=131のメニューを作ります。
 
この時注意することは、どちらの‘MENU’リソースの「Menu ID」も同じ値(例の場合には129)にしておくことです。
 
これにより、アプリケーションは2種類のメニュー分岐ルーチンを用意する必要がなくなります。そして同様に、それぞれのファイルメニューをレイアウトした‘BMAR’(メニューバー)リソースも2種類用意しておきます。
 

用意した2つの‘BMAR’リソースをGetNewMBar()で呼び出し、SetMenuBar()によりメニューバーを構築します。この時、アプリケーションがMac OS X環境で起動されているか? そうでないのか? を、Gestalt()によりチェックします。Gestalt()の第一引数にgestaltMenuMgrAttrを与え、帰ってきた値のgestaltMenuMgrAquaLayoutMaskがオンならば、アプリケーションはMac OS X環境で起動していると判断されます。ただし、この仕様は現在のMac OS X DP4上でのことで、今後変更があるかもしれないことを気にとめて置いてください。やっぱりAppleメニューは残してほしいとか、ファイルメニューにもQuitが欲しいというユーザの要望が大きくなると、今後変更されるかもしれませんので...(笑)

void setUpMenu(void)
{
  long  ret=0;
  Handle hd;

  Gestalt( gestaltMenuMgrAttr,&ret );
  if( ret & gestaltMenuMgrAquaLayoutMask )
    hd=GetNewMBar( 129 );
  else
    hd=GetNewMBar( 128 );
  SetMenuBar( hd );
  DrawMenuBar();
}

今までなら、AppendResMenu()で‘DRVR’ リソース名をアイテムに追加することで、Appleメニューの起動アイテム一覧を自分自身で作成する必要がありました。Carbon環境では、この処理もMac OS側が行うようになりました。よって、Mac OS 8/9環境でも、CarbonLibを用いたアプリケーションの場合には、Appleメニューアイテムを構築する必要はありません。これを行ってしまうと、起動アイテムがダブルで表示されてしまいますので注意してください。また、以前ならOpenDeskAcc()で実行していたAppleメニューアイテム(例えばセレクターとかスクラップブック)の起動も、Mac OS側が自動で行うように変更されています。ただし、Appleメニューの一番上のアイテムである「About」に関しては、今まで通り自分で処理する必要があります。

次回は(8)以降の工程についてお話しする予定です。新しいイベントモデルへの変更点やMac OS Xに対する最適化に関する解説です。
関連リンクオッティモ