シンボルテーブル



ここですること:
 ・新しいシンボルテーブルを追加する
 ・Color QuickDraw で遊ぶ




(1)シンボルテーブルとName List

 CompileItメニューから Name List を選ぶと、現在インストールされているシンボル名の一覧を見ることが出来ます。 CompileIt! はスクリプトをコンパイルする時、シンボルテーブルにアクセスするのではなく、この Name List を参照しながら作業をします。シンボルテーブル上で Add ボタンを押すということは、そのシンボルを Name List に追加することに他なりません。

 CompileIt! はかなり古いコンパイラで、初期状態では HyperCard 1.x と System6 の組み合わせでコンパイルするようになっています。(古い、というのは語弊がありますかね。「古いシステムに配慮した」と言い換えてもいいですが) マックのシステムは System7 で劇的に構造が変わり、ツールボックスの使い方にも違いが出ています。 ToolBox のルーチンは日々追加されており、より新しいシステムの機能を使うには、新しいシンボルテーブルを組み込む必要があります。

 シンボルテーブルは CompileIt! では少々頭の痛い問題です。HyperTalk との重複、新旧シンボルの混在、登録の手間とそれに伴うリスクなどを考えると、CompileIt! のシステムが必ずしも信頼に足る物ではないと感じることもあります。それでも私が CompileIt! を使い続けるのは、それらを補って余りある魅力があると思っているからですが...


(2)既存のシンボルテーブル

 まず買ったばかりの CompileIt! に含まれているシンボルテーブルを確認しましょう。
 CompileIt Names for ToolBox Access
  CompileIt! 独自の関数や定数定義などが入っています。
  ToolBox ルーチンではないので InsideMacintosh には載っていません。

 Useful ToolBox Commands & Functions
  ToolBox のうち、使用頻度の高いルーチンを集めたものです。

 ToolBox Variables & Fields
  ToolBox のうち、使用頻度の高い定数を集めたものです。

 High-Level File Manager
  ファイルマネージャのルーチンです。
  "High-Level" と言うのは比較的上位のルーチンという意味です。
  より細かな制御が必要な時は "Low-Level" ルーチンを使います。

 HyperCard 2 Names and CallBacks
  HyperCard が持つコールバックルーチンが定義されています。
  ToolBox ルーチンではないので InsideMacintosh には載っていません。
  製品版ハイパーカードのマニュアルや市販の解説書などに説明があります。

 Color QuickDraw Commands & Functions
  カラークイックドローのルーチンです。

 Print Manager Commands & Functions
  プリントマネージャのルーチンが含まれています。

 Custom Symbol Edit
  独自のシンボルを定義するためのツールです。

 SuperCard Commands & CallBacks
  スーパーカード独自のシンボルを定義したテーブルです。
 これらのシンボルテーブルには System6 でしか使えないシンボルと、System7 以降でも使えるシンボルとが混在しています。古いシンボルを Add してしまうと正しくないXが作られてしまう可能性があります。この回避方法についてこれから説明します。


