前記事の続きです
COM<-->JavaScript のやりとりができれば、いろいろなことができそうです。
前提
【IE限定】JavaScriptからCOMを呼び出すの続きです。
この記事は、上の記事を読んでいることを前提に書いています。
上の記事を読んでいない人は、この記事を読む前に、上の記事をお読みください。
(でないと、この記事で書いていることがサッパリわからないかもしれません。。)
実装
COM側の実装
IDLファイルを記述
IDLファイルには、以下を追加します。
- JavaScript関数を設定するプロパティ
- JavaScript関数を呼び出すメソッド
IDLファイル
// ATLProject1.idl : ATLProject1 の IDL ソース
//
// このファイルは、タイプ ライブラリ ([!output SAFE_IDL_NAME].tlb) およびマーシャリング コードを
// タイプ ライブラリ (ATLProject1.tlb) とマーシャリング コードを生成します。
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(d0b8ec50-7953-4607-86c6-6f4b2499db6f),
dual,
nonextensible,
pointer_default(unique)
]
interface IATLSimpleObject : IDispatch
{
// ★★★★★★★★★★ ここから ★★★★★★★★★★
[propput, id(1)] HRESULT JsFunc([in] VARIANT newVal);
[id(2)] HRESULT CallJsFunc();
// ★★★★★★★★★★ ここまで ★★★★★★★★★★
};
[
uuid(8cb35385-6c0f-4d8c-aef3-864ff7ec2143),
version(1.0),
]
library ATLProject1Lib
{
importlib("stdole2.tlb");
[
uuid(da1a207a-5427-49b2-b2fb-08b9f5fef902)
]
coclass ATLSimpleObject
{
[default] interface IATLSimpleObject;
};
};
import "shobjidl.idl";
ヘッダーファイルを記述
ヘッダーファイルにもプロパティ、メソッドを追加します。
ヘッダーファイル
// ATLSimpleObject.h : CATLSimpleObject の宣言
#pragma once
#include "resource.h" // メイン シンボル
#include "ATLProject1_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "DCOM の完全サポートを含んでいない Windows Mobile プラットフォームのような Windows CE プラットフォームでは、単一スレッド COM オブジェクトは正しくサポートされていません。ATL が単一スレッド COM オブジェクトの作成をサポートすること、およびその単一スレッド COM オブジェクトの実装の使用を許可することを強制するには、_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA を定義してください。ご使用の rgs ファイルのスレッド モデルは 'Free' に設定されており、DCOM Windows CE 以外のプラットフォームでサポートされる唯一のスレッド モデルと設定されていました。"
#endif
using namespace ATL;
// CATLSimpleObject
class ATL_NO_VTABLE CATLSimpleObject :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CATLSimpleObject, &CLSID_ATLSimpleObject>,
public IDispatchImpl<IATLSimpleObject, &IID_IATLSimpleObject, &LIBID_ATLProject1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CATLSimpleObject()
{
}
DECLARE_REGISTRY_RESOURCEID(106)
BEGIN_COM_MAP(CATLSimpleObject)
COM_INTERFACE_ENTRY(IATLSimpleObject)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
// ★★★★★★★★★★ ここから ★★★★★★★★★★
private:
CComPtr<IDispatch> mJsFunc;
public:
STDMETHOD(put_JsFunc)(VARIANT newVal);
STDMETHOD(CallJsFunc)();
};
// ★★★★★★★★★★ ここまで ★★★★★★★★★★
OBJECT_ENTRY_AUTO(__uuidof(ATLSimpleObject), CATLSimpleObject)
実装ファイルを記述
実装ファイルにもプロパティ、メソッドを追加します。
実装ファイル
// ATLSimpleObject.cpp : CATLSimpleObject の実装
#include "pch.h"
#include "ATLSimpleObject.h"
// CATLSimpleObject
// ★★★★★★★★★★ ここから ★★★★★★★★★★
STDMETHODIMP CATLSimpleObject::CallJsFunc()
{
if (mJsFunc)
{
DISPPARAMS params = { 0, 0, 0, 0 };
mJsFunc->Invoke(0,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
¶ms, NULL, NULL, NULL);
}
return S_OK;
}
STDMETHODIMP CATLSimpleObject::put_JsFunc(VARIANT newVal)
{
if (newVal.vt == VT_DISPATCH)
{
mJsFunc = newVal.pdispVal;
}
return S_OK;
}
// ★★★★★★★★★★ ここまで ★★★★★★★★★★
JavaScript側の実装
JavaScript側の実装です。
COM側にJavaScript関数を設定し、呼び出します。
HTMLファイル
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ActiveX</title>
</head>
<body>
<object id="activeXObj" classid="clsid:da1a207a-5427-49b2-b2fb-08b9f5fef902"></object>
<script>
var activeXObj = document.getElementById('activeXObj');
activeXObj.JsFunc = jsFunc;
activeXObj.CallJsFunc();
function jsFunc() {
alert('Call js func');
}
</script>
</body>
</html>