1

ネイティブ Windows API と chakrart JavaScript エンジンを使用してスクリプト可能なアプリケーションを作成しています。IDL に次のようなインターフェイスがあります。

[oleautomation, dual, nonextensible,
uuid(...)]
interface IMyInterface : IDispatch
{
[id(MYDISPID_EVENT), propget] HRESULT Event(BSTR strEventName, [out, retval] IDispatch ** ppHandler);
[id(MYDISPID_EVENT), propput] HRESULT Event(BSTR strEventName, IDispatch * pHandler);
};

問題なくネイティブ オブジェクトを chakrart エンジンに追加できました (JsVariantToValue を使用し、現在のコンテキストのグローバル オブジェクトにプロパティを設定することにより)。ただし、イベント ハンドラーを設定しようとすると、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」という例外メッセージが表示されます。

次の構文バリエーションを試しました。

object.Event["foo"] = handler;
object.Event("foo", handler);
object.put_Event("foo", handler);
object.Event("foo") = handler;

その最後は、vbscript を使用してこれを行う方法に近いです。

object.Event("foo") = GetRef("handler)

次のように IDL でメソッド構文を使用すると、それが機能します。可能であれば、プロパティの割り当てを使用することをお勧めします。

[id(MYDISPID_GETEVENT)] HRESULT GetEvent(BSTR strEventName, [out, retval] IDispatch ** ppHandler);
[id(MYDISPID_SETEVENT)] HRESULT SetEvent(BSTR strEventName, IDispatch * pHandler);

また、単純なプロパティの割り当てが機能することにも注意してください。インデックス付きのプロパティを試したときにのみ壊れます。JavaScript が object[prop] 構文で行うことは、少なくともネイティブ JavaScript オブジェクトに対しては非常に異なることを理解しています。これは、chakrart 相互運用レイヤーの非互換性によるものでしょうか?

4

1 に答える 1

0

目的の構文 (App.Event['foo'] = someHandler;) でこれを実行する方法を確認しました。前述のように、JavaScript が name['foo'] を name のメンバー ルックアップとして扱うことは既に知っていました。

App オブジェクトに、カスタム (非デュアル インターフェイス) IDispatch 実装を持つオブジェクトを返す Event の propget を実装させます。そのオブジェクトは DISPID への名前のマップを保持し、不明な名前が GetIDsOfNames を介して要求されるたびに、以前に割り当てられていない DISPID が返されます。

IDispatch の規則に準拠するために、特定の名前に対して同じ DISPID が常に返されるように、後で null ハンドラーが特定の名前に割り当てられた場合でも、オブジェクトは名前を追跡する必要があることに注意してください。

于 2017-11-02T22:57:21.847 に答える