(3)新しいシンボルテーブル

 CompileIt! の2枚ディスクのうち、CompileIt!ェ 2 of 2 の方に Symbol Table ト というフォルダがあります。この中には新しく追加された ToolBox ルーチンや、新しいシステムに対応したルーチンのシンボルが入っています。

 まず Symbol Table ト 直下にあるシンボルテーブルスタックを見てみましょう。ここにあるのは「追加の」テーブルで、ここにも System6 時代からあるルーチンが含まれています。

 スタック名 Error Code Names
   テーブル名 System Error Codes
     追加のエラーコード名

 スタック名 Low-Level File Manager
   テーブル名 Low-Level File Manager
     ファイルマネージャのうち PB の付くもの

 スタック名 Other Toolbox Names
   テーブル名 Other ToolBox Names
     その他のルーチンのシンボル

   テーブル名 Script Manager Names
     スクリプト(各国語サポート)ルーチン
     ※注意 System6 用です。System7 以降では使えません。

   テーブル名 Sound Manager Names
     サウンドマネージャのルーチン


 次に System 7 Updaters フォルダ内にあるシンボルテーブルスタックを見てみます。ここにあるのは System7 で追加されたものと、System7 で変更になったマネージャです。

 スタック名 Apple Events
   テーブル名 System 7 Events
    アップルイベント関連ルーチン

 スタック名 Color Quickdraw
   テーブル名 System 7 QuickDraw
    Color QuickDraw Commands & Functions に追加または修正するシンボル

 スタック名 Communications
   テーブル名 System 7 Network
    ネットワーク関連ルーチン

 スタック名 Errors
   テーブル名 System 7 Errors
    追加のエラーコード名

 スタック名 General
   テーブル名 System 7 General
    その他の、System7 で新しくなった、または追加した機能
    ( Help/Balloon/TextEdit/Notification/Memory/Time )

 スタック名 Object Support Library
   テーブル名 Object Support Library
    アップルスクリプト関連ルーチン

 スタック名 Scripts
   テーブル名 System 7 Scripts
    System7以降用のスクリプト(各国語サポート)ルーチン

 スタック名 System 7 Files
   テーブル名 System 7 File Routines
    System7 で新たに加わったファイルルーチン

 スタック名 System 7 Other
   テーブル名 System 7 Other
    その他の、System7 で新しくなった、または追加した低レベルルーチン
    ( sound/slot/process/SCSI/power/SANE )


 最後に New Table フォルダ内にあるシンボルテーブルスタックです。ここにあるのは当初システムのオプションとして用意されていた機能ですが、ドラッグマネージャは現在システムの一部になっています。

 スタック名 Drag Mgr
   テーブル名 Drag Manager
   ドラッグマネージャ関連ルーチン

 スタック名 QuickTime
   テーブル名 QuickTime
    QuickTime ムービー関連ルーチン

   テーブル名 QuickTime Tools
    QuickTime ムービー関連ルーチン
    ※注意 ここにあるシンボルは壊れています。
        インストールする場合は私のホムペにあるものを使って下さい。


(4)テーブル追加の問題と実際

 さて、これだけのシンボルテーブルがあると結構混乱しますが、別にどーと言うこともありません。全部インストールしちゃいましょう。各スタック上で "Install Names in CompileIt!" ボタンを押すだけで CompileIt! スタックにカードが追加され、以後 Add ボタンで各シンボルが使用可能になります。

 ただし・・・

 最初から CompileIt! に含まれているシンボルテーブルには、古くて使えないシンボルと、今でもそのまま使えるシンボルとが混在しています。新しいテーブルが古いテーブルをそっくり置き換えるものであるなら古いものを丸ごと削除すればいいのですが、今でも使えるルーチンを含んでいる以上、古いテーブルは温存しておかなければなりません。

 ここでシンボルテーブルと Name List の関係を思い出して下さい。 Add されたシンボルは Name List に追加されます。そしてコンパイル時には Name List だけが参照されます。もしも新旧のテーブル上に同名のシンボルがあった場合、Name List には最後に Add したシンボルの内容だけが登録されます。(これ重要)
 問題は、古いテーブルのシンボルを「うっかり」 Add してしまった場合です。この場合は Name List 上には古いシンボルが登録され、仮にスクリプトが正しくても、正しくないXが作られてしまいます。(再度新しいシンボルを Add してコンパイルし直せば、正しいXが作られるでしょう。スクリプトが正しければ、ですが)


 このトラブルを防ぐために、以下の手順を踏んで、確実に新しいシンボルを登録するようにします。そして古いシンボルテーブルは以後なるべく触らないようにします。

 (1)まずはシンボルが何も登録されていない CompileIt! を用意します。確実なのは、オリジナルの CompileIt! をコピーすることでしょう。

 (2)全てのシンボルテーブル上で "Add All" ボタンを押して、一旦全てのシンボルを登録します。( SuperCard のものは不要なら省略)

 (3)Symbol Table ト フォルダにある全てのスタックの全てのテーブル上で "Install Names in CompileIt!" ボタンを押して、シンボルテーブルを CompileIt! に取り込みます。
 ただし Symbol Table ト フォルダ直下にある Other Toolbox Names スタックの Script Manager Names シンボルテーブルは除外して下さい。これは System6用のシンボルですので、全く不要です。
 また、QuickTime Tools シンボルテーブルは壊れてますので、これも除外して下さい。QuickTime プログラミングをしたい場合は、私のホムペから修正版のシンボルテーブルをダウンロードして使って下さい。

 (4)新規に取り込んだ全てのテーブル上で、"Add All" ボタンを押します。この時点で、更新されるべきシンボルは更新( Name List 上に上書き)されます。気を付けなければならないのは古い(最初から CompileIt! に含まれていた)シンボルテーブルには触らないことです。もしここで古いシンボルを Add してしまうと何にもなりません。

 大切なのは、(2)と(4)の手順です。まず古いものを登録してしまってから、新しいものを上書きします。こうすることで、古いシンボルを排除して、新しいシンボルのみを Name List に残すことが出来ます。


 本当は RoyalSoftwere が System7 対応の新しいシンボルテーブルを整備してくれればいいのですが、当面はこのような消極的な方法で凌ぐしかありません。そもそも追加のシンボルテーブルの使い方さえもマニュアルに載っておらず、私もやっと最近手探りで理解したところです。OS8用のシンボルが提供される様子も無く、全く寂しい限りです。
 もしスクリプトをコンパイルしてど〜しても納得の行かないエラーが出た時は、この順序でシンボルテーブルを登録し直してみて下さい。私はこの罠にハマって(具体的には古い ColorQuickDraw のシンボルを使ってしまって)、数カ月も苦しいんだことがあります(^^;)


 特定のテーブル上のシンボルを全て削除したい時は Remove All ボタンを使って下さい。このボタンを押すと、そのテーブル上にある全てのシンボルが Name List から削除されます。また個別に削除したいときはシンボルにマークを付けた上で Remove ボタンを押します。CompileIt! はシンボルの名前だけでなくその定義を見て Name List を管理しているので、他のテーブルの同名のシンボルが Name List 上にあっても、そのシンボルは削除されません。逆に、既に登録されているシンボルと同名のシンボルを Add すると、Name List 上ではそのシンボルが上書きされます。

 これらシンボルテーブルと Name List の関係をきちんと理解していれば、シンボルテーブルの更新もそれほど恐いものではありません。またシンボルの Add 時に時折(もしくは頻繁に)「重複しているシンボルがあるよ」という警告が出ますが、これは基本的には無視しちゃうしか無いでしょう。複数あるシンボルのどちらを生かすかは、個々のXによって事情が異なるからです。


 シンボルテーブルの管理は CompileIt! の宿命であり、弱点のひとつです。しかし実はどんな開発環境であっても(例えば CodeWarrior でも)ルーチン定義の管理には面倒がつきものなのです。どうか宜しくご理解の上、優しい気持ちで付き合ってあげて下さい(^^;)


