я столкнулся с реализацией интерфейса IDispatch
. Есть четыре метода, и, к счастью, 3 из них просты:
function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetTypeInfo(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetIDsOfNames(...): HResult;
{
Result := E_NOTIMPL;
}
Это последний способ, Invoke
сложный. Здесь я столкнулся с тем, что мне нужно фактически регистрировать DispID и вызывать соответствующий метод; рассортировка параметров из массива вариантов.
function Invoke(
dispIdMember: DISPID;
riid: REFIID;
lcid: LCID;
wFlags: WORD;
var pDispParams: DISPPARAMS;
var pVarResult: VARIANT;
var pExcepInfo: EXCEPINFO;
var puArgErr: DWORD
): HRESULT;
Не желая писать весь утомительный шаблонный код, в котором, я уверен, будут ошибки, я пошел гуглить, а не выполнять какую-либо работу.
я нашел этот фрагмент в документации MSDN IDispatch.Invoke
:
Как правило, не следует реализовывать Invoke напрямую.
Отлично! я все равно не хотел его реализовывать! Продолжаем читать:
Вместо этого используйте интерфейс отправки для создания функций CreateStdDispatch и DispInvoke. Дополнительные сведения см. в разделах CreateStdDispatch, DispInvoke, Создание интерфейса IDispatch и Предоставление объектов ActiveX.
Ссылка Создание интерфейса IDispatch гласит:
Вы можете реализовать IDispatch любым из следующих способов:
- [отрезать]
- Вызов функции CreateStdDispatch. Этот подход является самым простым, но он не обеспечивает богатой обработки ошибок или нескольких национальных языков.
- [отрезать]
Отлично, CreateStdDispatch:
Создает стандартную реализацию интерфейса IDispatch с помощью одного вызова функции. Это упрощает предоставление объектов через автоматизацию.
HRESULT CreateStdDispatch( IUnknown FAR* punkOuter, void FAR* pvThis, ITypeInfo FAR* ptinfo, IUnknown FAR* FAR* ppunkStdDisp );
я собирался назвать это так:
CreateStdDispatch(
myUnk, //Pointer to the object's IUnknown implementation.
anotherObject, //Pointer to the object to expose.
nil //Pointer to the type information that describes the exposed object (i has no type info)
dispInterface //the IUnknown of the object that implements IDispatch for me
);
Чего я не могу понять, так это того, как реализация Windows API CreateStdDispatch
знает, какие методы вызывать для моего объекта, тем более что CreateStdDispatch
не знает, какой объектно-ориентированный язык я использую, или его соглашения о вызовах.
Как CreateStdDispatch
узнает
- какой метод вызывать для данного
dispid
? - соглашение о вызовах моего языка?
- как обрабатывать исключения из языка, на котором написан мой объектно-ориентированный объект?
Примечание: у меня нет другого выбора, кроме как реализовать dispinterface
; я не определил интерфейс . Я бы хотел, чтобы это была простая ранняя привязка IUnknown
, но это не так.
TAutoIntfObject
или я что-то упустил? - person David Heffernan   schedule 28.06.2011Invoke
, так как ни один потребитель никогда не зайдет достаточно далеко, чтобы вызвать его в любом случае. Потребитель вызоветGetIDsOfNames
, чтобы узнать dispid метода или свойства, которое он хочет вызвать, но вы ответите, что он не реализован. Без dispid потребитель не может заполнить первый параметрInvoke
. Кроме того, в документации не сказано, чтоE_NOTIMPL
является допустимым результатомGetIDsOfNames
. - person Rob Kennedy   schedule 29.06.2011dispIDs
, который он хочет вызвать. См. превосходные примеры обработки событий автоматизации от Techvanguard (techvanguards.com/products/eventsinkimp). - person Ian Boyd   schedule 29.06.2011