|
Technote 1020
Color Cursing: Two Major Causes
このテックノートの変更経歴
このテックノートは1989年6月にリリースされました。
'clut'リソースの注意事項は1996年2月に追加されました。
SetCCursor ()がGDeviceを変更することや、メモリを動かすことについての注意事項は1997年12月に追加されました。
カラーカーソルを使う
カラーカーソルを利用する際にシステムエラーやクラッシュを引き起こさないためにも、アプリケーション開発は以下の点に注意して進めて下さい。
カーソルの枠
例えば、縦横15 x 9ピクセルのカーソルがあれば、カーソルのバウンド枠(bounds.bottomとbounds.right)は上記の値にしがちですが、上記のような値は絶対に使わないで下さい。このカーソルのビットマップが拡張される場合(例えば、2ビットカラーで構成されているカーソルが8ビットカラーの画面に展開された場合)、SetCursor ()の四捨五入計算のため、ビットマップの横幅は8ピクセル分しか割り当てられません。拡張されたビットマップの溢れた部分はアプリケーションヒープに書き込まれてしまいます。
この問題をさけるためにはpixmapHandle^^.boundsを縦横16 x 16に固定して下さい。こうすることによって、SetCursor ()はカーソルのビットマップを正しく拡張します。また、実際に描画されるデータの量はカーソルのピクセルの値や'clut'リソースに依存しますので、枠を16 x 16より小さくして数バイト稼ごうとしても効果はほとんどありません。
折の悪い'clut'リソースのパージ
カラーカーソルのカラーテーブルをGetCTable ()で'clut'リソースから読み込む場合、カラーカーソル使用中は'clut'がpurgeableではないことを確認して下さい。折の悪いタイミングで'clut'がパージされると、システムはクラッシュします。
詳しくはInside Macintosh: Imaging with QuickDraw「Cursor Utilities」をご覧下さい。
SetCCursor ()はGDeviceを変更することがあります
システムソフトウェアバージョン7.5.2以降では、カーソルのビットマップはCopyBits ()を使ってオフスクリーンのGWorldで作成されます。このため、SetCCursor ()は以下のような一般的なコードで現在のポートとデバイスを保存します。
{
GetGWorld (&savePort, &saveDevice);
SetGWorld (offPort, NULL);
... CopyBits ()などのその他のコード
SetGWorld (savePort, saveDevice);
}
|
SetGWorld ()の副作用として、GWorldポートを渡した場合、デバイスパラメータは無視されます。現在のポートがGWorldポートの場合、SetCCursor ()を呼び出した結果として、デバイスがGWorldのデバイスとなります。
ポートがGWorldポートとなっている状態の時にSetCCursor ()を呼び出すと以下のような危険性があります。DisposeGWorld ()はGDeviceを安全な値に設定しますが、ポートは設定されません。このように、有効なポートがない状態でSetCCursor ()を呼び出してしまうと、GDeviceは捨てられたGDeviceに設定され、直後にコンピュータがクラッシュします。
このSetCCursor ()の副作用を避けるためには以下の点に注意して下さい。
- ポートとデバイスが常に一致していることを確認して下さい。ポートとデバイスが一致していないとカラーカーソルに関する様々な問題が発生します。
-
- 現在使われているポートは絶対に捨てないで下さい。必ず有効なポートに切り替えてから、現在のポートを捨てて下さい。捨てられたポートやデバイスに描画をすると、ほとんどの場合はクラッシュを引き起こすことになります。
割り込み時にSetCCursor ()を呼び出さない
SetCCursor ()はメモリを動かすことがあります。特に、システムソフトウェアバージョン7.5.2以降ではSetCCursor ()はCopyBits ()などのQuickDraw関数を多く呼び出します。割り込み時は絶対にSetCCursor ()を呼び出さないで下さい!ただし、割り込み時に白黒のSetCursor ()を呼び出すことは構いません。
参考文献
|