本アプリはCarbon対応です。Carbon対応以前のソースコードも添付しておきますので参考にしてください。【注意】現在のMac OS X(DP4)で起動するとファイル選択時にMovieファイルが選択できないかもしれません。そうした場合には、NavGetFile()に渡すlistをNULLに変更してお試しください。
ダウンロード → PlayMovie v2.0.sit(24K)
このサンプルアプリケーションは複数のMovieファイルをオープンし、ウィンドウ上に表示することができます。そしてQuickTimeのユーザインターフェースに準拠した方法で、Movieのプレイやストップ、コマ送り、カット&ペースト等のコントロールが可能となっています。利用したコンパイラはMetrowerks-C Pro5で、ソースはすべてMoviePlay.cにまとめられており、利用するMac OS用ライブラリはCarbonLib(v1.04)のみです。ソース中で頭文字が大文字のルーチンがToolBoxやQuickTimeのルーチンであり、小文字の物が筆者が作成したルーチンとなっています。にこのソースをコンパイルするには、QuickTime用に用意されたいくつかのヘッダファイル(Movies.h等)が必要ですので注意してください。また、コンパイル時にヘッダーファイルの保存場所のパス名が異なる場合があります。そうした場合にはIDEのSettingのAccess Pathsを、ご利用の環境に合わせるように調整してください。ソースの最初に「#define TARGET_API_MAC_CARBON 1」を定義して、このプロジェクトがCarbon対応であることを指示します。
グローバル変数
このアプリケーションで利用するグローバル変数は3種類です。w_mov[MAXW]とw_play[MAXW]は、Movieファイルをオープンしそれをウィンドウに割り付けた時に、Movie自身とそれをコントロールするMovie Controllerを保持しておくためのハンドラです。MAXWは50と定義されていますので、同時に50までのMovieウィンドウを開くことができるということです。e_movはMovieのカット&ペーストに利用します。
main()
このルーチンがアプリケーションの入り口となります。Carbonでは、おなじみのMacintosh各マネージャの初期化はありません。ここでは、Gestalt()を利用して現在のMacintoshの環境でQuickTimeが利用できるかどうかを調べていますが、Mac OS Xではこの操作も必要ないでしょう。Gestalt()に代入するgestaltQuickTimeという定数はMovies.hの中で定義されています。このチェックでQuickTimeが利用できないと判断されると、ビープを1度ならしてアプリケーションは強制的に終了します。EnterMovies()によりMovie ToolBoxの利用手続きを行い、Quitイベントを登録しメニューを登録したら、mainLoop()に制御を渡します。
setupEvent()
EventHandlerにアプリ終了処理(Quit処理)を登録します。Mac OS XではファイルメニューからQuitが外され、アプリケーションメニュー(今までのAppleメニューの場所)の一番下に自動的にQuitが追加されます。よってアプリをMac OS Xで起動させる場合には、EventHandlerにアプリ終了処理を登録しておくことが必要となりますので注意しましょう。
myQuitApp()
EventHandlerに登録する、アプリケーション終了処理です。
setupMenu()
このアプリケーションのメニューを構築しています。利用するメニューは、Appleメニュー、ファイルメニュー、編集メニューの3種類です。まずGestalt()にgestaltMenuMgrAttrを代入し、起動されている環境がMac OS Xかそうでないかを判断し、構築するメニューを変えています。Mac OS Xではファイルメニューの「終了」は必要ありません。またCarbon環境では、AddResMenu( mhd,'DRVR' )を使いAppleメニューを構築する必要はありません。OS側が自動に行ってくれます。
maiLoop()
Macintoshのアプリケーションは、WaitNextEvent()で各種イベントを受取り処理ルーチンへ分岐していく仕組みになっています。通常のMacintoshのアプリケーションと異なるのは、chkMovieEvent()により事前にMovieを割り付けてあるウィンドウに対してイベントが発生したかどうかをチェックし、そのイベントの対してQuickTimeが直接イベントに対する処理を実行している点です。またCarbon環境では、SystemTask()ルーチンをイベントループに挿入する必要はありません。(イベントモデルはCarbonLib v1.1で大幅に変更される予定です)
doMouseDown()
Macintoshでマウスクリックが発生した場合に処理をおこなうルーチンです。クリック位置がそれぞれメニューバー内、ウィンドウ内、ウィンドウタイトル内、クロウズボックス内かどうかを判断して各処理ルーチンへ分岐します。Carbon環境では、SystemClick( )を呼ぶ必要はありません。
doKeyDown()
Macintoshでのキー入力を処理するルーチンです。メニューのショートカットキーの判断に、MenuKey( code )の代わりにMenuEvent( event )を利用します。これは、ショットカットがコマンドキーのみではない可能性が出てきたからです。このアプリケーションは通常のキー入力に対しては何も実行しません。
doUpdate()
Movieウィンドウのアップデートは、MCIsPlayerEvent()にイベント処理を渡した時点でMovie Controllerがすべてを行ってくれますので、このルーチンはダミーです。BeginUpdate()、EndUpdate()以外の特殊な処理は行っていません。(後述chkMovieEvent()を参照)SetPort( window )の代わりにSetPortWindowPort( window )を利用しているところに注目してください。
doDrag()
ウィンドウのタットルバー上でマウスクリックが発生した場合にウィンドウを移動させる処理を行います。アクセッサールーチンのGetRegionBounds()を利用しています。
doGoAway()
ウィンドウのクロウズボックス上でマウスクリックが発生した場合に、disposeMovieWindow()を呼び出しウィンドウを削除します。
doQuit()
アプリの終了処理を行います。アプレケーションを終了する場合は、searchMovieWindow()で現在オープンされているウィンドウをカウントし、それらをすべてクロウズした後、ExitMovies()を実行しMovie ToolBoxの使用終了をQuickTimeに知らせます。このようにEnterMovies()とExitMovies()はQuickTime内のMovieルーチンを使用する手続きしてペアで利用されます。
doMenu()
コードからメニューidとメニューitemを得て、それをclickMenu()に渡します。
clickMenu()
マウスによりメニューが選択された場合や、コマンドキーを利用したショートカットがなされた場合の処理を行います。どのメニューが選択されたかは、id番号とitem番号により判断されて、各処理ルーチンへと分岐します。id番号129がFileメニュー、130がEditメニューです。Carbon環境では、Appleメニューの項目をオープンする処理は、OpenDeskAcc()を使わなくてもOS側が自動的に行います。(Aboutなどは別)
clickFileMenu()
選択されたメニューアイテムにより、Movieウィンドウのオープンとクロウズ、アプリケーションの終了を実行します。
clickEditMenu()
Movieウィンドウに表示されているMovieのカット&ペースト等を処理してやります。すべての処理はQuickTime内のMovie Control Componetsに定義されている各種ルーチンが行ってくれ、プログラマはそうしたルーチンを呼び出すだけですむようになっています。こうしたルーチンには引き数として、Movie Controllerを定義しているw_play[]を渡すことになりますが、その配列番号は各ウィンドウ構造体のrefCon値に入っており、それを参照することで決定できます。MovieのCutやCopyはシフトキーを押しながらControllerのつまみをドラッグして映像をセレクションすることにより実行可能になります。
sfEventProc()
Navigation ServiceのNavGetFile()で呼び出されるイベント処理用のコールバックルーチンです。MovieウィンドウのUpdateイベントのみに対応してます。
openMovie()
ファイル名選択のダイアログ(Navigationサービス)をオープンし選択されたMovieファイルをオープンした後、ウィンドウ上に表示します。ここでファイル選択をつかさどっているルーチンはNavGetFile()です。Carbon環境では、今まで使用してきたSFGetFile()やStandardGetFilePreview()などは利用できません。ファイルの選択にはすべてNavigation Serviceのルーチンを利用することになります。オープン可能なファイルタイプ(今回はMooVのみ)は'open'リソースに保存されています。ファイル選択が完了すると、そこから入手したFSSpec(ファイルの保存場所を含んだ構造体)をloadMovie()に渡します。loadMovie()によりMovieファイルをオープンしMovieを得ると、openMovieWindow()にそのMovieを渡して処理を完了します。このルーチンでは、ファイル選択ダイアログで複数のMovieファイルが選択された場合にも対応しています。
loadMovie()
引き数でのFSSpec(ファイルの保存場所を含んだ構造体)をOpenMovieFile()に渡し、Movieファイルをオープンします。Movieファイルが正常にオープンできたならば、ファイルリファレンスナンバーが返ってきます。それをNewMovieFromFile()に渡すことにより、ファイルからMovieを抽出してやります。最後にCloseMovieFile()でオープンしたMovieファイルを閉じて処理を終了します。
openMovieWindow()
引き数で受け取ったMovieの矩形枠にピッタリ合ったウィンドウを作成し、そこに新規のMovieControllerを付加してやります。Movieの表示枠はGetMovieox()により得ます。newMovieWindow()でウィンドウをオープンした後に、NewMovieController()で新規のMovie ControllerをMovieに割り当てます。SetMovieSelection()は現在のセレクションエリアを初期化し、SetMovieTimeValue()はContorollerのつまみ位置をMovieの先頭に持っていきます。MCEnableEditing()は、このウィンドウ上でのMovie編集を許可するよう設定してくれます。
newMovieWindow()
w_mov[]配列が空いているかどうか調べてやり、もし空いていればCreateNewWindow()で、その配列番号をrefConフィールドに持ったカラーウィンドウを作成してやります。
disposeMovieWindow()
引き数で指定されたウィンドウを削除し、そこに割り当ててあったMoviとMovie Controllerも削除してやります。この時点でw_mov[]にゼロを代入することにより、この配列番号を再度利用できるようにしています。
chkMovieEvent()
MCIsPlayerEvent()で現在オープンしているすべてのMovieウィンドウにイベントを渡し、Movie Contorollerによる適切な処理の実行を保証してやります。この時に各Movieに対して時間が配分されますので、ウィンドウを切り替えてもプレイ中のMovieはストップすることなく処理を実行します。
searchMovieWindow()
現在オープンしているすべてのMovieウィンドウのWindowPtrを配列に入れ、リタン値としてその個数を返します。
こんな簡単なプログラミングでも、QuickTimeの能力を引き出し利用できるというのは、Macintoshでプログラミングする大きな魅力のひとつです。まあQuickTimeにかぎらず、ToolBoxやColor QuickDraw等をうまく利用するということも同様なのですが、Macintoshでのプログラミングはアイデア勝負の世界であり、「多くの優秀な部品を使って自分の目的にあった使いやすい代物を組み立てる」ということに集中することが可能な世界なのかもしれませんね。
copyright 2000 Ottimo, Inc. All rights reserved
無断転載・引用禁止
Contact Us: koike@ottimo.co.jp