LoginSignup
1
0

More than 3 years have passed since last update.

【IE限定】COMからJavaScriptを呼び出す

Posted at

前記事の続きです
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,
            &params, 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>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0