ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

スクリプトによる拡張1

2009年4月9日公開

自分で作ったプログラムに、マクロ言語(スクリプト言語といった方が通りが良いか)による拡張を行えるようにする機能を実装することを考える。

例えば、ExcelであればVBAによって処理の自動化や機能の拡張ができるようになっている。あれと同じようなことを実現してみる。

とは言っても、VBAそのものを実装するのは容易ではないため、とりあえずVBScriptを使うものとする。これだったら、それ程難しくなく組み込むことができる。

概要

Microstftは、アプリケーションに組み込んで使うことができるVBScriptやJScriptの処理系として、MSScript.ocxというコンポーネントを公開している。というか、デフォルトでWindowsに入っている。だから、これを使ってやることにする。

MSScript.ocxは拡張子がocxであることから判る通りCOMコンポーネントである。だから、アプリケーションは、このCOMコンポーネントのインターフェースを取得して、そいつを使ってやるようにしなければならない。

だから、このページに記載されている方法を実施するには、少なくともCOMに関するプログラミングの知識が必要になる。

環境

今更だが、このページではWindows 2000上でVisual C++ 6.0を使ってアプリケーションを実装する事を前提に説明を行っている。

なぜかと言えば、俺が使っている環境が未だに新しくならないからだ。

スクリプトの実行

四の五の言わずに、アプリケーションにMSScript.ocxを組み込む手順を示す。

アプリケーションを作る

そもそも、MSScript.ocxを組み込む対象となるアプリケーションが必要になるので、まずはそれを用意してやる。

まずは、ウィザードでアプリケーションの土台を作る。

スクリプトを組み込む対象となるアプリケーションは、本来であれば当然の事ながら業務要件に合わせて作成されるべきものである。だが、あまりに生々しいアプリケーションを例にとって説明しようとすると難しくなるため、説明用のダミーのアプリケーションを用意するものとする。

あくまでも説明用のアプリケーションソフトなのだから何でも良いと言えばなんでも良いのだが、とりあえず一番簡単そうなダイアログベースのものにしておいた。

UIとしては、ダイアログ上にテキストボックスとOKボタンがあるだけの簡単なものだ。

テキストボックスは、実行するべきスクリプトを入力するために使うものであるため、一応複数行入力できるよう設定しておいた。そうでないと、スクリプトが一行しか入力できず不便である。

アプリケーションのひな形ができたら、ここでちょっとプロジェクトの設定を変更しておく。

これは余り本質的な作業ではないのだが、とりあえずアプリケーション内部で使用する文字列をUNICODEに変更しておく。これは、コンパイル時に文字列の種類(つまりchar*かwchar_t*かの違い)で引っかからないようにするためである。

やるべき作業としては、「プリプロセッサの定義」に含まれている"_MBCS"を削除して、その代わりに"_UNICODE"を追加することと、「エントリ ポイント シンボル」に"wWinMainCRTStartup"を設定することである。

なお、アプリケーション内部の文字列の扱いについては、それぞれのアプリケーションごと慎重に決めるべき問題であるため、ここではこれ以上深くは追求しない。

コードの追加

土台となるアプリケーションを用意したら、今度はそれにプログラムを追記する。

まずは、アプリケーションクラスのInitInstance()にCoInitializeの呼び出しを追加する。

BOOL CScrTestApp::InitInstance()
{
	AfxEnableControlContainer();

	// 標準的な初期化処理
	// もしこれらの機能を使用せず、実行ファイルのサイズを小さくしたけ
	//  れば以下の特定の初期化ルーチンの中から不必要なものを削除して
	//  ください。

///////////////////////////////////////////////////////
// 以下を追加
	::CoInitialize( NULL );
///////////////////////////////////////////////////////

   ・・・・・・

COMを使用するので、最初に一度この関数を呼び出してあげなければならない。追加する箇所はどこでも良いのだが、とりあえず一番最初に実行されそうなところに入れておく。

その次は、stdafx.hに、msscript.ocxをインポートする宣言を追記する。

  ・・・・・・

#include <afxwin.h>     // MFC のコアおよび標準コンポーネント
#include <afxext.h>     // MFC の拡張部分
#include <afxdisp.h>    // MFC のオートメーション クラス
#include <afxdtctl.h>	 // MFC の Internet Explorer 4 コモン・・・
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>     // MFC の Windows コモン コントロール サポート
#endif // _AFX_NO_AFXCMN_SUPPORT

/////////////////////////////////////////////////////////
// 以下を追加
#import "msscript.ocx"
using namespace MSScriptControl;
/////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

   ・・・・・・

msscript.ocxの宣言はMSScriptControlという名前空間の中で定義されているため、ここで名前空間の宣言をしておく。

なお、この宣言をここに入れるべきではないとか、あるいは、using namespaceは使うべきではないというのは、個々人が信奉している宗教による問題なので、ここではこれ以上深くは追求しない。

次は、ダイアログ上のOKボタンが押下されたときの処理である。しかしその前に、OKボタンが押下されたときのイベントハンドラを登録してあげる必要がある。

OnOKの関数には下記のように記述する。

void CScrTestDlg::OnOK() 
{
///////////////////////////////////////////////////////////////
// 以下を追加
//  CDialog::OnOK();

  CString ScriptStr;
  _bstr_t ScriptBstr;
  CEdit *pEdit = (CEdit*)GetDlgItem( IDC_EDIT1 );

  // 入力されたスクリプトを取得する
  pEdit->GetWindowText( ScriptStr );
  ScriptBstr = ScriptStr;

  try {
    // MSScriptのインターフェースを取得する
    IScriptControlPtr pSC( __uuidof( ScriptControl ) );

    // 言語としてVBScriptを使うことを設定する
    pSC->PutLanguage( _bstr_t( "VBScript" ) );

    // 実行
    pSC->AddCode( ScriptBstr );
  }
  catch ( _com_error &e ) {
    // エラーが発生したので、メッセージを表示する
    AfxMessageBox( e.ErrorMessage() );
  }

//////////////////////////////////////////////////////////////

}

重要なのはtryブロックの中の処理である。tryの前にあるのは、ただダイアログ上にあるエディットボックスから入力されたテキストを取得する処理をやっているだけのコードだ。

tryの中の1行目の処理で、ScriptControlというコンポーネントを生成して、IScriptControlというインタフェースの取得を行っている。

2行目の処理では、ScriptControlの初期化を兼ねて、使用するスクリプト言語の種類を設定している。ここでは一応VBScriptを使うように宣言している。VBScript以外にもJScriptが指定できる。

3行目の処理で、エディットボックスから取得したスクリプトのコードをScriptControlに渡して実行させている。

実行

とりあえず、これでスクリプトを実行する事ができるようになったから、ここで作ったアプリケーションを起動してみることにする。

起動すると下記のような画面が表示される。

中央にあるエディットボックスにメッセージボックスを表示する命令を入力してOKボタンを押下してみると、下記のようなメッセージボックスが表示される。

これでは、本当にVBScriptが実行されたのかどうか疑わしいような気がするから、もうちょっと込み入ったスクリプトを実行させてみる。

これを実行するとこうなる。

ちゃんと実行されていることが判る。

これで一応、アプリケーションからVBScriptを実行させることができるようになった。しかし、VBScriptを実行しただけではどうしようもない。ここから更にVBScriptからアプリケーションを制御できるようにしてあげなければならない。

次のページでは、VBScriptのコードから自分で作ったC++のコードを呼び出す方法について解説する。

次ページへ >>


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.