2009-11-05 8 views
5

Kontynuując od this question, jestem zdezorientowany, czy DISPID_VALUE na IDispatch::Invoke() dla funkcji skryptu i właściwości (JavaScript w moim przypadku) można uznać za standardowe i niezawodne do wywoływania rzeczywistej funkcji, która jest reprezentowana przez IDispatch?
Jeśli tak, czy jest to wymienione w dowolnym miejscu w MSDN?jest wiarygodne DISPID_VALUE dla wywołań na IDispatchs ze skryptów?

Należy pamiętać, że pytanie dotyczy tego, czy można się spodziewać takiego zachowania, a nie tego, jak mogą wyglądać niektóre interfejsy, z których nie mogę wiedzieć wcześniej.

Prosty przypadek użycia może być:

// 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: próbował wyjaśnić kwestię.

Odpowiedz

3

Powinno być wiarygodne dla wywołań obiektów ze skryptów, jeśli skrypt definiuje je konsekwentnie. Tak powinno być w przypadku JScript/Javascript w MSHTML, ale niestety istnieje naprawdę rzadka dokumentacja na ten temat, nie mam żadnego solidnego dowodu w ręku.

Z mojego doświadczenia wynika, że ​​funkcja JavaScript przekazywana do metody attachEvent() powinna być zawsze spójna - obiekt otrzymany, który jest "funkcją", może mieć tylko jedną metodę wywoływalną, która pasuje do siebie. Dlatego domyślna metoda jest jedyną, którą można znaleźć, z DISPID 0. Funkcje JavaScript zwykle nie mają funkcji składowych, chociaż jestem pewien, że istnieje sposób, aby to było możliwe. Jeśli miałby funkcje składowe, zobaczyłby je w taki sam sposób, jak funkcje elementów na obiektach. Funkcje członkowskie w JScript będą zawsze spójne w odniesieniu do IDispatchEx, zgodnie z zasadami funkcji expando, ponieważ wszelkie funkcje dodane do obiektu liczą się jako expandos.

IDispatchEx interface @ MSDN

2

Domyślna metoda lub właściwość wywoływana przez DISPID_VALUE powinna być spójna dla danego interfejsu. Ta metoda/właściwość musi być określona jako DISPID_VALUE w definicji interfejsu w IDL dla biblioteki typów. Jedyny sposób, w jaki można to zmienić, to fakt, że właściciel interfejsu wydał nową wersję interfejsu, która zmieniła domyślną metodę/właściwość, ale która naruszyłaby podstawową zasadę interfejsów COM.

+0

Wartość DISPID_VALUE na ogół powinna być stała, nie pomaga mi - czy mogę oczekiwać, że będzie ona konsekwentnie wywoływać np. faktyczna funkcja wszystkich 'IDispatch'ów, które reprezentują funkcje skryptowe? –

+0

Z mojego doświadczenia wynika, że ​​tak długo, jak są one bezpośrednio reprezentatywne dla obiektów skryptów. Jak wspomniałem w mojej odpowiedzi poniżej, obiekty IDispatch, które dostajesz przez ConnectionPoints są nieco inne – taxilian

0

Możesz dodać DISPID do DISPINTERFACE, ale nie możesz ich zmienić po opublikowaniu. Jeśli potrzebujesz, możesz użyć nazwy IDispatch::GetIDsOfNames do odwzorowania nazw na DISPID.

Odbierz egzemplarz Inside Ole (drugi ed) i Inside Ole 2 (drugi ed) za kilka dolców używanych w Amazon. To dobre odniesienie dla tych mrocznych inkantacji OLE.

+0

Co robi 'GetIDsOfNames()' dostaję mnie kiedy chcę zadzwonić np. anonimowe obiekty funkcji, które zostały mi przekazane? –

+0

To ci nie daje. Musisz znaleźć informacje o typie z biblioteki typów lub dokumentacji –

1

Jak meklarian powiedział DISPID_VALUE (0) wydaje się działać całkiem consistantly dla funkcji JS (w ten sposób, że działa świetnie z niestandardowych attachEvent). Używam ich w ten sposób przez około rok i zawsze działa. Znalazłem również z formantem activeX osadzonym z tagiem <object>, który w celu zapewnienia jego stałej pracy, muszę zaimplementować IConnectionPointContainer i IConnectionPoint dla głównego obiektu (object tag) CCispObject implementującego IDispatch, ale inne, które eksponuję na javascript jako zwróć wartości z metod lub właściwości (przez Invoke) Muszę zaimplementować attachEvent i detachEvent sam.

Przy zastosowaniu punktów przyłączeniowych, obiekty IDispatch których mowa, będą oczekiwać zdarzenia zostać zwolniony do tej samej DISPID ponieważ są one przypisane do obiektu na IDispatch ..

zobaczyć http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h dla przykładu realizacji ConnectionPoints.