あまつぶ

2.29 【誰のウィンドウやねん】

 デバッガに落ちてしまう原因がちょっとずつわかってきた。ウィンドウのrefConの内容を調べてウィンドウの種類を判別しようとしているところで不正なアドレスにアクセスしてしまっているということはすぐにわかったのだがその先がややこしかった。
 まず、デバッガに落ちた時にログをとったりしてその時refConになにが入っていたのかを調べてみた。すると、refConかrefConの指すアドレスのどちらかに'obj 'という4バイトが入っていることを発見。PhutではWindowExtensions.hを使っていたこともあり、refConにはウィンドウの種類やウィンドウに関する情報などをおさめたハンドルを入れてあるのだからこれはおかしい。自分のウィンドウではないのか……?
 次に、refConの内容を調べて、上記の場合であればそのウィンドウのタイトルを表示するコードを追加して実験してみた。デバッガ上で表示される方が楽だろうと思ったのだが、タイトルが日本語名だったりしてかえって苦労してしまった。名前は、「アプリケーション」だった。Phutで開いているウィンドウにはそういう名前のものはない。ということは、やはりPhutのウィンドウではない。名前からするとアプリケーション切り替えのウィンドウかなという気もしつつ。
 あまりいい方法とは言えないが、refConの内容を調べて'obj 'が入っていた時は無視するように変更してまたしばらく様子を見てみることにしたのだが、またしても同じようなことが起こってしまった。今度は、refConに'sdev'という4バイトが入っていた。うーん、これはコントロールバーのことだろうか……。
 refConの内容が'sdev'の場合も無視するように……とやるのは簡単だが、他のウィンドウが関わってこないとも限らない。refConに入っているものが自分で用意したハンドルであると確実に判る方法も思いつかないし、結局、refConを使う方法はあきらめてウィンドウのプロパティを使ってみることにした。
 GetWindowProperty()とかSetWindowProperty()とかのあたり。プロパティのクリエータなんかを指定できるから、ここに自分のアプリケーションのクリエータを入れておけば確実に判別できるはず。OS 8.5以降でしか使えないが、CarbonLib 1.0が入っていれば使えるから問題なし。通常のバージョンでもこれと同じやり方をする方が安全かも知れないが、またそのうち検討することにしよう。

 ところで、前に書いたかどうかよく覚えてないけど、PhutのCarbon版がMacOS 8.1+CarbonLibで動くかどうかについて。試しにやってみたところ、やはりIconServices関連のルーチンがあやしいようだ。GetIconRefFromFile()なんかはちゃんと動いているみたいだけどIconSuiteToIconFamily()はだめ。ひょっとするとIconFamilyHandleに変換することは無理でも、IconRefを調べて描画するくらいはできるのかもしれないな。それなら、アイコンの管理をIconRefで行うようにすれば8.1でも動くかも知れない。これについてはもう少し調査が必要になりそうなのでまずは8.5.1上で正しく動くようになってからかな。

 久々に今日のToolbox。前回は99.11.19かな? MacOS 8.5以降、あるいはMacOS 8.1+CarbonLib 1.0.2以降が必要。

pascal OSStatus  GetWindowProperty
          (WindowRef     window,
           PropertyCreator  propertyCreator);
           PropertyTag    propertyTag,
           UInt32       bufferSize,
           UInt32       *actualSize,
           void        *propertyBuffer);
      

ウィンドウに設定されたプロパティを得る。

返り値      エラー。
window      調べたいウィンドウ。
PropertyCreator  プロパティーのクリエータ(OSType)。
PropertyTag    プロパティのタグ(OSType)。
bufferSize    プロパティをおさめるバッファのサイズ。
actualSize    指定したプロパティの実際のサイズ。
propertyBuffer  プロパティをおさめるバッファ。

#include  <MacWindows.h>



pascal OSStatus  GetWindowPropertySize
          (WindowRef     window,
           PropertyCreator  propertyCreator);
           PropertyTag    propertyTag,
           UInt32       *size);


ウィンドウに設定されたプロパティのサイズを得る。GetWindowProperty()を呼ぶ前にチェックすることになるのではないかと思う。

返り値      エラー。
window      調べたいウィンドウ。
PropertyCreator  プロパティーのクリエータ(OSType)。
PropertyTag    プロパティのタグ(OSType)。
size       指定したプロパティのサイズ。

#include  <MacWindows.h>



pascal OSStatus  SetWindowProperty
          (WindowRef     window,
           PropertyCreator  propertyCreator);
           PropertyTag    propertyTag,
           UInt32       propertySize);
           void        *propertyBuffer);


ウィンドウにプロパティを設定する。

返り値      エラー。
window      プロパティを設定するウィンドウ。
PropertyCreator  プロパティーのクリエータ(OSType)。
PropertyTag    プロパティのタグ(OSType)。
propertySize   指定するプロパティのサイズ。
propertyBuffer  指定するプロパティをおさめたバッファ。

#include  <MacWindows.h>


       

February 25, 2000 ↑ February index → March 3, 2000