◇ ActiveXオートメーションとは?
○ オートメーションの概要
ActiveXオートメーション(以前はOLEオートメーションと呼ばれていた)を用いて、他のアプリケーションに対してオブジェクトを公開し、アプリケーション内のActiveXサーバと別のActiveXクライアント機能に対応したアプリケーションとの間のデータ連携を可能にするためのプログラム開発用インターフェースです。○ 用語の概要説明
オートメーションサーバによって公開されたオブジェクトはVisualBasicやVBA(Visual Basic for Application)に対応したアプリケーションなどで操作できます。オートメーションを利用すれば、VisualBasicを利用して効率的に短期間でユーザコマンド開発を行うことが可能です。
また、Excel(Microsoft Excel)やWord(Microsoft Word)などに代表されるVBA対応アプリケーションのデータを自アプリケーションで利用したり、自アプリケーションにデータを反映させることが出来ます。また、オートメーションの利用方法や記述形式はVisualBasicに完全準拠しており、VisualBasicを既に利用されている方は新たな言語を理解する必要なく、すぐに効率的なユーザプログラム開発が始められます。
さらに、オートメーションはマクロ的な利用も包括していますので、アプリケーションが従来持っていたマクロの移行を効率的に行うことが可能です。
また、演算や分岐処理などの一般的な処理は、VisualBasicが持つ豊富な機能をそのまま利用することで個別に開発・用意する手間を省き、より高度な開発I/Fを効率良く作成できます。
VisualBasicでオブジェクトを操作するには、オブジェクトの保有するメソッドを使用したり、オブジェクトのプロパティ値の取得または設定することにより行います。○ VARIANTの説明オブジェクトを利用するための関数は、次のとおりです。
関数 内容 CreateObject 指定した種類の新しいオブジェクトを作成します。 オブジェクトは、アプリケーションの要素を表します。VisualBasicでは、オブジェクトのメソッドの1つを使ったり、プロパティのいずれかの値を変更する前に、対象となるオブジェクトを識別する必要があります。
プロパティは、サイズ、色、画面の位置などオブジェクトの特徴や、使用可能または表示/非表示などの動作を定義する属性です。
オブジェクトの特徴を変更するには、そのプロパティ値を変更します。プロパティに値を設定するには、対象となるオブジェクトの後ろに、ピリオド、プロパティ名、等号 (=)、新しいプロパティ値の順で記述します。
プロパティによっては、取得のみで設定できないものもあります。メソッドを使うと、オブジェクト上でのコマンドの実行や処理の開始や終了などの動作を操作することができます。書式はプロパティに良く似ていますが、等号による値の設定が出来ないなどの違いがあります。
また、プロパティとメソッドは区別されずに統括して「メソッド」と呼称されることも多々あります。
なお、ここに記述した以外の詳細につきましては、後述の参考文献等を御参照ください。
VARIANTは様々な型の値を入れられる特別な変数で、オートメーションを扱う上で非常に重要なものです。
中身は単純な構造体で、変数の型を入れる「vt」とunionになっている値を入れるメンバなどで構成されています。ですから、例えばBOOLの値をいれようと思えば、
といった感じになります。
VARIANT vaResult;
vaResult.vt = VT_BOOL;
vaResult.bool = (VARIANT_BOOL)VA_TRUE;COleVariantというクラスを利用すると、より簡単に扱えます。
たとえば、longの値をセットするなら
long lRet;
VARIANT vaResult;
COleVariant cvRet;lRet = 5;
cvRet = (long)lRet;
vaResult = cvRet.Detach();文字列はBSTRという型で入っていますので、一旦CStringに変換すると楽に取得できます。
void CnvBSTR2CString( BSTR bStr, CString* pCStr )
{
int nBytes;
LPSTR lpsz;
int nLen;TRY {
nLen = SysStringLen(bStr);
nBytes = WideCharToMultiByte(CP_ACP, 0, bStr,
nLen, NULL, NULL, NULL, NULL);
lpsz = pCStr->GetBufferSetLength(nBytes);
WideCharToMultiByte(CP_ACP, 0, bStr, nLen,
lpsz, nBytes, NULL, NULL);
}
CATCH( CMemoryException, e ) {
throw;
} END_CATCH
return;
}この他にも型変換・配列・引数の省略なども表現できます。
[型変換] COleVariant cvRet;
cvRet.ChangeType( VT_I4, NULL );
[配列チェック] int dCheckVariantArray( const VARIANT FAR& vaCheck )
{
VARTYPE vt;
vt = vaCheck.vt & VT_ARRAY;if ( vt == VT_ARRAY )
return VT_IS_ARRAY;
else
return VT_NOT_ARRAY;
}
[引数省略チェック] vt = RubberType.vt & TYPE_MASK;
//引数省略チェック
if ( vt == VT_ERROR ) {
if ( RubberType.scode != DISP_E_PARAMNOTFOUND ) {
//引数が省略されている
}
}配列を使用する場合はこの他に安全配列(SAFEARRAY)を理解する必要があります。
これにつきましては、次項を御参照ください。
○ 安全配列の説明
VARIANTで配列を扱う場合、安全配列(SAFEARRAY)と呼ばれるものを利用します。安全配列には、次元の数とその中の境界値、そして、配列の実データへのポインタなどが納められています。
中身は単純な構造体ですが、実データへのアクセスなどを配慮し、処理用の関数が多数用意されています。以下にその処理の一例を示していきます。
まず、VARIANTの変数が配列かどうかを判定してみましょう。
int dCheckVariantArray( const VARIANT FAR& vaCheck )
{
VARTYPE vt;vt = vaCheck.vt & VT_ARRAY;
if ( vt == VT_ARRAY ) {
return VT_IS_ARRAY;
}
else {
return VT_NOT_ARRAY;
}
}このように、変数の元の型を示す値にVT_ARRAYがORされた形で、型と配列が指示されています。
longの配列(ByVal) vt = VT_I4 | VT_ARRAY BOOLの配列(ByVal) vt = VT_BOOL | VT_ARRAY longの配列(ByRef) vt = VT_BYREF | VT_I4 | VT_ARRAY BOOLの配列(ByRef) vt = VT_BYREF | VT_BOOL | VT_ARRAY ただし、変数の元の型がいかなる種類であっても、実際の値は安全配列を示すポインタに保管されています。安全配列をCreateする際に格納される型が決定されているからです。
全ての型の配列(ByVal) parray 全ての型の配列(ByRef) pparray 次に、配列の構成を調べます。C/C++の配列と異なり、「次元数」・「下限境界値」・「上限境界値」という概念が導入されています。ここでいう「次元数」とはC/C++での配列数ではなく、「下限境界値」・「上限境界値」で指定された配列の次元の個数(多次元配列)だという点に注意して処理を進めてください。
なお、VBでデフォルト指定された配列の下限境界値は「1」となります。
int dCheckArrayDim( SAFEARRAY FAR* pArray, long lMin )
{
long lBound;//配列数チェック
if ( SafeArrayGetDim( pArray ) != 1 ) return( -1 );//下限境界値チェック
if ( SafeArrayGetLBound( pArray, 1, &lBound ) != S_OK )
return( -1 );
if ( lBound > 1 ) return( -1 );//上限境界値チェック
if ( SafeArrayGetUBound( pArray, 1, &lBound ) != S_OK )
return( -1 );
if ( lBound < lMin ) return( -1 );return( 0 );
}配列への個々のデータ設定には通常、「SafeArrayPutElement」関数を用います。格納するデータの型は安全配列のCreate時に指定した型と一致している必要があります。
rgIndices[0] = i + 1;
SafeArrayPutElement( pArray, rgIndices, (void FAR*)pData );配列へのデータの一括設定には「SafeArrayAccessData」関数を用いるのが一般的です。格納するデータの型を安全配列のCreate時に指定した型と意図的に不一致にしたい場合にも用いることができます。
また、使用後は必ず「SafeArrayUnaccessData」関数をCallする必要があります。
if ( SafeArrayAccessData(pArray,(void HUGEP* FAR*)&pvPtr) != S_OK ) {
return ( -1 );
}
if ( pvPtr == NULL ) {
return ( -1 );
}
memcpy( pvPtr, pData, dwSize );
SafeArrayUnaccessData ( pArray );なお、VC5.0以降は「COleSafeArray」クラスも用意されており、上記の操作をより簡便に利用することが可能となっています。
メンバ関数等は全て上記のAPIと同一名称となっていますので、説明は割愛します。
○ 命名ガイドライン
Automationサーバを作成する上で、標準的なオブジェクトや名前付けのガイドラインがMicrosoftによって示されています。
この資料などを基に作成するAutomationサーバにおいても、出来る限りこのガイドラインに準拠するのが望ましいでしょう。サーバの母体であるアプリケーションを指すオブジェクトを「Applicationオブジェクト」と呼びますが、このオブジェクトにおいて、以下のプロパティ及びメソッドは必須です。
< Property > Application Applicationオブジェクトを返す。(ReadOnly) FullName アプリケーションのフルパスを返す。(ReadOnly) Name アプリケーション名を返す。(ReadOnly) Parent 親オブジェクトを返す。(ReadOnly) Visible アプリケーションがユーザに見えるかどうかを設定または返す。(Read/Write)
< Method > Quit アプリケーションを終了する。 以下のプロパティ及びメソッドについては必須ではありませんが、通常のサーバでは一般的なものであり、作成するのが望ましいでしょう。
< Property > Height アプリケーションのメインウィンドウの上端から下端までの距離を設定または返す。(Read/Write) Left 物理画面の左端からアプリケーションのメインウィンドウまでの距離を設定または返す。(Read/Write) Top 物理画面の上端からアプリケーションのメインウィンドウまでの距離を設定または返す。(Read/Write) Width アプリケーションのメインウィンドウの左端から右端までの距離を設定または返す。(Read/Write)
< Method > Repeat ユーザインターフェースの直前の動作を繰り返す。 Undo ユーザインターフェースの直前の動作を取消す。 また、オブジェクト、プロパティ、メソッドの名前はユーザに分かりやすいものにすべきです。一般的には以下のルールに基づいて命名を行うのが望ましいとされています。
・1語全体または1音節を使う
○Application,Window
×App,Wnd
・大小時の識別を利用する
○ShortCutMenus,BasedOn
×Shortcut_Menus,BASED_ON
○ 参考文献
上記に記載した内容はオートメーションサーバやクライアント機能を作成する上で最低限理解しておく必要がある内容です。
この他にも必要に応じて様々な知識が必要になることがあります。こうしたケースでは以下の書籍などを参考にされると良いでしょう。
オートメーションプログラマーズリファレンス
Microsoft Corporation 著
アスキー書籍編集部 訳