X作成講座 on FB[02]  (1)テンプレートの書き換え


 さて実際に XCMD を作ってみましょう。一番単純なXの例として、2つの値を渡すとその合計を返す XFCN "tasu" を作ります。

 作業は大きく分けて HyperXcmd.MAIN(テンプレート) の書き換え、ソース入力、STR#リソースの準備、の3つに分けられます。「また HyperXcmd.MAIN を書き換えるの?」と思われたかも知れませんが、このファイルはあくまでテンプレートであり、XCMD を作るたびにその XCMD 用に書き換えて使うように出来ているのです。


             −・−・−


 まず XCMD テンプレート フォルダをコピーします。分かり易いように "tasu.x folder" とでも名前を変えて下さい。この中の HyperXcmd.MAIN をダブルクリックしてFBII を立ち上げます。

 説明しやすいように、ソースに行番号を付けて下さい。「編集」メニューの「プレファランス...」で右側にある「行番号を表示」にチェックを入れます。


 では、テンプレートを解説しながら説明します。
 書き換えの必要なところは "#" を付けてあります。

00006 GLOBALS "HyperXcmd.GLBL"                    'get our globals file first
00007 END GLOBALS
 ここでグローバル変数を定義したファイルを読んでいます。
 HyperXcmd.GLBL には XCMD 作成に必要なグローバル変数が定義されています。

00009 RESOURCES "", "STAKWILD", "XCMD", 6011, "<xcmd name>",_resPurgeable%
 コードリソースとしてコンパイルするための設定をしています。
 各パラメータの意味はリファレンスマニュアルを参照して下さい。
 # XFCN を作る場合は "XCMD" を "XFCN" に書き換えます。
 # 6011 を希望するリソースIDに書き換えます。
 # <xcmd name> に XCMD の名前 "tasu" を入れます。

00011 OUTPUT FILE "<stack name>"                  'add xcmd to target stack
 # <stack name> に XCMD をインストールするスタック名を入れます。

00013 INCLUDE "HyperXcmd Events.INCL"             'load your own xcmd routines
 XCMD で必要になるイベント処理ファイルを読んでいます。
 外部ウィンドウを作る場合にのみ必要です。
 不要ならコメントアウトしてしまって構いませんが、その場合は
 イベントに関連するものを全てコメントアウトして下さい。

00015 ENTERPROC% (xCmdPtr&)                       'use % because we are making a code rsrc
 ここからプログラムがスタートします。
 xCmdPtr& には HyperTalk と値をやりとりするためのメモリブロックの
 アドレスを受け取っています。

00016   DIM rect;8
00017   DIM 63 title$
 必要ならここに DIM文を入れます。このテンプレートでは rect と title$ を
 定義していますが、多分外部ウィンドウを作成するために入れたあとで、
 削除するのを忘れたのでしょう。
 今回は不要なのでコメントアウトしてしまって構いません。

00019   LONG IF xcmdID% = 0
00020     xcmdHndl& = FN RECOVERHANDLE (REGISTER(a4))'get handle to xcmd
00021     LONG IF xcmdHndl&                       'we got a handle?
00022       CALL GETRESINFO (xcmdHndl&, xcmdID%, type&, tmp$)'get rsrc ID of xcmd
00023     END IF
00024     % REGISTER(A4) + _drvrMenu, xcmdID%     'set xcmd to read STR# ID
00025   END IF
 ここでは XCMD 自身の ID を xcmdID% に入れ、それを A4 レジスタに入れています。
 これは XCMD と同じ ID の STR# リソースを読むための準備です。

00026   CALL GETPORT(hcPort&)                     'save original port
 オリジナルのグラフポートを保存しています。
 外部ウィンドウを使わないのであれば不要ですが、もしこの行をコメントアウト
 するなら、hcPort& を使っている全ての行をコメントアウトする必要があります。

00027   xCmdPtr&.passFlag% = _false               'keep HC from passing msg on
 パスフラグを false にしています。
 ここを true にすると HyperTalk の pass xxx と同じ動作をします。

