タイトル【小池邦人のプログラミング日記】2000/1/5<Carbon Event Managerを使う その2>カテゴリーCarbon/CF, 小池邦人のプログラミング日記
作成日2001/1/5 12:44:35作成者小池邦人
やっとこさ「CarbonLib 1.2 SDK」のGM版が、以下のサイトから一般ユーザでもダウンロードできるようになりました。ただし、それに含まれているUniversal Interfacesは、いまだv3.4b3というβバージョンです(涙)。

◇Development Kits
 http://developer.apple.com/sdk/

 

SDKの出来具合(?)は別の機会に調べてみるとして、今回は「CarbonLib 1.2 SDK」に添付されている「BasicCarbEvents」サンプルで、Carbon Event Managerがどのように使われているのかを詳しく調べてみます。2001年1月4日現在、ADCメンバーサイトに登録されているUniversal Interfacesの最新バージョンも、やはりv3.4b3です。このバージョンで、前回お話した「Carbon.r」のバグは取れているようです。Metrowerks CodeWarrior 6用のPreCompiled Headerを使用されている方は、この最新バージョンをダウンロードして、作り直されることをお薦めします。

まずは、オリジナルのプロジェクトである「BasicCarbEvents.mcp」を起動させてみましょう。

 

「Libraries Group」に登録されている「CarbonLib」はv1.2のStubライブラリを、「MSL RuntimePPC.Lib」はCodeWarrior 6の最新Runtimeライブラリをリンクしてください。リンク用の「Access Paths」はSettingダイアログで調整します。また「MSL C.PPC.Lib」もCarbon対応の「MSL C.Carbon.Lib」に差し替えます。(今回はリンクしなくても大丈夫のようです)それから「CarbonHeaders.pch」は外してしまい、代わりにSettingダイアログの「C/C++Language」に記述されている「CarbonHeaders.h」を、事前に準備しておいたPreCompiled Headerの「CarbonHeadersPCH」に変更するとリンク時間が短縮できます。

 

これでプロジェクトの準備はOK、メイクすると問題なくサンプルアプリが作成されることが確認できました。

このサンプルアプリケーションのソースファイルは、BasicCarbEvents.cひとつだけです。アプリケーションの動作内容は、ウィンドウをひとつオープンし、そこに36ポイントのフォントサイズで「Hello World!」と描画する簡単なものです。メニューで機能するのはFileメニューの「Quit」だけ、コメント文を除けば100行程度の短いソースコードとなっています。まずはmain()を見てみると、InstallStandardMenuBar()でメニューを作成し、AEInstallEventHandler()でQuit(作業終了)用のApple Event Handlerを登録しています。

続いてCreateNewWindow()でウィンドウを作成するのですが、その時にウィンドウのアトリビュートに、kWindowStandardHandlerAttributeフラグを加えている点に注目してください。

 

Carbon Eventでは、各オブジェクト(ウィンドウやコントロールやメニュー)に対しEvent Handlerルーチンを用意しないと、「Standard Handler」と呼ばれるディフォルト処理が実行されます。例えば、ウィンドウのタイトルバーをドラッグしてデスクトップ上を移動させるといった処理は、わざわざEvent Handlerルーチンに記載しなくても実行されるわけです。CreateNewWindow()のWindowAttributes引数にセットしているkWindowStandardHandlerAttributeは、そのStandard Handlerを有効にするオプションです。このアトリビュートを設定しないと、ウィンドウに対するディフォルト処理は実行されませんので注意してください。

次はInstallWindowEventHandler()により、ウィンドウに対応するEvent Handlerを登録します。このサンプルでは利用していませんが、アプリケーションに対応するEvent Handlerルーチンの登録にはInstallApplicationEventHandler()を、コントロールにはInstallControlEventHandler()を、メニューにはInstallMenuEventHandler()を、それぞれ利用します。

 

オブジェクトの種類だけではなく、個々のオブジェクトに対してEvent Handlerが登録できるところが、Apple Eventとは異なる重要なポイントです。InstallWindowEventHandler()の最初の引数は、対応するウィンドウのWindowRefを、2番目にはEvent Handlerルーチン名(EventHandlerUPP)を渡します。このサンプルでは、作成したウィンドウに対し登録されているEvent Handlerルーチンは1種類だけです。

続いてEvent Handlerルーチンが対応できるEventの個数とその種類を渡します。種類を明記するEventTypeSpec構造体には「eventClass」と「eventKind」をペアで表記し、それの配列として渡します。今回、配列に記載されているeventClassは、すべてkEventClassWindowとなります。また、eventKindの方は、kEventWindowClose、kEventWindowDrawContent、kEventWindowBoundsChangedの3種類が記載されています。対応する処理を調べると、kEventWindowCloseはウィンドウでClose Boxがマウスクリックされた場合に、kEventWindowDrawContentはウィンドウのアップデートで内部の再描画が必要になった場合に、kEventWindowBoundsChangedはウィンドウのリサイズや移動が起こった場合に発生していることが分かります。

ウィンドウに対応するEvent Handlerの登録が終了したら、ShowWindow()でウィンドウを表示し、その直後にRunApplicationEventLoop()を実行します。Carbon Eventの基本は、今までWaitNextEvent()を使いメインイベントループを実行していた処理を、RunApplicationEventLoop()に置き換えることです。そうすると、後はCarbon Event Manageがイベント発生を管理し、必要に応じて適切なEvent Handlerルーチンに処理を渡してくれます。ここでは、ウィンドウをオープンしたことで、一番最初にeventClassがkEventClassWindowで、eventKindがkEventWindowDrawContentのイベントが発生します。それを受け取ったEvent Handlerルーチン(MyWindowEventHandler)は、HandleWindowUpdate()を呼んでウィンドウ上に「Hello World!」を描画するわけです。また、アプリを終了させる時には、QuitApplicationEventLoop()を呼ぶことも忘れないでください。

次回は、ウィンドウに対応させたHandleルーチンの挙動と、Fileメニューで「Quit」が選択された時のCarbon Event Managerの対応を詳しく調べてみることにします。
[小池邦人/オッティモ]
関連リンクオッティモ