OLEオートメーションの利用 (独自拡張)

 本BASICでは,OLEオブジェクトをFull BASICのモジュールに対応させて利用する。
 次の条件を満たせば,ActiveXなどのOCXの利用も可能。
  非表示(親ウィンドウを必要としない)
  ディスパッチインターフェースに対応している

OLEオブジェクトのモジュールへの割り当て

 モジュール名は任意の名前でよい。
 モジュールにOLEオブジェクトを割り当てる方法は2通りある。
 通常,モジュール本体にProgID(またはClassIDの文字列表現)を引用符で括ったものを引数とするOLE CretaeObject文を書く。この文は,OLEオブジェクトの生成を意味するが,実際には翻訳時に実行される。
例 ProgIDによる指定
OLE CreateObject "Word.BASIC"
例 ClassIDによる指定
OLE CreateObject "{000209FE-0000-0000-C000-000000000046}"

 もう一つの方法は,OLEオブジェクトのプロパティとして存在するオブジェクトをモジュールに割り当てるときに使う(後述)。
 
OLEメソッドの外部手続きへの割り当て

 メソッドは,モジュールの外部手続きに割り当てる。
 値を返すメソッドは外部関数に割り当て,external function行とend function行の間にOLE METHOD文を書く。結果の型が文字列の場合は文字列関数として,結果の型が数値かBOOL値のときは数値関数として定義する(文字列関数のときは,関数名の末尾に$を付加する)。
 値を返さないメソッドは外部副プログラムに割り当て,external sub行とend sub行の間にOLE METHOD文を書く。
 OLE METHOD文の引数には,引用符で括ってメソッド名を書く。
 手続きの引数の個数と型(数値と文字列の別)は,割り当てるメソッドのそれと一致させる。
 メソッド名は翻訳時に検査する。引数の型と個数の誤りは実行時に検出される。


 MS-Wordがインストールされていれば,次のプログラムが実行可能。
 160行から280行までのモジュールWordにOLEオブジェクトのWord.BASICを組み込んでいる。Word.BASICというProgIDはWindowsのレジストリに登録されている。
 モジュールで定義された外部手続きをモジュール外から使うために170行に示すようなPUBLIC文を書く。(外部関数の場合は,PUBLIC SUB文でなくPUBLIC FUNCTION文を書く)
 モジュールで定義された外部副プログラムを使うプログラム単位には,100行に示すようなDECLARE EXTERNAL文を書く。DECLARE EXTERNAL文で定義された外部手続きは,モジュール名を付加して書いても,モジュール名を省いて書いてもよい。(モジュール名を付加して書くと,110行は CALL Word.FileNew("") のようになる)外部関数を使う場合は,100行と同様の形式でDECLARE EXTERNAL FUNCTION文を書く。

100 DECLARE EXTERNAL SUB Word.Filenew, Word.Insert, Word.FileSaveAs
110 CALL FileNew("")
120 CALL Insert("この文字列が文書に挿入されます。")
130 CALL FileSaveAs("A:\TEST01.DOC")
140 END
150
160 MODULE Word
170 PUBLIC SUB FileNew, Insert, FileSaveAS
180 OLE CREATEOBJECT "Word.Basic"
190 EXTERNAL SUB FileNew(s$)
200 OLE METHOD "FileNew"
210 END SUB
220 EXTERNAL SUB Insert(s$)
230 OLE METHOD "Insert"
240 END SUB
250 EXTERNAL SUB FileSaveAs(s$)
260 OLE METHOD "FileSaveAs"
270 END SUB
280 END MODULE

OLEプロパティの外部手続きへの割り当て

 プロパティの設定は外部副プログラムに割り当てる。
 external sub行とend sub行の間にOLE PROPERTYPUT文を書く。その引数に,引用符で括ってプロパティ名を書く。副プログラムの引数が設定すべき値になる。
 配列型のプロパティの場合,添え字を引数として指定し,最後の引数に設定すべき値を書く。

 プロパティの読み出しは,外部関数に割り当てる。
 external function行とend function行の間にOLE PROPERTYGET文を書く。その引数に,引用符で括ってプロパティ名を書く。
 配列型のプロパティの場合,添え字は関数の引数で指定する。

利用可能なデータ型

 利用可能なデータ型は数値または文字列に限る。複素数や配列には対応していない。
 マイクロソフトの真偽値は数値の一部なので,数値に割り当てれば使える。OLEでは,真は-1,偽は0と定義されている。

プロパティとして存在するオブジェクトのモジュールへの割り当て

 OLE CREATEOBJECT文の代わりにOLE ASSIGN文をモジュールで実行すると,オブジェクトを参照する数値からモジュールにオブジェクトを割り当てることができる。この数値は,親オブジェクトのプロパティを読み出すことで得られる。
 プロパティの読み出しのとき,オブジェクト値をとるプロパティを指定すると,結果は,そのオブジェクトを参照する数値になる。この値は,必ず単一のOLE ASSIGN文に割り当てなければならない。(値を受け取るだけで止めたり,1回のプロパティ読み出しで取得した値を変数に割り当て,複数のOLE ASSIGN文に渡すようなことをしてはいけない)
 OLE ASSIGN文は,OLE CREATEOBJECT文と異なり,実行文である。OLE ASSIGN文でオブジェクトが割り当てられたモジュールでは,メソッド名,プロパティ名の検査は,最初にそれらが割り当てられた手続きが呼び出されるまで保留される。


 この例は,Word2002がインストールされているとき実行できる(他のバージョンのWordについてはテストしていない)。
