Страница 54 из 111
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; } |