(5)カラーQDを使ってみる

 さて今回はインストールしたばかりの Color QuickDraw を使って遊んでみましょう。

 ハイパカのカードピクチャーはハイパカが管理しており、特殊な方法を使わないといじることが出来ませんが、ウィンドウ自体は普通のウィンドウなので、そこに色々なものを描くことが出来ます。もちろん前回と同様、カード移動やアプリの切替等で画面の更新が起きると消えてしまいますが、逆に言えば何をしても良い遊び場みたいなもので、心置きなくいたずらすることが出来ます(笑)


 まず前回の「ランダムな図形を描く」スクリプトを「ランダムな図形をランダムな色で描く」スクリプトに改造してみます。

-- CompileIt! Script
global myRect: R[8], cdRect: R[8]                          -- Rect 構造体
global myRGB: R[6], saveRGB: R[6]                          -- RGB 構造体

on drawRandomColor
  GetPort cdPort                                           -- カレントポート
  put cdPort@.portRect.topLeft into cdRect.topLeft         -- レクト左上
  put cdPort@.portRect.botRight into cdRect.botRight       -- レクト右下
  put cdRect.bottom into vMax
  put cdRect.right into hMax
  --
  SetPort cdPort                                  -- 描画対象ポートを明示
  GetForeColor saveRGB                            -- 現在のフォアカラーを保存
  EraseRect cdRect
  --
  repeat 1000
    put random($FFFF) into myRGB.red              -- RGB の赤をランダムに設定
    put random($FFFF) into myRGB.green            -- RGB の緑をランダムに設定
    put random($FFFF) into myRGB.blue             -- RGB の青をランダムに設定
    RGBForeColor myRGB                            -- 描画色をランダムに変える
    put random( vMax ) - trunc( vMax/3 ) into myTop
    put random( hMax ) - trunc( hMax/3 ) into myLeft
    put myTop + random( vMax ) - trunc( vMax/2 ) into myBottom
    put myLeft + random( hMax ) - trunc( hMax/2 ) into myRight
    SetRect myRect, myLeft, myTop, myRight, myBottom
    put random( 8 ) into myJob
    if myJob = 1 then FrameRect myRect
    if myJob = 2 then PaintRect myRect
    if myJob = 3 then EraseRect myRect
    if myJob = 4 then InvertRect myRect
    if myJob = 5 then FrameOval myRect
    if myJob = 6 then PaintOval myRect
    if myJob = 7 then EraseOval myRect
    if myJob = 8 then InvertOval myRect
  end repeat
  RGBForeColor saveRGB                            -- 描画色を戻す
