● ToolBox API徒然草(2006/10/23)

  このニュースは、MOSAの会員にのみ配布されているデベロッパー向けの
  デジタルマガジンMOSADeNのに掲載された記事です。ほぼ一ヶ月遅れで
  ここに掲載されて行きます

 〜 Carbonモダンアプリケーションへの道(その3) 〜


自作アプリケーションのメイン処理の中心として活躍していたAPIが突然消えてしまったら、デベロッパーは途方にくれてしまいます。そうした事態を避けるために、Apple社は何年かかけて少しずつ代用APIを準備してきました。今回は、そうした代用APIを取り上げ調査してみたいと思います。

その規模がちょうど良いので、まずは「Drag Manager」という割と渋めの箇所から攻めてみることにしましょう(笑)。Drag Mangerは、あらゆる種類のオブジェクト(ファイル情報、アイコン、画像など)のドラッグ&ドロップの仕組みを提供しているマネージャです。Finderでアイコンをドラッグして別の場所へドロップする場合なども、Drag ManagerのAPIが利用されています。随分と昔から存在しているAPI群ですが、関連ヘッダファイルのDrag.hを調べてみると、DEPRECATED指定されているAPIはたったひとつだけです。

この事から、Drag ManagerはMac OS X 10.4以降でも生き残るようなのですが、今ひとつ最新のCarbon Eventの仕組みとマッチしていない感じもあります。また、ファイル情報をドラッグ&ドロップで渡す場合に、必ずFSSpec構造体を使う仕組みとなっており、未だにFSRefに対応していません。この様に、生き残こる事自体に対して色々と疑問点は残りますが、これもシステムの進化の「都合」のひとつなのでしょうか(笑)。

Drag Managerで、唯一DEPRECATED指定を受けたAPIは、以下のSetDragImage()です。通常Mac OS Xでは、画像データをドラッグする時に「半透明の画像」が表示されますが、それを作成するためのAPIです。

OSErr SetDragImage(
DragRef inDrag,
PixMapHandle inImagePixMap,
RgnHandle inImageRgn,
Point inImageOffsetPt,
DragImageFlags inImageFlags );

APIに渡す引数の中に、QuickDrawで使っていたPixMapHandleやRgnHandleがあるので、まあDEPRECATEDとなっても仕方がないでしょう。これの代用APIとして、Mac OS X 10.2から追加されたのがSetDragImageWithCGImage()です。画像データとして、PixMapHandleの代わりにCoreGraphicsで用いるCGImageRefが利用されています。

OSStatus SetDragImageWithCGImage(
DragRef inDrag,
CGImageRef inCGImage,
const HIPoint * inImageOffsetPt,
DragImageFlags inImageFlags );

ちなみに、ImageWellコントロールに貼り付けたPicture画像をPixMapHandleに変換してからSetDragImage()に渡すルーチンは、以下のようになります。



SetDragImage()にはPicHandleを直接渡すことはできませんので、NewGWorld()でオフスクリーン(GWorld)を作成し、そこにPicture画像を描画することで、PixMapHandleを得ています。GWorldPtrとRgnHandleはドラッグ終了後に削除する必要がありますので、引数で受け取るようになっています。上記ルーチンをSetDragImageWithCGImage()を用いる方法に書き直すと、以下のように簡単になります。



GetImageWellContentInfo() APIを用いれば、ImageWellコントロールから画像データを得ることが可能です。引数で渡すControlButtonContentInfo構造体のControlContentTypeの設定内容により、得られる画像データとしてPicHandleやCGImageRefなどを選択することができます。当然、これらの画像データは、先んじてその形式でImageWellコントロールに付加されている必要があります。そちらの作業には、SetImageWellContentInfo() APIを用います。



GetImageWellContentInfo()とこの構造体を用い、ImageWellコントロールからPicHandleを得るためのgetMyControlWellPict()ルーチンは以下の様になります。



同様に、CGImageRefを得るgetMyControlWellCGImage()ルーチンは以下の通りです。



ところで、ヘッダファイルのControls.hでは、ControlButtonContentInfo構造体のメンバの一部の使用(pictureやiconSuiteなど)を「推奨しない」と言っていません。つまり、ImageWellコントロールへのPicHandleの出し入れは、QuickDrawが消えてもそのまま残るのでしょうか?この辺の方針が明確でないのが若干困りものですね。また、Drag Managerでは、SetDragImageWithCGImage()同様に、Mac OS X 10.2から3つ、10.3からは2つのAPIが追加されています。こうした最新APIを利用する場合には、アプリケーションのターゲットとなるOSバージョンが幾つなのかについても、ちゃんと気にとめておく必要があります。注意しましょう!

今回はDrag Managerについて代用APIを調査してみましたが、今回の例題と同じような状況はCarbon Frameworkの広範囲に及んでいます。次回も代用APIの調査を継続してみたいと思います。


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