2009-11-05 15 views
5

Continuando da this question, sono confuso se DISPID_VALUE su IDispatch::Invoke() per le funzioni di script e proprietà (JavaScript nel mio caso) può essere considerato standard e affidabile per richiamare la funzione effettiva che è rappresentata dal IDispatch?
Se sì, è menzionato ovunque in MSDN?è DISPID_VALUE affidabile per richiami su IDispatch da script?

Si prega di notare che la domanda è se questo comportamento può essere previsto, non ciò che alcune interfacce non posso sapere in anticipo potrebbe essere simile.

Un semplice caso d'uso potrebbe essere:

// usage in JavaScript 
myObject.attachEvent("TestEvent", function() { alert("rhubarb"); }); 

// handler in ActiveX, MyObject::attachEvent(), C++ 
incomingDispatch->Invoke(DISPID_VALUE, IID_NULL, LOCALE_SYSTEM_DEFAULT, 
         DISPATCH_METHOD, par, res, ex, err); 

edit: cercato di chiarire la questione.

risposta

3

Dovrebbe essere affidabile per invocare oggetti da script se lo script lo definisce in modo coerente. Questo dovrebbe essere il caso di JScript/Javascript in MSHTML, ma sfortunatamente c'è una documentazione sparsa sull'argomento, non ho alcuna prova solida in mano.

Nella mia esperienza personale, una funzione Javascript passata a attachEvent() deve essere sempre coerente: un oggetto ricevuto che è una "funzione" può avere solo un metodo chiamabile che corrisponde a se stesso. Quindi il metodo di default è l'unico che puoi trovare, con DISPID 0. Le funzioni Javascript di solito non hanno funzioni membro, anche se sono sicuro che c'è un modo per farlo. Se avesse funzioni membro, le vedresti allo stesso modo delle funzioni membro sugli oggetti. Le funzioni membro in JScript saranno sempre coerenti con IDispatchEx, in base alle regole delle funzioni expando, poiché tutte le funzioni aggiunte a un oggetto vengono conteggiate come espansioni.

IDispatchEx interface @ MSDN

2

Il metodo o la proprietà di default che invoca DISPID_VALUE devono essere coerenti per una determinata interfaccia. Tale metodo/proprietà deve essere specificato come DISPID_VALUE nella definizione dell'interfaccia nell'IDL per la libreria dei tipi. L'unico modo in cui potrebbe cambiare è se il proprietario dell'interfaccia ha rilasciato una nuova versione dell'interfaccia che ha cambiato quale metodo/proprietà era l'impostazione predefinita ma violerebbe una regola fondamentale delle interfacce COM.

+0

Che DISPID_VALUE dovrebbe essere in genere coerente non mi aiuta - posso aspettarmi che invochi costantemente ad es. la funzione effettiva su tutti gli IDispatch che rappresentano le funzioni di script? –

+0

Secondo la mia esperienza, sì, purché siano direttamente rappresentativi degli oggetti script. Come accennato nella mia risposta di seguito, gli oggetti IDispatch che si ottengono tramite ConnectionPoint sono leggermente diversi – taxilian

0

È possibile aggiungere DISPID a DISPINTERFACE, ma non è possibile cambiarli una volta che è stato pubblicato. Se è necessario, è possibile utilizzare IDispatch::GetIDsOfNames per associare i nomi ai DISPID.

Raccogli una copia di Inside Ole (2a ed) e Inside Ole 2 (2a ed) per alcuni dollari usati su Amazon. È un buon riferimento per questi incantesimi OLE oscuri.

+0

Cosa mi fa getIDsOfNames() quando desidero chiamare ad es. oggetti funzione anonimi che sono stati consegnati al mio controllo? –

+0

Non ti dà quello. È necessario trovare le informazioni sul tipo da una libreria di tipi o documentazione –

1

Come meklarian detto, DISPID_VALUE (0) sembra funzionare abbastanza consistantly per le funzioni di JS (così funziona benissimo con un attachEvent personalizzato). Li ho usati in questo modo per circa un anno, e ha sempre funzionato. Ho anche trovato con un controllo activeX incorporato con un tag <object> che per farlo funzionare in modo coerente, ho bisogno di implementare IConnectionPointContainer e IConnectionPoint per il main (object tag) IDispatch-implementazione CComObject, ma tutti gli altri che espongo a javascript come restituire valori da metodi o proprietà (tramite Invoke) Devo implementare attachEvent e disconnettere me stesso.

Quando si utilizza il punto di connessione, gli oggetti IDispatch in questione si aspettano gli eventi per essere alimentate allo stesso DISPID in quanto sono attaccati alla sull'oggetto IDispatch ..

vedono http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h per un esempio di attuazione delle ConnectionPoints.

Problemi correlati