トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

独り言日記(2005/10)

独り言日記

Mac(Carbon)でのリージョンの罠(2005/10/31)

Carbonでは、「BitmapToRegion」で1bit/pixelの画像からリージョンを作成することができます。

例えば(適当に描いた)以下のような画像の赤の部分を背景とします。

赤だけ抜き出して1ビット画像を生成する、というのはプログラムで自動化できますね(これのTipsがほしい方、おっしゃってください。書きますので)。で、以下のようなマスク画像が得られます。

Appleサイトの「CreateCustomWindow」のサンプルを上記のような画像で置き換えると、背景を指定の画像でマスクした非矩形のウィンドウを作ることができる、そう考えてしまうかと思います。実はこれが「ブーッ」です。

実は「OSXでは上記画像の場合リージョンのみずれてしまう」というとんでもないバグがあります。OS9では問題ないことからして、OSX特有のバグかと思ってます(OSX10.4.2と10.3.9で確認)。ウィンドウを描画する場合は「リージョン(RgnHandle)」と「画像(GWorldPtr)」の両方を使う必要があるのですが、特定の条件下でリージョンでずれが生じ画像描画自身は正常に行われます。

具体的には以下の図のように、リージョンのみ左端と上端が勝手にトリミングされてしまいます。

結果、以下のように表示されることになります。実際は、マスク領域自身がずれますのでもっと変になりますが。

「特定の条件」おわかりでしょうか?つまり、左端か上端に空白領域がある、これがひっかかっているようです。

きちんと動作させるには以下のような画像を用意しないとダメなんです(ずれた分を元に戻す、というプログラムを書いてもいいのですが「戻す(MoveWindow)」作業が目に見えてしまうため、たぶんすっきりしないと思います)。

左端・上端に数ピクセルでも接している、これが不正にさせない大事な条件です。

実際はウィンドウ自身をアニメーションさせたい場合は、上下左右すべてをトリミングしてあげないといけません(これも、そうしないと別問題が絡むんですよ)。

また、「じゃあ、ずれた分をリージョンごと元に戻してはどうか」と考える方もおられるかと思います。いろいろ手段を試したのですが無駄でした(T_T)。この「勝手にトリミング」は、ウィンドウで描画が起こる(リージョンで抜く)直前で処理されるようで、手を出すことはできませんでした。リージョン左上に1ピクセルの点をダミーで置くと、これまたきっちり行くんですね。しかし、常に左上に謎の点がある、という不格好な状態になりますので元画像自身をあらかじめトリミングしてあげるほうがよいでしょう。

CodeWarrior8.3でCarbonアプリ、という組み合わせもあるかもしれませんが、覚え書きということで。

この他にもリージョン関連では「ウィンドウをアニメーションで動かしたい場合にリージョンのアニメーションがついてこない」という現象もあります。例えば、画面上を飛び回る蝶の羽ばたきをアニメーションする場合、など。あらかじめ元画像の上下左右をトリミングしてもダメです。これもマニアックな手段を使わないと回避できません。これは次回にでも。

Macプログラム(Carbon)でのアイコン生成(2005/10/28)

ひさびさに覚え書き。

Macでは最大128x128 pixelのアイコンを持ちますが、これをリソースとしてCarbonアプリに添付します。これ、結構面倒だったりします。

私が使う手は以下の2つのOSXのツールを使用して、リソース用の「icns」情報を生成しています。最終的にCodeWarriorでアイコンをアプリケーションにつける手順です。アイコンの背景を透過する、ということもできます。

Iconographer

http://www.apple.com/jp/downloads/macosx/customize/iconographer.html

複数サイズのアイコンを作成します。あらかじめ、アイコン元画像として16x16 / 32x32 / 48x48 / 128x128のサイズのものを作成します。同時に、背景を白・抜く部分を黒としたマスク画像も作ります。この画像を「Iconographer」にコピー&ペーストしてきます。

できあがったら、「別名で保存」にてアイコン形式を「Mac OSX(.icnsファイル)」にして保存します。マスクを自動生成 みたいに聞いてきますが、YESマンで通してください。これで第一段階は完了です。

まだ、ファインダで見えるファイル自身には作成したアイコンが表示されていないのが分かると思います。

Iconverter