end drawRandomColor


 前回と変えたところだけ注釈を入れてあります。

 カラークイックドローには色指定に「カレント」という考え方があって、暗黙のうちにグラフポートに設定されているフォアカラー(描画色)で描画をするようになっています。そのフォアカラーを変更する命令が RGBForeColor で、ここではこれをランダムに変えて色付きのレクトや円に色を描いています。

 カードのレクトを得る部分が少し変わりました。
 まず GetPort でカレントのグラフポートを得ています。 XCMD に実行が移った時には必ずカードウィンドウがカレントになっているので、こうすることによってカードウィンドウのグラフポートが得られます。ここで得られるのはグラフポート構造体へのポインタです。グラフポート構造体の各メンバーにアクセスする時は @ が必要です。
 次にグラフポート構造体のメンバーのひとつである、portRect構造体を読んでいます。 portRect には常にそのグラフポートのレクトが入っているので、このレクトの中の topLeft を cdRect の topLeft に、botRight を cdRect の botRight に書き込むことによって、グラフポートのレクトを共有変数 cdRect にコピーしています。(8バイトいっぺんにコピーすることは出来ないので、4バイトづつに分けています)
 前回のやりかたでもなんら問題はありませんが、まぁ ToolBox らしく書くならこっちが正統派ですね。ただしデバッガを使う場合は少し注意が必要です。デバッガ起動状態では GetPort はデバッガ画面のグラフポートを返します。この回避策についてはまたいつか。

 RGB構造体は各色16ビット(2バイト)*3色の、計6バイトです。
 XCMD 終了時に元に戻すために、GetForeColor で現在の RGB値を取り出して、共有変数 saveRGB に保存しておきます。
 R G B のそれぞれの色は .red、.green、.blue でアクセス出来ます。共有変数 myRGB の各メンバーにランダムな値(16ビット=65535=$FFFF 以内)を書き込んで、RGBForeColor でフォアカラー(描画色)に指定しています。ちなみにバックカラーはウィンドウを消去する時の色で、これを変更すると EraseRect に影響します。デフォルトでは白( $FFFFFFFFFFFF )になっています。

 あとの描画部分は前のものと同じです。フォアカラーをランダムに変えることによって、ランダムな色の図形が描かれます。
 描画に入る前に SetPort で描画ポートを明示的に指定していますが、これはやらなくても大丈夫です。元々カードウィンドウがカレントになっているのですからわざわざ指定する意味は余りありません。ですが、SetPort はしつこいくらいにやっておく癖をつけておいた方がいいようです。明示的に SetPort しなかったばかりにおかしな動作に悩まされることが少なくありません。転ばぬ先の杖、ですかね。

(6)Picture の表示

 線や四角ばかり描いていてもつまらないので、今度はピクチャーを表示してみましょう。

 まずスタックをひとつ作って下さい。これを ResEdit で開き、ピクトリソースをひとつ入れます。カードの半分くらいの大きさのものがいいでしょう。このピクトをカードウィンドウに表示する XCMD を作ってみます。
-- CompileIt! Script
global picRect: R[8], myLoc: L

on drawingPicture tgPic, where

  GetPort cdPort 
  SetPort cdPort
  
  put GetNamedResource( "PICT", tgPic ) into picHand
  if picHand = 0 then
    put GetResource( "PICT", tgPic ) into picHand
  end if
  if picHand = 0 then
    return "Error : Not found PICT resource"
  end if
  
  if the number of items of where > 2 then
    StrToRect where, picRect
  else
    put picHand@@.picFrame.topLeft into picRect.topLeft
    put picHand@@.picFrame.botRight into picRect.botRight
    StrToPoint where, myLoc
    OffsetRect picRect, myLoc.IntegerType[2], myLoc.IntegerType[1]
  end if
  
  DrawPicture picHand, picRect
  