100 DECLARE EXTERNAL FUNCTION Word.Documents
110 DECLARE EXTERNAL FUNCTION Word.Caption$
120 DECLARE EXTERNAL SUB Word.SetVisiBle
130 DECLARE EXTERNAL SUB Documents.SetDocuments, Documents.Open
140 DECLARE EXTERNAL SUB Selection.SetSelection, Selection.EndKey
150 CALL SetDocuments(Word.Documents)
160 CALL Open("C:\BASICw32\README.TXT")
170 CALL SetSelection(Word.Selection)
180 CALL SetVisible(-1)
190 WAIT DELAY 10
200 PRINT Caption$
210 CALL EndKey
220 END
230
240 MODULE Word
250 OLE CREATEOBJECT "Word.Application"
260 PUBLIC FUNCTION Selection,Caption$,Documents
270 PUBLIC SUB SetVisible
280 EXTERNAL FUNCTION Selection
290 OLE PROPERTYGET "Selection"
300 END FUNCTION
310 EXTERNAL FUNCTION Caption$
320 OLE PropertyGet "Caption"
330 END FUNCTION
340 EXTERNAL SUB SetVisible(n)
350 OLE PropertyPut "Visible"
360 END SUB
370 EXTERNAL FUNCTION Documents
380 OLE PropertyGet "Documents"
390 END FUNCTION
400 END MODULE
410
420 MODULE Documents
430 PUBLIC SUB Open, setDocuments
440 EXTERNAL SUB setDocuments(n)
450 OLE ASSIGN n
460 END SUB
470 EXTERNAL SUB OPEN(s$)
480 OLE METHOD "Open"
490 END SUB
500 END MODULE
510
520 MODULE Selection
530 PUBLIC SUB SetSelection, EndKey
540 EXTERNAL SUB SetSelection(n)
550 OLE ASSIGN n
560 END SUB
570 EXTERNAL SUB EndKey
580 OLE METHOD "EndKey"
590 END SUB
600 END MODULE

(Note)
 値を返すメソッドを関数に割り当てたとき,そのメソッドが引数として書いた変数の値を書き換えたとしても,その結果はBASICの変数には反映しない。
 本BASICはプログラムの実行が終わるとすぐにオブジェクトを削除するので,非同期で動作するOCXを使う場合は,OCXの動作が終了するまでプログラムの実行を終えないようにする。

イベント処理

 イベント処理を行う場合は,OLE CREATEOBJECTの引数に,ProgID(またはClassIDの文字列表現)を引用符で括ったものに続けて,コンマで区切って,イベント インターフェースのGUIDの文字列表現を引用符で括ったものを書く。
例 次のいずれかの形式で書く。
OLE CREATEOBJECT "xxxxx.xxxx","{1234567A-1234-1234-89AB-0123456789AB}"
OLE CREATEOBJECT "{12345678-1234-1234-89AB-0123456789AB}","{1234567A-1234-1234-89AB-0123456789AB}"

OCXからイベント処理のために呼び出される外部副プログラムをモジュール内に書き,そのexternal sub行の末尾にコンマで区切って「DispID」とそのイベントのDispIDを示す数値定数を書く。
例 EXTERNAL SUB OnEvnet(s$),DispID 2

<注意> 本BASICは,手続きが非同期で異なるスレッドから呼ばれてもよいようにできていない。OCXが非同期でイベント処理手続きを呼び出す場合は,BASIC本来のスレッドはWAIT文かPAUSE文を実行して実質的に休止状態にしておかなければならない。

<Note> OCXから呼ばれた手続きで実行したSTOP文はBASICプログラムの終了を意味しない。STOP文を実行したとき,BASICは手続きの実行を中断してOCXに例外を生成すべきことを伝える。それ以後の動作はOCXしだいである。デバッグウィンドウで中止を選択した場合も同様。

シグナル

 非同期で呼ばれるイベント処理手続きが処理の終了を知らせるのにシグナルを使うことができる。
 シグナルは英字で始まる名前で識別する(引用符で括らない)。

SIGNAL シグナル名
 シグナル名で識別されるシグナルを発する。
WAIT SIGNAL シグナル名
 シグナル名で識別されるシグナルが発せられるまで待機する。
WAIT SIGNAL シグナル名 TIMEOUT 数値式
 数値式で指定される時間(秒)が経過するか,またはシグナルを受信するまで待機する。
 指定可能な数値は最小0.01,最大429496729.5
 TIMEOUTを指定すると,Ctrl-Bを押しても待機中は中断しない。


<参考> 十進BASIC Q&A OLEオートメーション(OCXの利用)