http://www.versiontracker.com/dyn/moreinfo/macosx/16468

Iconographerで作成したファイルだけでは、リソース(ResEditで使用)の「icns」情報を取り出せませんので、次にIconverterというのをかまします。各種画像をアイコンに変換するツールです。

Iconographerで作成した「xxxx.icns」ファイルをIconverterにドラッグ&ドロップします。すると、右に透過した128x128pixelのアイコンが表示されます。「サムネイルをつける」をチェック、「背景色をつける」のチェックをはずしておきます。この状態で、出力先を「選択」ボタンで指定して、右端の「抽出」ボタンを押します。なんら変化はないですが(右下のプログレスバーがわずかにアニメーションする)、これで「xxxx.icns」のアイコンが変化したものが作成されます。

これでアイコンリソースは出来ました。このファイルをResEditにドラッグ&ドロップします。いうまでもなく、ResEditはClassicアプリですのでOS9がOSX上で動作するようにしておく必要があります。

ResEditでの作業

ドラッグした「xxxx.icns」ファイルがResEditで正常に読み込まれると、リソースとして「icns」が見つかるかと思います。これを自分のアプリケーションのリソース(ResEditで開いておくこと)にコピーします。

ResEdit上でも、[Apple key] + [C]でコピー、[Apple key] + [V]でペースト、が効きますのでこれを利用のこと。

これでResEditを保存します。

CodeWarriorでの作業

まだまだ続きますよ。CodeWarrior上で、作成したリソース(xxx.rsrc)がプロジェクトに含まれていることを確認します。もちろん、アイコンのicnsリソースも内包しているものです。[Edit]メニューのプロジェクトのSettingにて、左のツリーより「Target - Target Settings」を選択します。Post-linkerのプルダウンで「Output Flags Post Linker」を選択します。CarbonなのでLinkerは「Macintosh PowerPC」選択が前提です(Mach-Oは試してないです)。

次に、左のツリーより「Linker - Output Flags」を選択し、Finder Flagsの「Has bundle」「has custom icon」のチェックを入れます。

以上で、CodeWarriorでターゲットのアプリをビルドすることで、無事作成したアイコンに変化します。OSX/OS9.2/OS9.0.4でアイコンが指定のものに変わったのを確認できました。

いやはや、ややこしいですね。こんな儀式的なことが他でもいっぱいあります。それはまた順を追って説明していきます。

