seraphyの日記

日記というよりは過去を振り返るときのための単なる備忘録

ActiveScriptSiteに独自のオブジェクトを公開する。

上の続き。

ActiveScriptHostでスクリプトにオブジェクトを公開するには、ActiveScriptのAddNamedItemメソッドを呼び出して名前を予約する。これは、SetSiteを呼び出したあとに行う必要がある。

なお、名前を登録するだけでオブジェクトは、この時点では必要ない。

...(前略)...
		// スクリプトエンジンにSiteを設定
		hr = pScript_->SetScriptSite(pSite);
		ATLASSERT(SUCCEEDED(hr));

		// ルートコンテキスト上に「util」という名前のオブジェクトを登録する。
		hr = pScript_->AddNamedItem(L"util",
			SCRIPTITEM_ISPERSISTENT | SCRIPTITEM_ISVISIBLE);
		ATLASSERT(SUCCEEDED(hr));

		ParseScript();
...(後略)...

ここで次のようなスクリプトを呼び出すとすると、

Call util.SayHello

ActiveScriptSiteのGetItemInfoが呼び出されるため、ここで「util」という名前であるかをチェックして、該当するのであればスクリプトに渡したいIDispatchを実装したオブジェクトを返却すればよい。(IUnknownを受け取るようになっているが。)

名前が該当しない場合は、TYPE_E_ELEMENTNOTFOUNDを返す。(しかし、このメソッドはAddNamedItemで登録された名前のみが呼び出されることに留意されたし。)

ITypeInfoはスクリプト側で利用するシチュエーションがないと思われるので常にNULLを返してよいと思われる。(返すと、なにかいいことがあるのか?)

...(前略)...
	virtual HRESULT STDMETHODCALLTYPE GetItemInfo( 
		/* [in] */ LPCOLESTR pstrName,
		/* [in] */ DWORD dwReturnMask,
		/* [out] */ IUnknown **ppiunkItem,
		/* [out] */ ITypeInfo **ppti) throw()
	{
		_tprintf(_TEXT("GetItemInfo\n"));
		HRESULT hr = TYPE_E_ELEMENTNOTFOUND;
		static CComBSTR name(L"util");
		if (name == pstrName) {
			hr = S_OK;
			if (dwReturnMask & SCRIPTINFO_IUNKNOWN) {
				hr = pSayHello_.QueryInterface(ppiunkItem);
			}
			if (SUCCEEDED(hr) && (dwReturnMask & SCRIPTINFO_ITYPEINFO)) {
				*ppti = NULL;
			}
		}
		return hr;
	}
...(後略)...

以上、おわり。