C++BuilderからVBScriptやJScriptを使うには、「Microsoft Script Control」を使用します。
メニューから[ファイル]-[新規作成]-[VCL フォームアプリケーション]を選択します。
新しいプロジェクトが作成されます。
メニューから[コンポーネント]-[コンポーネントのインポート]を選択します。
「コンポーネントのインポート」ダイアログが表示されます。
「タイプライブラリの取り込み」を選択して、「次へ」ボタンをクリックします。
「登録されたタイプライブラリ」から「Microsoft Script Control 1.0」を選択して、「次へ」ボタンをクリックします。
「ユニットディレクトリ名」にユニットを保存するディレクトリを選択して、「次へ」ボタンをクリックします。
「パレットページ名」は、パレットに登録しないので「(none)」のままにします。
「Project1.bdsprojプロジェクトにユニットを追加」を選択して、「完了」をクリックします。
フォームに1 行編集コントロール(TEdit)を2つと、プッシュボタンコントロール(TButton)コントロールを1つ、配置します。
Button1をクリックすると、VBScript(またはJScript)を使ってEdit1の式を計算し、結果をEdit2に表示します。
Unit1.h
「Microsoft Script Control」を使用するので、ヘッダに #include "MSScriptControl_OCX.h" を、private変数としてTScriptControl* を追加します。
#include "MSScriptControl_OCX.h"
private:
TScriptControl* ScriptControl;
Unit1.cpp
フォームのコンストラクタでTScriptControlの設定を行います。
プログラミング言語に VBScript を使用する場合は ScriptControl->Language に VBScript を、JScript を使用する場合は JScript を指定します。
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ScriptControl = new TScriptControl(this);
ScriptControl->Language = "VBScript";
}
ボタンを押したときのイベントです。
TScriptControl::Eval() でスクリプトを実行します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString src = Edit1->Text;
AnsiString result = VarToStr(ScriptControl->Eval(WideString(src).c_bstr()));
Edit2->Text = result;
}
実行時に実行する関数を選択するサンプルプログラムです。
フォームに複数行編集コントロール(TMemo)と、ラジオボタングループ(TRadioGroup)、プッシュボタンコントロール(TButton)を配置します。
複数行編集コントロール(TMemo)のLinesプロパティに実行する関数を登録します。
Function CurrentTime
MsgBox FormatDateTime(Now())
End Function
Function CurrentDate
MsgBox FormatDateTime(Date())
End Function
CurrentTimeは現在の日時をメッセージボックスに表示する関数、CurrentDateは現在の日付をメッセージボックスに表示する関数です。
ラジオボタングループ(TRadioGroup)のItemsプロパティに、実行する関数の選択肢を登録します。
CurrentTime
CurrentDate
プッシュボタンコントロール(TButton)のOnClickイベントに次のコードを登録します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TScriptControl* sc = new TScriptControl(this);
sc->Language = "VBScript";
sc->AddCode(WideString(Memo1->Lines->Text).c_bstr());
AnsiString function = RadioGroup1->Items->Strings[RadioGroup1->ItemIndex];
sc->Eval(WideString(function).c_bstr());
delete sc;
}
TScriptControl#AddCode()で関数を登録し、TScriptControl#Eval()で関数名を指定して実行します。
実行する関数を選択してボタンを押すと、選択した関数が実行されます。
引数を渡して関数を実行するサンプルプログラムです
フォームに1 行編集コントロール(TEdit)を2つと、プッシュボタンコントロール(TButton)コントロールを1つ、配置します。
プッシュボタンコントロール(TButton)のOnClickイベントに次のコードを登録します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TScriptControl* sc = new TScriptControl(this);
sc->Language = "VBScript";
//関数の登録
AnsiString code = "Function Add(val1, val2)\n"
" MsgBox val1 + val2\n"
"End Function";
sc->AddCode(WideString(code).c_bstr());
//引数の設定
Variant v = VarArrayCreate(OPENARRAY(int, (0, 1)), varVariant);
v.PutElement(Edit1->Text.ToInt(), 0);
v.PutElement(Edit2->Text.ToInt(), 1);
PSafeArray params = TVarData(v).parray;
sc->Run(WideString("Add").c_bstr(), ¶ms);
delete sc;
VBScriptの関数Addは引数を2つ受け取り、引数の和をメッセージボックスに表示します。
ボタンを押すと、Edit1とEdit2の値を関数に渡します。
関数の返値を受け取るサンプルプログラムです。
フォームに1 行編集コントロール(TEdit)を3つと、プッシュボタンコントロール(TButton)コントロールを1つ、配置します。
プッシュボタンコントロール(TButton)のOnClickイベントに次のコードを登録します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TScriptControl* sc = new TScriptControl(this);
sc->Language = "VBScript";
//関数の登録
AnsiString code = "Function Add(val1, val2)\n"
" Add = val1 + val2\n"
"End Function";
sc->AddCode(WideString(code).c_bstr());
//引数の設定
Variant v = VarArrayCreate(OPENARRAY(int, (0, 1)), varVariant);
v.PutElement(Edit1->Text.ToInt(), 0);
v.PutElement(Edit2->Text.ToInt(), 1);
PSafeArray params = TVarData(v).parray;
//関数を実行し、返値を受け取る
Variant ret = sc->Run(WideString("Add").c_bstr(), ¶ms);
Edit3->Text = VarToStr(ret);
delete sc;
}
VBScriptの関数Addは引数を2つ受け取り、引数の和を返します。
ボタンを押すと、Edit1とEdit2の値を関数に渡し、関数の返値をEdit3に表示します。
スクリプトのエラーを拾うには、TScriptControl::Errorイベントを使用します。
//エラーが発生したときは OnError メソッドを呼ぶ
ScriptControl->OnError = OnError;
//エラーが発生したときの処理
void __fastcall TForm1::OnError(TObject* Sender)
{
//エラーの行
long ErrorLine = ScriptControl->Error->get_Line();
//エラーの列
long ErrorColumn = ScriptControl->Error->get_Column();
//エラーメッセージ
AnsiString ErrorDescription = ScriptControl->Error->get_Description();
MessageDlg(Format("エラー(行:%d、列:%d)%s", ARRAYOFCONST((ErrorLine, ErrorColumn, ErrorDescription))),
mtWarning, TMsgDlgButtons() << mbOK, 0);
}