Справочник по технологии COM
Страница 54. DispGetParam


DispGetParam

Считывает параметр из структуры DISPPARAMS, проверяя как позиционные, так и именованные параметры, и приводит параметр к заданному типу.

HRESULT DispGetParam
(
DISPPARAMS FAR* pdispparams,
unsigned int position,
VARTYPE vtTarg,
VARIANT FAR* pvarResult,
unsigned int FAR* puArgErr
);

Параметры:

  • pdispparams - Указатель на параметры, переданные IDispatch::Invoke.
  • position - Позиция параметра в списке аргументов. DispGetParam начинает с конца массива, так что если position равен 0, то возвращается последний параметр массива.
  • vtTarg - Тип, к которому следует привести значение параметра.
  • pvarResult - Указатель на вариант, в который следует поместить параметр.
  • puArgErr - После возврата указывает на индекс аргумента, вызвавшего ошибку DISP_E_TYPEMISMATCH. Этот указатель возвращается Invoke, чтобы указать позицию вызвавшего ошибку аргумента в DISPPARAMS.

Коды возврата:
Из возвращенного HRESULT получают один из следующих кодов возврата:

Код возврата Значение
S_OK Успех.
DISP_E_BADVARTYPE Тип варианта vtTarg не поддерживается.
DISP_E_OVERFLOW Полученный параметр невозможно привести к заданному типу.
DISP_E_PARAMNOTFOUND Параметр, заданный position, не найден.
DISP_E_TYPEMISMATCH Аргумент невозможно привести к заданному типу.
E_INVALIDARG Один из параметров неверен.
E_OUTOFMEMORY He хватает памяти для выполнения операции.

Комментарии:
Выходной параметр pvarResult должен быть допустимым вариантом. Текущее содержимое будет освобождено стандартным способом. Содержимое варианта освобождается с помощью VariantFree.
Если Вы используете DispGetParam для получения правой части в операции установки значения свойства, то вторым параметром должен быть DISPID_PROPERTYPUT. Например:

DispGetParam(&dispparams, DISPID_PROPERTYPUT, VT_BOOL, &varResult)

Невозможен доступ к именованным параметрам позиционно, и наоборот.

Пример:
В следующем примере DispGetParam используется для установки свойств X и Y:

STDMETHODIMP CPoint::Invoke(
DISPID dispidMember,
REFIID riid,
LCID Icid,
unsigned short wFlags,
DISPPARAMS FAR* pdispparams,
VARIANT FAR* pvarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr)

{
unsigned int uArgErr;
HRESULT hresult;
VARIANTARG vargO;
VARIANT varResultDummy;
UNUSED(lcid);
UNUSED(pExcepInfo);
// Проверка wFlags.

if (wFlags & (DISPATCH_METHOD | DISPATCH_PROPERTYGET |
DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
return ResultFromScode(E_INVALIDARG);

// Данный объект предоставляет только интерфейс "по умолчанию".

if(!IsEqualIID(riid, IID_NULL))
return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

// Упрощает следующий ниже код в том случае, когда
// вызывающий игнорирует возвращаемое значение.


if(puArgErr == NULL)
puArgErr = &uArgErr;
if(pvarResult == NULL)
pvarResult = &varResultDummy;
VariantInit(&vargO);

// Исходно предполагаем, что возвращаемого значения нет.

Variantlnit(pvarResult);
switch(dispidMember)
{
case IDMEMBER_CPOINT_GETX:
V_VT(pvarResult) = VT_I2;
V_I2(pvarResult) = GetX();
break;

case IDMEMBER_CPOINT_SETX:
hresult = DispGetParam(pdispparams, 0, VT_I2, &vargO, puArgErr);
if(hresult != NOERROR) return hresult;
SetX(V_I2(&vargO));
break;

case IDMEMBER_CPOINT_GETY:
V_VT(pvarResult) = VT_I2;
V_I2( pvarResult) = GetY();
break;

case IDMEMBER_CPOINT_SETY:
hresult = DispGetParam(pdispparams, 0, VT_I2, &vargO, puArgErr);
if(hresult != NOERROR) return hresult;
SetY(V_I2(&vargO));
break;

default:
return ResultFromScode(DISP_E_MEMBERNOTFOUND);
}

return NOERROR;
}

 
Следующая статья »