タイトル【小池邦人のプログラミング日記】2001/1/31<Carbon Event Managerを使う 最終回>カテゴリーCarbon/CF, 小池邦人のプログラミング日記
作成日2001/2/1 0:36:57作成者新居雅行
今回は、ViewJPEGの画像ウィンドウに対応したEvent Handlerを実装してみます。ウィンドウのクロウズ、移動、リサイズ、ズームといったCarbon Eventに対応したHandlerルーチンを用意することになります。

今回も前回と同様に、Carbon Event Handlerのインストールルーチンを記述することから始めます。ViewJPEGで、画像ウィンドウに対応するHandlerルーチンをインストールしているのは、setUpWindowEvent()です。

 

EventTypeSpecの配列には、インストール用のeventClassとeventKindのペアが列記されています。その数は全部で9種類、そのうち「kEventClassWindow」クラスに属するEventは7種類となります。残り2種類のEventは、それぞれ「kEventClassMouse」と「kEventClassKeyboard」クラスに属しています。この3つのクラスに含まれる全9種類のCarbon Eventを、myWindowEventHandler()ただひとつで処理することになります。InstallApplicationEventHandler()により、EventTypeSpecの配列と一緒にmyWindowEventHandler()をインストールします。ちなみに、CarbonEvent.hを調べてみると、kEventClassWindowクラスには非常に多くのEventが属していることが分かります。

 

当然、これら全部に対応したHandlerをアプリケーション側で用意する必要はありません。必要な物だけをピックアップして対応すればOKです。さっそく、画像ウィンドウ用Event HandlerであるmyWindowEventHandler()の内容を見てみることにしましょう。一番最初にGetEventClass()とGetEventKind()を使い、処理分岐に必要なeventClassとeventKindの両方をEvent情報(EventRef)から得ています。

 

この2つのパラメータを使い、第1レベルでクラス別に処理を分岐させ、さらに第2レベルでEvent種類によって分岐させます。kEventClassWindowクラスでの最初の仕事は、GetEventParameter()によりEventが発生した画像ウィンドウのWindowRef(WindowPtr)を得ることです。すべての処理は、このWindowRefを持つウィンドウに対して実行されます。

 

kEventWindowActivated、kEventWindowDeactivated、kEventWindowClosedの3つのCarbon Eventは、マウス選択によりウィンドウを切り替えた時(旧Activate Event同等)と、Close Boxがクリックされた時に発生します。これらの処理内容は、旧Event Modelの場合とほとんど変わりません。次のkEventWindowDrawContentは、昔で言うところのUpdate Eventに似ており、旧Event Model同様にウィンドウ内容を再描画させる必要があります。kEventClassWindowクラスのEventには、kEventWindowUpdateという種類も存在するのですが、こちらはUpdate Eventとまったく同等となります。ただし、Mac OS XではUpdate Event対応は必要ありませんので、今回はインストールしていません。

次のkEventWindowZoomは、Zoom Boxがマウスクリックされた場合に発生します。IsWindowInStandardState()で、現在のウィンドウの状態がStandardStateかUserStateかをチェックすることにより、ズームインするかズームアウトするかを判断し、ZoomWindowIdeal()を呼んでいます。このCarbon Eventが発生すると、引き続きkEventWindowDrawContentが発生するので、先んじてInvalWindowRect()でウィンドウ全領域の再描画を指示しておきます。最後にウィンドウやスクロールバーのメンテナンスルーチンを呼び出して処理は完了です。続くkEventWindowResizeCompletedは、ウィンドウのリサイズ完了時に発生するCarbon Eventです。その処理内容は、kEventWindowZoomの場合とほとんど同じです。