end drawingPicture
 このXは第1引数にピクトリソースの名前、もしくはIDを必要とします。第2引数はオプションで、ピクトを表示する座標、もしくはレクトです。

 まずは第1引数の処理です。リソースを読むときは ID で検索する GetResource か、 名前で検索する GetNamedResource を使います。このプログラムでは渡された値をまず名前と仮定して GetNamedResource し、それで見つからなかったら渡された値をIDと仮定して GetResource しています。こうすることによって名前でもIDでも受付けつけられるような、柔軟なXを作ることが出来ます。どちらの方法でも見つからなかった時はエラーを返して終了します。

 第2引数は座標、もしくはレクトを処理します。まず the number of items でアイテムの数を数え、2以上だったらレクト文字列が渡されたと判断して処理します。
 アイテムの数が3未満だった場合は座標とみなしますが、その座標位置へピクトを置いた場合にどのようなレクトをなるのかを計算しなければなりません。ピクトの表示にはポイント(座標)ではなくレクトが必要なのです。
 まず、ピクトリソース自身の持つレクトを得ます。ピクト構造体の中には .picFrame 構造体があって、ここにピクト自体のレクト情報が入っています。これを共有変数 picRect にコピーします。ハンドル経由のアクセスなので @ を2つ使っていることに注意。
 それからこのレクトを指定座標に移動します。OffsetRect はレクトを指定ピクセルだけ移動するルーチンで、第1引数にレクト構造体、第2引数に水平方向の移動量、第3引数に垂直方向の移動量を渡します。 myLoc は座標値なので、IntegerType[2] が水平座標、IntegerType[1] が垂直座標です。
 引数 where に座標情報が入っていると決めつけて StrToPoint に渡していますが、もし where が省略されて何も無かった場合でも問題にはなりません。この場合は myLoc に座標 0,0 が入ります。つまり第2引数省略時には座標 0,0 からピクトが表示されることになります。

 ここで使っている IntegerType は少し説明が必要ですね。
 シンボルテーブルの CompileIt Names for ToolBox Access を見ると、汎用のフィールド定義が並んでいます。例えば IntegerType はオフセット0の2バイトと定義されているので、構造体の中の最初から2バイトを取り出すのに使える定義です。同様に CharacterType は1バイト、HandleType や LongintType は4バイトを取り出します。更に配列の添字を付けることで、例えば IntegerType[2] なら2番目の整数、つまりオフセット2の2バイトを取り出せます。HandleType[2] の場合はオフセット4の4バイトになります。(要素の大きさによってオフセット量が変わることに注意)
 これらの定義は汎用に使えるので覚えておくと良いでしょう。例えば RGB構造体の blue メンバーにアクセスするには myRGB.integerType[3] という書き方が出来ます。ただし CompileIt! の(=アップルの)定義定数を使った方が見やすいのは言うまでもありません。
 座標のアクセスには実は .h、.v というメンバがちゃんと登録されていて、それぞれ水平座標、垂直座標を取り出すのに使えるのですが、h とか v とかは変数名でときどき使いたいことがあるので、私は敢えて Remove しています。良い子はちゃんと登録して、myLoc.h とか myLoc.v のような書き方をしましょう(^^;)

 ピクトリソースのハンドルが得られ、表示するレクトも決まりました。あとは DrawPicture コマンド一発で描画されます。例によってカード移動などで消えてしまうはかない画像ですが、まぁいろいろ遊んで下さい。


(7)ついでにカラーアイコン

 同じような手順でアイコンが表示出来ます。 "ICON" リソースは GetResource の代わりに GetIcon ルーチンを使ってリソースハンドルを得ます。描画するのは PlotIcon です。また "cicn" も簡単に表示できます。 GetCIcon でハンドルを得て、PlotCIcon で表示します。これらは簡単なのでおのおの自習するように。


 どうでしょうか。カード移動で消えてしまう画像とは言え、QuickDraw で遊ぶには充分と思います。ピクトやアイコンはシステムに便利なルーチンが用意されているためかなり簡単に描くことが出来ます。テキストも画像として描くだけなら簡単なのですが、スクロールさせたり編集させたりするには TextEdit というマネージャを使わねばならず、少々しんどい思いをすることになります。ま、これは上級用としてまたいつか。


inserted by FC2 system
Next



CompileIt! Lab.

UDI's HomePage