2017-10-19 59 views
1

我正在使用本機窗口API和chakrart JavaScript引擎創建可編寫腳本的應用程序。 我喜歡在我的IDL以下接口:基於Chakra和IDispatch的索引屬性

[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至少對於本地JavaScript對象來說與對象[prop]語法有很大不同。這可能僅僅是一個不兼容的chakrart互操作層?

+0

所以我沒有給你答案,但我即將嘗試做類似的事情,並且很好奇你是如何註冊你的本地對象的?您是否創建了一個類型爲VT_DISPATCH的VARIANT,其中包含對象的IDispatch指針,將它傳遞給JsVariantToValue,然後將該值作爲全局對象的屬性註冊? –

+1

這正是我所做的。這也意味着我卡住了使用ChakraRT而不是能夠使用ChakraCore,ChakraCore是引擎的便攜式部分,但IDispatch不是,所以...我也寫了一個函數,它需要IDispatch和ITypeInfo指針和寄存器所有可分派的成員作爲全局的屬性。這是因爲JavaScript運行時託管沒有像IActiveScript :: AddNamedItem s SCRIPTITEM_GLOBALMEMBERS標誌。 抱歉多次刪除我的回覆,我失明瞭,編輯框與我的屏幕閱讀器表現不佳。 – SoronelHaetir

回答

0

我已經確認了一種使用所需語法(App.Event ['foo'] = someHandler;)執行此操作的方法。正如前面提到的,我已經知道JavaScript會將名稱['foo'視爲成員名稱

讓App對象爲Event實現propget,該對象具有自定義(非雙接口)IDispatch實現。該對象將名稱映射到DISPID,並且每當通過GetIDsOfNames請求未知名稱時,都會返回一個先前未分配的DISPID。

請注意,爲了符合IDispatch的規則,即使稍後將空處理程序分配給給定名稱,對象也需要跟蹤名稱,以便始終爲特定名稱返回相同的DISPID。

+0

我與ChakraRT團隊進行了聯繫,他們確認IDispatch的支持是最基本的,而且索引的屬性不起作用。只要只需要一個索引器(就像我的例子中那樣),並且該值可以轉換爲可用的字符串(同樣在我的示例中),我所給出的解決方法就會起作用。但是,如果您需要一個對象來工作多語言(特別是如果你需要JavaScript和VBScript),它可能會更好,只是去方法路線(從我原來的問題GetEvent/SetEvent)。 – SoronelHaetir