最後のkEventWindowBoundsChangingは、旧Event Modelには存在しなかったタイプのEventです。このCarbon Eventは、ウィンドウの矩形枠が変化している最中に連続して発生します。Mac OS Xに付属している「Internet Explorer」でウィンドウをリサイズしてみてください。ウィンドウの中身をリアルタイムで再描画しながらリサイズが実行されることが分かります(ライブリサイズ)。kEventWindowBoundsChangingは、こうした機能を実現するために用意されていると思われます。ところが、このCarbon Event、何故だかウィンドウを移動している時にも発生してしまいます。ですから、まずGetEventParameter()にkEventParamAttributesを渡し、ウィンドウサイズが変化しているときだけ処理するように制限しています。続いて、同じくGetEventParameter()にkEventParamCurrentBoundsを渡し、現状ウィンドウ矩形枠を得て、それが画像サイズより大きくならないように調整します。最後に、SetEventParameter()により調整済みの矩形枠を再度セットすることで処理は終了します。ちなみに、この処理を行わないと、Grow Boxをマウスドラッグした時に制限が利かず、画像ウィンドウはどこまでも大きくなってしまいます。

次は、kEventClassMouseクラスです。kEventMouseDownは、どこであろうともマウスクリックが起こった時に発生します。まずはConvertEventRefToEventRecord()を利用して、EventRefを旧Event ModelのEventRecord(eve)へと変換し、そのクリック位置がウィンドウ内の場合だけ、処理ルーチンであるdoContent()へと分岐させます。

 

旧Event Modelをそのまま用いたちょっとズルイ処理方法のようにも見えます(笑)。ウィンドウ内のマウスクリックに関しては、kEventClassWindowクラスにも対応するCarbon Eventが用意されており、本当ならばスクロールバー(コントロール)に対してもkEventClassControlクラスのHandlerを用意する方が美しいと思われます。ところが調べてみると、どうも現状のCarbonLib 1.2では、kEventClassControlクラスに属するほとんどのCarbon Eventが未実装のようなのです。色々と試してみたのですが、この処理以外にはスムーズなスクロールバー操作を行う方法を発見することができませんでした。

最後は、kEventClassKeyboardクラスです。ここでは、まずGetEventParameter()を3回使いCharCode(ASCIIコード)、KeyCode、KeyModifierを得ています。それを旧Event Modelでもキー入力を担当していたkeyinControls()ルーチンにそのまま渡しています。

 

この処理もkEventClassMouseクラス同様、kEventClassControlクラスが実装されていないために取った苦肉の策です。本当ならもう少し美しい処理が実現できるでしょう。このクラスは「Raw Keyboard Event」と呼ばれています。Cabon環境には、Carbon Event Modelを考慮に入れた「Multi Lingual Text Editor」という新しいテキスト入力システムが用意されています。もしアプリケーションでCarbon Eventと親和性の高いテキスト入力を実現したければ、代わりにそちらに対応したkEventClassTextInputクラスを利用することになると予想されます。

 

これだけのCarbon Event Handlerを実装したViewJPEGアプリケーションを、さっそくMac OS Xパブリックβ版で起動してみました。ほとんどのEvent Handlerは正常に動いてくれたのですが、kEventClassWindowクラスのkEventWindowBoundsChangingを含め、いくつかのCarbon Eventを受け取ることができませんでした。どうも、まだ未実装のようです。例えば、ウィンドウリサイズの最中にkEventWindowBoundsChangingが発生しないため、リサイズの制限が利かないといった不都合が起こります(涙)。と言うわけで、現状のMac OS X パブリックβでは、Carbon Event Modelに準拠するために、これ以上の労力を費やしても意味が無いように思えます。Appleには、なんとか早急に次なるβ版(もう正規版発表まで時間がない...)の提供を実現して欲しいものです。(それからドキュメントも!!)

今回サンプルとして利用したCarbon Event対応の「ViewJPEG v1.2」のソースファイルとプロジェクトファイルは、オッティモのサイトのライブラリに登録されています。ぜひ旧ソースと比較しながら参考にしてみてください。
[小池邦人/オッティモ]
関連リンクオッティモ