しかし、OSX(10.4)でもバグが多いこと・・・。OS9と挙動が違うし、というのがちらほら見受けられます。Carbonだからかなぁ、なんかやる気のないAPIが多いですねぇ(^_^;;。CreateEditTextControlで作れるControlRefなんて、TEHandleを改悪しただけじゃぁ・・・(ControlRefからTEHandle情報をゲットしてそれで処理したほうが見通しがいいですし)。

まだ開発の渦中にいるのですが、そろそろ終わりが見えてきたので表に出せそうなTipsは出していこうかと思います。

Macプログラム(Carbon)で使えそうなアプリ(2005/10/10)

連投ですが、Mac関連。プログラムでこれがあれば便利かも、というのを列挙しています(今作っているもので頻繁に利用しているものです)。忘れないようにということでメモ書きです。

リソースエディタ

「ResEdit」(Classicのみ)。古いMacのリソース管理ソフトの定番です。ダイアログや表示メッセージ、メニューリソース、アイコンなどなど編集します。Carbonアプリ作成時にはかかせません。

http://developer.apple.com/tools/ResEdit213.hqx

バイナリエディタ

「HexEdit」(OSX対応)を使うとファイルの中身をダンプできます。ファイル内容を確認/解析するのに重宝できそうです。

http://hexedit.sourceforge.net/

サウンド変換

「SoundConverter」(OSX対応)でwav/mp3/aiffなどのサウンドファイルを相互変換できます。

http://www.dekorte.com/projects/shareware/SoundConverter/

「SoundApp」(Classicのみ)。これも同じくサウンド変換。「システムサウンドとsndリソースの吐き出しに対応している」これが大きなメリットです。リソースの「snd」として取り込むことができる形式に変換できます。

SoundAppにてaiffやwav形式のファイルを読み込み、「システムサウンド」としてファイル保存します。このコンバートしたシステムサウンドファイルをResEditにドラッグすると、「snd」形式のリソースを取り出すことができます。これを、自分が作るアプリのリソースファイルにコピーすることで、リソース内に音データを持ってくることが可能になります。

http://www.naotaka.com/SoundApp/

あと、Windowsでいうペイントブラシっぽい簡易ペイントツールがあれば快適にアプリ生成ができるかな。ペイント系はいろいろありそうですね。

リソース編集 - ResEdit(2005/10/10)

以下、覚え書きということで。引き続き、OS X環境にてなんとかClassicアプリである「ResEdit」を使いたいということで試行錯誤してました。以下のが最終版のようです(Classic環境でのみ動作。バージョンは2.1.3)。

http://developer.apple.com/tools/ResEdit213.hqx

ただし、これはClassic環境でしか使えないです。最近のTiger(OS X 10.4)マシンではClassic環境は動作しません(OS 9.xマシンからのアップグレードなら可能)。よって、eMac上ではOS9のインストーラが起動しないので 古いiMac上にリムーバブルのハードディスクをつないでOS 9を入れました。インストール完了後、eMacにハードディスクをつなぎ、メニューの「システム環境設定」より「Classic」を選択。ハードディスク上のOS9のシステムフォルダを選択し、OS 9を起動します。これで、eMac上のOS X 10.4上でClassicを動作させることができました。結果、無事ResEditが使えるように。

ちなみに、OS 9を入れたマシンからリブートしようとしてもeMac上では起動できませんでした。なんか、起動時のプロテクトでもかけてるんですかね。中からの起動はできるんだからOS 9単体起動も許してほしいものです。

しかし、やはりResEditは使いやすいですねぇ。先日書いたAlertボックスもあっという間に対応できました。それに比べて、InterfaceBuilder(NIBによるリソース生成ツール)はあんなに使いにくいんだろう...。

リソースの日本語文字化けについてOS Xでは対策があるのでこれは次回にでも。Classic用/OS X用の2カ所の指定がいります。

Carbonでのリソース編集(2005/10/09)

MacにてCarbon対応アプリを作る場合、Alertボックス(バージョン情報などの表示)やメニュー、アプリケーション自身を表すアイコンは「リソース」としてプログラムで追加してあげる必要があります。これはWindowsでも同じですが、MacはClassic(〜OS 9.x)とOS Xで大きく事情が異なります。

ClassicのアプリをCarbonで作る場合のリソース編集を行うツールとして「ResEdit」というのが代表的です。しかしこれ、Classic環境でしか動かないんですね。また、今は開発は止まってますし(Apple社開発)。ただ、ResEditで作成した旧リソースは今のOSXアプリでも現役で利用することができます。

OS XではNIB(InterfaceBuilderで生成)でリソースを作ることができますが制約が強く、ProjectBuilderと連携しないと画像をリソースに追加できない(ドラッグ&ドロップでリソース追加できるようにしてほしいものです)、Alertボックスはどうやって作るんだろう(私が知らないだけかも)、などなどよくわからない部分が多いです。CocoaとCarbonでできることが異なるのですが(Cocoaのほうが高機能)、やりすぎるとOS X onlyの動作になってしまうのかもしれません(調べてないのであくまで推測です)。

いっぽう、CodeWarriorには「PowerPlant Constructor」というリソースエディタがついているのですが(Carbon環境(OSX環境)でも利用できる)Alertボックスを作れないような気が。また、OSXの128x128pixelアイコンも追加できないようで、癖があります(私が保有しているCodeWarriorはそもそも英語版なので日本語が化けますが)。で、Carbon対応アプリとしてOS9/OSX双方に対応するアプリを作る場合、結局はClassic環境を生かしておいて、ResEditでリソース作るしかないかなぁ、という気がします。OS9/OSX両方対応のアプリを作る場合、このリソース管理はやっかいですねぇ。

しかも、私が持ってるeMacではOS X9.xがインストールできないため、リソース編集のためだけに古いiMacを引っ張りださねば...。(MacではプリインストールされたOSのバージョンよりも低いOSをインストールしようとした場合、インストールできない現象がよくおこるらしい...、Winじゃ、最近のマシンでも余裕でWin98とかインストールできるのに...)

というわけで、一難去ってまた一難で Macプログラムは大変っすね。リソース編集ソフトは、なぜかOSX(もしくはCarbon対応)バージョンが少なく、市販のものでももう今でも生きているのはない感じがします。(市販で「Resorcerer」というのがあり、よさげな気がしたのですが開発は止まっているようです。というか、OS X 10.4では不都合があるみたい)

CreateCustomWindow問題解決(2005/10/07)

ようやくOS X 10.4にて非矩形ウィンドウのときにドラッグができない(「CreateCustomWindow」サンプル)の回避策を見つけました。

ソースはAppleのサイトよりダウンロードしてください。

で、CustomWindow.cの

myWindowGetFeatures関数の「kWindowSupportsSetGrowImageRegion」の行をコメント化します(XCode2.1ではこれは宣言がありませんでした。CW8.3はあったかも。いずれにしても不要です)。というか、

*(OptionBits*)param = kWindowCanGetWindowRegion |
                      kWindowDefSupportsColorGrafPort;

だけでOKです。

最後のgetCurrentPortBounds関数を以下に置き換えます。

void getCurrentPortBounds(WindowRef window, Rect* inRect)
{
    GetWindowBounds(window, kWindowGlobalPortRgn, inRect);	
}

第一引数にWindowRefを渡すように変更し、「GetWindowBounds」にてスクリーン上でのウィンドウ矩形座標を取得しています。どうも、サンプルにあった

CGrafPtr thePort;
GetPort(&thePort);
GetPortBounds(thePort,inRect);

は、OS X 10.4で誤作動を起こしていたようです。Classic(OS 9)でリコンパイルして動かしても動いてなかったのでこれもチェックせねば。

とりあえず、無事10.4で動作する方法が見つかったのでほっとしました。これで、仕事での大きな障害を1つクリアです。

OS X 10.4でのQuickDraw(2005/10/06)

10/2に書いたAppleサイトの「CreateCustomWindow」のサンプルソースですが、深く追っているとどうもリージョン関連でも変な動きがしているところがあります。ドラッグで移動しないほか、ドラッグ動作を繰り返すとウィンドウがどんどん小さくなっていきます。ただし、10.4の環境のみの不都合。

「MapRgn」が正しく動いていない?と思ってAppleのサイトをみると、10.4では推奨されないとのこと。いろいろ調べてみると、AppleはQuickDrawを消し去ろうとしている予感ですねぇ。QuickDraw関連は結構なAPIが10.4以降は非推奨状態のようです。

ということは、大部分のCarbonアプリは動かなくなる訳で10.3 ==> 10.4の高い壁がありますな。というか、未だCreateCustomWindowの移動ができない、、、、Quartz2Dとかを使うといいのだろうか、、、

自然植物園(2005/10/04)

ひさびさの携帯電話カメラものです。そろそろ秋ということで。

場所は目黒自然教育園。たまに涼みに行くのですが、土日だと人も多くなってきた気がします(依然、年齢層が高いのですが)。もうススキも多くなってきていて、トンボも飛び交っているのを見ると風流さを感じますね。

しかし、今は携帯のカメラでも数百万画素が普通になってきてますねぇ。私のは30万画素・・・。

非矩形ウィンドウを生成する(2005/10/02)

いきなりプログラムの話題です。

C/C++にてアプリケーションとして非矩形のウィンドウを生成する場合、Windowsの場合は「SetWindowRgn」のWindowsAPIを使用します。「非矩形」とは、四角くない、たとえば円形や独自の形状を持った形をさします。時計型のウィンドウとかありますね。Winの場合はいろんなところでやり方はのってるので割愛。

で、Macは・・・というと情報が少ない少ない(^_^;;。Carbonでは「CreateCustomWindow」を使用することで、非矩形のウィンドウを実装することができます。Appleのサイトでずばり「CreateCustomWindow」のサンプルコードがダウンロードできます。

http://developer.apple.com/samplecode/CustomWindow/listing3.html

でですね、問題はOS 10.4(Tiger)です。うまく動かない・・・・(T_T)。もうちと、互換性を考えるかせめてサンプルソースがまともに動くようにあらかじめチェックしてほしいものです。マスクで抜かすことはできるのですが、ドラッグするとTigerでは移動しないですねぇ。10.3以前では問題ないのですが・・・

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.