00029   prmCount% = xCmdPtr&.paramCount%          'get parameter count
 XCMD に渡された引数の数を prmCount% に入れています。
 通常、HyperTalk から XCMD が呼ばれた時は、引数の数がここに入ります。
 ところが外部ウィンドウを作成する XCMD では、HyperTalk から呼ばれる以外に
 HyperCard から「イベントが起きたよ」と呼び出される場合があります。
 イベントによって XCMD が呼ばれた時は、prmCount% に -1 が入ります。
 以下の IF 文ではこれを利用してイベント処理を分けています。

00030   LONG IF prmCount% => 0                    'just passing some parameters
 通常の XCMD 呼び出しならば・・・

00031     LONG IF prmCount% <= _maxParams         'is paramcount count correct?
 引数の数が設定範囲内ならば・・・
 # この _maxParams は HyperXcmd.GLBL ファイル内で設定されています。
 # ソースをどう分けて管理するかにもよりますが、この値は XCMD ごとに
 # 異なるので、私はここに直接値を書き込んでしまうのが良いと思います。
 # 例えば引数を2つまで許すなら LONG IF prmCount% <= 2 とします。

00033       LONG IF prmCount% <> 0
00034         FOR j = 0 TO prmCount% - 1          'cycle thru parameters
00035           FN ZeroToPas (xCmdPtr&, [[xCmdPtr& + _params + j * 4]], str255$(j))
00036         NEXT                                'C string to P string
00037       END IF
 各引数文字列(C文字列)を str255$() という文字列配列に格納しています。
 当然 256バイト以降の文字は切り捨てられます。

00038       CALL INITCURSOR                       'reset our cursor
 カーソルをアローカーソルに設定しています。
 外部ウィンドウを扱う場合に必要です。
 # 外部ウィンドウを扱わないのならコメントアウトした方が良いでしょう。

00040       SELECT UCASE$(str255$(0))             'check first parameter value
 第1引数の値によって分岐します。

00041         CASE "!"                            'if '!' then return version info in msg
00042           FN ReplyToQuery (xCmdPtr&, _versionInfo)'send info
00043
00044         CASE "?"                            'if '?' then return usage info in msg
00045           FN ReplyToQuery (xCmdPtr&, _usageInfo)'send info
 もし "!" が渡されたら、バージョン情報を返します。
 もし "?" が渡されたら、書式情報を返します。
 この2つは XCMD の標準的なインターフェースです。
 バージョンと書式情報の返し方は後述しますが、FBではリソースを
 利用するようになっています。

00047         CASE ELSE
00048                                             'handle normal xcmd parameters
 "!" でも "?" でもなかったら自前のルーチンを実行します。
 # ここ(00048)に XCMD/XFCN のプログラム本体を書きます。
 # 長くなりそうなら呼び出し部分だけをここに書いて、
 # 本体を書いた別ファイルをインクルードするようにすると良いでしょう。

00051     XELSE
00052       FN ErrorHandler (xCmdPtr&, _wrongParams)'if paramcount incorrect
00053     END IF                                  'paramCount > 0
 引数の数が規定値より大きかった場合のエラー処理です。
 XELSE は 00031 からの分岐です。

00055   XELSE
00056                                             '
00057     FN HandleHCEvent (xCmdPtr&)             'handle all windoid events here
 prmCount% が -1 だった場合、つまりウィンドウを持つ XCMD で
 イベントによる呼び出しを受けた場合の処理です。
 XELSE は 00030 からの分岐です。
 外部ウィンドウを扱わないXでは、ここが実行されることがありません。

00060   CALL SETPORT(hcPort&)                     'restore original port
 外部ウィンドウを使う場合は XCMD 中でカレントポートを移動するので、
 ここで元に戻しています。
 外部ウィンドウを使わないのであればコメントアウトして構いません。


 以上で HyperXcmd.MAIN の書き換えは一旦終了です。この書き換えは XCMD を作る度に必要になります。これって結構面倒なんですよね(笑)
 このテンプレートは外部ウィンドウを作ることを前提として作られているので少々複雑ですが、慣れてくると何が必要で何が不要なのかが分かってきます。外部ウィンドウを使わない自分用のテンプレートを用意しておくと便利かもしれません。

 何カ所か「?」な部分が残ったと思いますが、以後順次説明を加えていきます。


Next



FutureBASIC Lab.

UDI's HomePage
inserted by FC2 system