カタバミさんのプログラミングノート

日曜プログラマーがプログラミング関係のメモを記録するブログです。

Visual C++ 2017でATLを利用してWord.Applicationのインスタンスを作成する方法

概要

Visual C++ 2017でATLを利用してWord.Applicationのインスタンスを作成する方法のサンプルコードです。この例では作成したインスタンスからWordのバージョンを取得します。

ソースコード

#define STRICT
#include <Windows.h>
#include <atlbase.h>

using namespace::ATL;

void Test();

int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
	// COMの初期化
	HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
	if (FAILED(hr))
		return hr;

	Test();

	// COMの開放
	CoUninitialize();

	return hr;
}

void Test()
{
	CComPtr<IDispatch> pWord;
	// CLSCTXは無指定またはCLSCTX_INPROC_SERVERだと失敗します。
	HRESULT hr = pWord.CoCreateInstance(L"Word.Application",
		nullptr, CLSCTX::CLSCTX_LOCAL_SERVER);
	if (FAILED(hr))
		return;

	CComVariant version;
	hr = pWord.GetPropertyByName(L"Version", &version);
	if (SUCCEEDED(hr))
	{
		// TODO:バージョン取得後の処理
		MessageBox(nullptr, CComBSTR(version.bstrVal), nullptr, MB_OK);
	}

	pWord.Invoke0(L"Quit");
}

解説

Word.ApplicationがCoCreateInstanceにCLSCTX_LOCAL_SERVERを要求する理由

CoCreateInstance関数またはCoCreateInstanceEx関数には3番目の引数としてdwClsContext(dwClsCtx)が存在します。この引数には複数の値を指定することができ、代表的な値にCLSCTX_INPROC_SERVER、CLSCTX_INPROC_HANDLER、CLSCTX_LOCAL_SERVE、CLSCTX_REMOTE_SERVERがあります。

Word.Applicationは動作に実行ファイル(EXEコード)を必要としているため、DLLを指定する値(CLSCTX_INPROC_SERVER、CLSCTX_INPROC_HANDLER、CLSCTX_REMOTE_SERVER)は指定することができず、CLSCTX_LOCAL_SERVER以外ではエラーが発生することになります。

CLSCTX 概要
CLSCTX_INPROC_SERVER このクラスのオブジェクトを作成・管理するコードはクラスコンテキストを指定する呼び出し元関数と同じプロセスで実行されるDLLです。
CLSCTX_INPROC_HANDLER このクラスのオブジェクトを管理するコードはインプロセス・ハンドラです。これはクライアントプロセスで実行されるDLLであり、クラスが遠隔でアクセスされるインスタンスの場合、このクラスのクライアント側構造を実装します。
CLSCTX_LOCAL_SERVER このクラスのオブジェクトを作成・管理するEXEコードは同じコンピューターで実行されますが、分離されたプロセス空間に読み込まれます。
CLSCTX_REMOTE_SERVER リモートコンテキスト。このクラスのオブジェクトを作成・管理するLocalServer32またはLocalServiceコードは異なるコンピューターで実行されます。
CLSCTX_INPROC_SERVER16 Obsolete
CLSCTX_INPROC_HANDLER16 Obsolete