How to Implement index attributes for COM Component Objects

Source: Internet
Author: User

Previous SeriesArticleWe know how to implement interoperability between JavaScript and COM objects. Here, let's look at a special application -- index attribute. The index attribute allows the COM object to be accessed like an array. For example, we have a COM object instance omyarray, which can be called in Javascript as follows:

 

// Standard mode <br/> omyarray. item (0) = "test"; <br/> alert (omyarray. item (0); </P> <p> // default attribute method <br/> omyarray (0) = "test "; <br/> alert (omyarray (0); </P> <p> // index attribute method <br/> omyarray [0] = "test "; <br/> alert (omyarray [0]); <br/>

 

The default attribute is well implemented, that is, to allow the COM object to provide an attribute method of dispid = 0.

You need to reload the index attribute.TheGetidsofnames andInvoke method.

 

Let's first look at how JavaScript executes index attributes.

When JavaScript encounters omyarray [0], it calls the idispatch. getidsofnames method to check whether there is an attribute named "0. If yes, use the returned dispid to continue calling the idispatch. Invoke method.

 

For convenience, the following example only supports long index parameters.

 

_ Interface imyarray: idispatch <br/>{< br/> [ID (00000000), propget] <br/> hresult item ([in] variant varkey, [out, retval] variant * pvar); <br/> [ID (00000000), propput] <br/> hresult item ([in] variant varkey, [in] variant pvar ); </P> <p> class atl_no_vtable cmyarray: <br/> Public idispatchimpl <imyarray> <br/>{</P> <p> public: <br/> hresult finalconstruct () <br/>{< br/> m_nindexcounter = 10000; <br/>}</P> <p> PRIVATE: <br/> // For convenience, only long-type index names are supported <br/> catlmap <long, _ variant_t> m_omapfromnametovalue; </P> <p> // index-based access <br/> dispid m_nindexcounter; <br/> catlmap <dispid, long> m_omapfromidtoindex; <br/> catlmap <long, dispid> m_omapfromindextoid; </P> <p> Public: <br/> // supports default attributes <br/> stdmethod (get_item) (variant varkey, variant * pvar); <br/> stdmethod (put_item) (variant varkey, variant pvar ); </P> <p> // index attributes <br/> stdimethyl Thod (getidsofnames) (refiid riid, lpolestr * rgsznames, uint cnames, <br/> lcid, dispid * rgdispid); <br/> stdmethod (invoke) (dispid dispidmember, refiid riid, <br/> lcid, word wflags, dispparams * pdispparams, variant * pvarresult, <br/> raise info * p1_info, uint * puargerr ); </P> <p >}; </P> <p> /// implementation </P> <p> stdmethodimp cmyarray: get_item (variant varkey, variant * pvar) <br/>{< br/> // <br/> _ Varia Nt_t vresult; <br/> m_omapfromnametovalue.lookup (varkey. lval, vresult); </P> <p> * pvar = vresult. detach (); <br/> return s_ OK; <br/>}</P> <p> stdmethodimp cmyarray: put_item (variant varkey, variant pvar) <br/>{< br/> // <br/> m_omapfromnametovalue.setat (varkey. lval, pvar); <br/> return s_ OK; <br/>}</P> <p> stdmethodimp cmyarray: getidsofnames (refiid riid, lpolestr * rgsznames, uint cnames, <br/> lcid, dispi D * rgdispid) <br/>{< br/> // <br/> hresult HR =__ super: getidsofnames (riid, rgsznames, cnames, lcid, rgdispid ); <br/> If (HR! = Disp_e_unknownname) <br/> return hr; </P> <p> // used as an index attribute <br/> long nindex = _ wtol (rgsznames [0]); </P> <p> dispid ndispid; <br/> If (this-> m_omapfromindextoid.lookup (nindex, ndispid) <br/>{< br/> * rgdispid = ndispid; <br/>}< br/> else <br/>{< br/> ndispid = ++ m_nindexcounter; </P> <p> This-> m_omapfromidtoindex.setat (ndispid, nindex); <br/> This-> m_omapfromindextoid.setat (nindex, ndispid); </P> <p> * rgdispid = ndispid; <br/>}</P> <p> // <br/> return s_ OK; <br/>}</P> <p> stdmethodimp cmyarray :: invoke (dispid dispidmember, refiid riid, <br/> lcid, word wflags, dispparams * pdispparams, variant * pvarresult, <br/> interval info * p1_info, uint * puargerr) <br/> {<br/> // you can determine whether the index attribute is an index attribute because the index attribute starts from 10000 and does not conflict with each other. <br/> long nindex; <br/> If (this-> m_omapfromidtoindex.lookup (dispidmember, nindex) <br/>{< br/> If (wflags & dispatch_propertyget) <br/>{< br/> return this-> get_item (_ variant_t (nindex), pvarresult ); <br/>}< br/> else if (wflags & dispatch_propertyput) | (wflags & dispatch_propertyputref )) <br/> & pdispparams-> cargs = 1 <br/>) <br/> {<br/> return this-> put_item (_ variant_t (nindex ), pdispparams-> rgvarg [0]); <br/>}< br/> else <br/>{< br/> return e_fail; <br/>}< br/> else <br/> {<br/> return _ super: invoke (dispidmember, riid, lcid, <br/> wflags, pdispparams, pvarresult, p1_info, puargerr); <br/>}< br/>

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.