!!!独り言日記 !! Mac(Carbon)でのリージョンの罠(2005/10/31) Carbonでは、「BitmapToRegion」で1bit/pixelの画像から リージョンを作成することができます。 例えば(適当に描いた)以下のような画像の赤の部分を 背景とします。 {{ref_image rgn_img_20051031.png}} 赤だけ抜き出して1ビット画像を生成する、というのは プログラムで自動化できますね(これのTipsがほしい方、おっしゃってください。 書きますので)。 で、以下のようなマスク画像が得られます。 {{ref_image rgn_img_20051031_m.png}} Appleサイトの「CreateCustomWindow」のサンプルを上記のような画像で 置き換えると、背景を指定の画像でマスクした非矩形のウィンドウを作ることができる、そう考えてしまうかと思います。 実はこれが「ブーッ」です。 実は「OSXでは上記画像の場合リージョンのみずれてしまう」というとんでもないバグがあります。 OS9では問題ないことからして、OSX特有のバグかと思ってます(OSX10.4.2と10.3.9で確認)。 ウィンドウを描画する場合は「リージョン(RgnHandle)」と「画像(GWorldPtr)」の両方を使う必要があるのですが、特定の条件下でリージョンでずれが生じ 画像描画自身は正常に行われます。 具体的には以下の図のように、リージョンのみ左端と上端が勝手にトリミングされてしまいます。 {{ref_image rgn_img_20051031_2.png}} 結果、以下のように表示されることになります。実際は、マスク領域自身が ずれますのでもっと変になりますが。 {{ref_image rgn_img_20051031_4.png}} 「特定の条件」おわかりでしょうか?つまり、左端か上端に空白領域がある、 これがひっかかっているようです。 きちんと動作させるには以下のような画像を用意しないとダメなんです(ずれた分を元に戻す、というプログラムを書いてもいいのですが「戻す(MoveWindow)」作業が目に見えてしまうため、たぶんすっきりしないと思います)。 {{ref_image rgn_img_20051031_3.png}} 左端・上端に数ピクセルでも接している、これが不正にさせない大事な条件です。 実際はウィンドウ自身をアニメーションさせたい場合は、上下左右すべてをトリミング してあげないといけません(これも、そうしないと別問題が絡むんですよ)。 また、「じゃあ、ずれた分をリージョンごと元に戻してはどうか」と 考える方もおられるかと思います。 いろいろ手段を試したのですが無駄でした(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) ひさびさの携帯電話カメラものです。そろそろ秋ということで。 {{ref_image 05-10-02_14-11.jpg}} {{ref_image 05-10-02_14-08.jpg}} 場所は[目黒自然教育園|http://ft-lab.ne.jp/photo/meguro.html]。 たまに涼みに行くのですが、土日だと人も多くなってきた気がします(依然、年齢層が高いのですが)。もうススキも多くなってきていて、トンボも飛び交っているのを 見ると風流さを感じますね。 しかし、今は携帯のカメラでも数百万画素が普通になってきてますねぇ。 私のは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以前では問題ないのですが・・・