● 小池邦人のMac OS Xへの道 2002/06/28

〜 Movie ControllerをCarbon Eventに対応させる その1 〜

今回は、久しぶりにQuickTime関連の話です。Carbon Eventモデルを採用しているアプリケーションからQuickTime標準の「Movie Controller」を使う方法を解説したいと思います。(以下がMovie Controllerの操作パネル)

 

以前にCarbon化した「MoviePlay」というサンプルアプリケーションを改良し、Carbon Eventモデルに対応させてみます。開発環境には、最新のMetrowerks CodeWarrior v8(英語版)を用います。

以下がCodeWarrior v8からオープンした「MoviePlay v3.0」用のプロジェクトウィンドウです。

 

使用するリソースは、'MBAR'、'MENU'、'xmnu'リソースといったメニュー関連の物と、Movieファイルをオープンする時に用いる'open'リソースです。

 

今回は旧プロジェクトを引き継いでいるため、Nibファイルは使わず、リソースファイルのみが登録されています。このため、Settingダイアログの「Project Type」は「Excutable」のままとし(Application Packageにはしない)引き続き「Mac OS Packager」の仕組みを利用します。完成したアプリケーションは、Mach-O版でMac OS X Nativeとなります(Mac OS 9.xでは起動しない)。Linker(リンカー)はv8から実装された「Mac OS X PowerPC Mach-O」の方を利用し、Prefix File(プリコンパイルヘッダーファイル)も「MacHeadersMacOSX」へと変更しておきます。

最初に、MoviePlayer 3.0で使う外部変数とmian()ルーチンを見てみます。



まずは、外部変数からです。handler_uppには、本アプリケーションで用意するCarbon Event HandlerルーチンのEventHandlerUPPを保存します。e_movは、編集メニューから実行するカット&ペースト処理用のテンポラリーMovieです。w_mov[]とw_play[]の両配列は、Movieウィンドウに登録するMovieとMovieControllerをそれぞれ保持するために確保されています。先んじて「MAXW」(配列数)は50と定義されていますので、同時にオープンできるMovieウィンドウの数は50までに制限されます。

mian()の最初では、Movie Controllerを利用する準備としてQuickTimeのEnterMovies() を呼んでいます。ちなみに、Movie Controllerの使用を中止したら、ExitMovies() を呼んでQuickTimeの作業用メモリを解放することもできます。続いて、SetMenuBar()とDrawMenuBar()でアプリケーションのメニューを構築し、setUpCarbonTimer()でCarbon Event Timerルーチンを、setUpAppCarbonEvent()でCarbon Event Handlerルーチンを登録しています。最後にRunApplicationEventLoop()を実行すれば、アプリケーションはCarbon Event Loop(昔で言うところのメインループ)に入ります。

以下が、Carbon Event Timerルーチンを登録しているsetUpCarbonTimer()と、その本体のmyCarbonTimer()ルーチンです。



Carbon Event Timerルーチンは、InstallEventLoopTimer()により登録します。3番目の引数が、何秒ごとにTimerルーチンを呼び出すのかを決定する引数です。今回は0.1秒ごとに呼び出すように設定してあります。myCarbonTimer()の仕事は、ウィンドウ上のMovie Controllerに対して、定期的に処理時間を分配するためにMCIdle()を呼ぶことです。

最初のcollectMovieWindow()ルーチンは、現在オープンされているMovieウインドウのWindowRefを配列に集め、その個数を返してきます。



Movieウィンドウに配置されているMovie Controllerは、外部変数のw_play[]に保存されています。その配列番号は、ウィンドウ作成時にWindowRefのwindowRefConフィールドに保存されるので、GetWRefCon()でその値を取り出せば得ることができます。Mac OS 9.xでMovieを再生した場合には、MCIdle()を定期的に呼ばないと、その再生が止まってしまいました。Mac OS Xではさすがに止まることはありませんが、Movieの再生ポジションを示すバーが動かないなどの不都合が起こります。

続いて、アプリケーション用のCarbon Event Handlerルーチンを登録するsetUpAppCarbonEvent()と、Movieウィンドウ用にHandlerルーチンを登録するsetUpWindowCarbonEvent()を見てみます。



アプリケーション用のHandlerルーチンは、InstallApplicationEventHandler() で登録します。対応するEventの種類は「kEventProcessCommand」のみで、これによりユーザのメニュー選択に対処します。これと比較して、InstallWindowEventHandler()で登録するMovieウィンドウ用Carbon Eventは9種類もあります。これらは、Movie Controllerに対するユーザの操作(Movieの再生や停止指示)やControllerのアクティブ、インアクティブ処理などを実現するために必要となります。

最後に、Carbon Event Handlerルーチンの本体を見てみます。MoviePlay 3.0ではmyCarbonEventHandler()ルーチンひとつで、アプリケーションとウィンドウ両方のCarbon Eventを処理します。



Eventクラスが「kEventClassCommand」の場合はメニュー選択処理なので、コマンドIDを得て、それをdoCommand()に渡します。Eventクラスが「kEventClassWindow」と「kEventClassKeyboard」の場合には、Movie Controllerへのマウスやキーボード操作に対処する処理を実行します。どちらの場合にも、ConvertEventRefToEventRecord()や手作業で「旧EventRecord構造体」を構築し、それをMCIsPlayerEvent()に渡します。後は、MCIsPlayerEvent()が引数で渡されたMovieControllerに対して適切な処理を実行してくれます。MCIsPlayerEvent()に渡すMovieControllerは、Timerルーチンと同様にGetWRefCon()で得た配列番号をもとにw_play[]から得ています。

ちなみに、今回紹介した「Movie ControllerをCarbon Eventモデルへ対応させる方法」は、QuickTime 5がターゲットです。QuickTime 6(Mac OS X 10.2から搭載か?)では、Handlerルーチンで先ほど紹介した「面倒なCarbon Event処理」をほとんど省くことが可能なようです。QuickTime 6の詳しい内容を知りたい方は、Apple社のQuickTimeサイトにアップロードされている「Whats New in QuickTime 6」(220ページ 1.2MB)というPDFドキュメントを参照してください。

http://developer.apple.com/techpubs/quicktime/qtdevdocs/RM/newsframe.htm

このドキュメントには、QuickTime 5からQuickTime 6への変更点がまとめられています。これは、ADC メンバーサイトからダウンロードできたWWDC 2002関連フォルダにも含まれていましたが、今回のリビジョンで内容が更新されています。

ここで解説している「MoviePlay_3.0」サンプルアプリケーションは、以下のサイトに登録されていますので試してみてください。Mac OS X 10.1とMetrowerks CodeWarrior v8が必要です。v7の場合でも、ソースファイルやリソースファイルを新規プロジェクトに登録してMakeすれば大丈夫でしょう(多分...)。

http://www.ottimo.co.jp/library/

次回は今回の続きで、編集メニューからのMovieのカット&ペーストや、Movieファイルを読み込み、それを表示するためのウィンドウをオープンする課程を解説します。


copyright 2002 Ottimo, Inc. All rights reserved
無断転載・引用禁止
Contact Us: koike@ottimo.co.jp