◇ MFCを用いたオートメーションクライアントの作成方法
○ タイプライブラリを用いたクラスの作成
オートメーションクライアント機能を利用する場合、その接続先となるサーバのタイプライブラリ(拡張子:TLB or OLB, DLLの場合もあり)が必要になります。○ サーバとの接続方法
通常、タイプライブラリはアプリケーションのインストールフォルダにデフォルトでインストールされます。
存在しない場合、インストールディスクやアプリケーション開発元へ問い合わせる必要があるでしょう。Visual C++でMFCを用いる場合、オートメーションクライアントとなるDLLは、以下の手順で作成できます。
なお、ここでの説明はVC4.0をベースにしていますが、それ以降のバージョンでも同様の操作で作成が可能です。(1) App WizardでDLLを生成
・DLLの形式は問いません。
・既にMFCを利用したDLLを利用していれば、それを流用することも可能です。(2) Class Wizardを使ってサーバのインポートクラスを生成
・ClassWizardの「OLE オートメーション」タグで新しいクラスを作成する。
・OLEオートメーションオプションは「OLE TypeLibから」を選択する
・インポートの指定に対象とするサーバのタイプライブラリを指定する。(3) 参照したいクラス(オブジェクト)を選択
・複数のクラスを選択可能。
前述の方法で作成したサーバのインポートクラスを用いてサーバとの接続を行います。○ オブジェクト・コレクションの利用インポートされたクラスは、COleDispatchDriverクラスをベースに作成されています。接続やメソッド/プロパティのCallはこのクラスのメンバを用いて行われます。
また、サーバとの接続にはサーバアプリケーションを示す識別子となる文字列が必要となります。アプリケーションによって、以下の例のような文字列を指定します。
Excel(95以降) Excel.Application Word (97以降) Word.Application この識別子の文字列はサーバアプリケーションにより異なりますので、アプリケーションのマニュアル等を参照して調査する必要があります。
さらに作成した関数をC言語レベルでも使用できるようにしたい場合は、関数の先頭に以下の指定を行うと良いでしょう。
extern "C" _declspec( dllexport ) 以下にExcelをサーバとした場合の簡単な関数例を示します。
extern "C" _declspec( dllexport ) int TestFunc(void)
{
_Application ExcelCtrl;
int iRet;CoInitialize(NULL);
if ( ExcelCtrl.CreateDispatch( _T("Excel.Application"), NULL ) == 0 ) {
return( -1 );
}if ( ExcelCtrl.GetVisible() == TRUE ) {
iRet = 1;
}
else {
iRet = 0;
}ExcelCtrl.ReleaseDispatch();
CoUninitialize();return( iRet );
}
サーバ中には多くのオブジェクトや、その集合体であるコレクションが用意されている場合が少なくありません。
ここでは、こうしたオブジェクトの利用方法について解説します。サーバ中に存在するオブジェクトはサーバクラスのインポートの際にCOleDispatchDriverクラスをベースに既にインポートされているはずです。
オブジェクトや配下のメソッド/プロパティのCallはこのクラスのメンバを用いて行われます。以下にExcelでの一例を示しながら説明していきましょう。まず、必要な変数を定義します。
ここで用いる変数は大別して、インポートしたクラスとオブジェクトへのポインタを示す「LPDISPATCH」です。
_Application ExcelCtrl;
LPDISPATCH pWorkbooks;
Workbooks books;
LPDISPATCH pDisp;
_Workbook book;
LPDISPATCH pSheets;
Worksheets sheets;
LPDISPATCH pWorkSheet;
_Worksheet sheet;
LPDISPATCH pRange;
Range range;
VARIANT varNull;また、メソッドをVB上で用いる場合、引数を省略するケースが多々存在します。
しかし、VCからメソッドを用いる場合、完全に省略することはできません。省略したい場合は、以下で定義した変数を指定することで同等の処理を実現できます。
varNull.vt = VT_ERROR;
varNull.scode = DISP_E_PARAMNOTFOUND;次にまず前項と同様、サーバとの接続を行ないます。
CoInitialize(NULL);
if ( ExcelCtrl.CreateDispatch( _T("Excel.Application"), NULL ) == 0 )
return( -1 );ブックを開きます。ここでは、ブックのコレクションと開いたブックのクラスを取得する処理を行なっています。
引数の省略も活用しています。
pWorkbooks = ExcelCtrl.GetWorkbooks();
books.AttachDispatch(pWorkbooks);
pDisp = books.Open("C:\\Test.xls", varNull, varNull,
varNull, varNull, varNull, varNull,
varNull, varNull, varNull, varNull,
varNull, varNull);
book.AttachDispatch(pDisp);
次はシートの特定です。ここでは、ブック中のシートと所定のシートのクラスを取得する処理を行なっています。
pSheets = book.GetWorksheets();
sheets.AttachDispatch(pSheets);
pWorkSheet = sheets.GetItem(COleVariant("sheet1"));
sheet.AttachDispatch(pWorkSheet);シート中の指定範囲(Range)を特定し、値を設定します。A1セルに「100」を代入していることになります。
pRange = sheet.GetRange(
COleVariant((short)1),
COleVariant((short)1));
range.AttachDispatch(pRange);
range.SetValue(COleVariant((short)100));サーバとの接続を切る前に参照した全てのオブジェクトを解放します。
これを忘れると、切断後もサーバアプリケーションがメモリ中に残留するなど、障害の原因になります。
必ず解放するように注意してください。
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();最後にサーバとの接続を切ります。以上で処理は完了です。
ExcelCtrl.ReleaseDispatch();
CoUninitialize();