Property для ActiveX объекта
От: larisa Украина  
Дата: 05.07.04 15:19
Оценка:
Как описать Property для ActiveX объекта, наследованного от IDispatch ( без ATL ), что бы можно было обратиться к этим Property из VBscript.
С ув. Лариса
Re: Property для ActiveX объекта
От: rus blood Россия  
Дата: 05.07.04 15:23
Оценка:
Здравствуйте, larisa, Вы писали:

L>Как описать Property для ActiveX объекта, наследованного от IDispatch ( без ATL ), что бы можно было обратиться к этим Property из VBscript.


Прописать их в idl-файле, и соответственно, реализовать.
Имею скафандр — готов путешествовать!
Re[2]: Property для ActiveX объекта
От: larisa Украина  
Дата: 05.07.04 15:35
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, larisa, Вы писали:


RB>Прописать их в idl-файле, и соответственно, реализовать.

Кто такой idl-файл?
У меня уже есть реализованый объект. Вот его описание.


class Math : public IDispatch
{
private:
    int         _CallRead;

public:
    Math();
    ~Math();

    /* IUnknown methods */
    STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
    STDMETHOD_(unsigned long, AddRef)(void);
    STDMETHOD_(unsigned long, Release)(void);

    /* IDispatch methods */
    STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pcTypeInfo);

    STDMETHOD(GetTypeInfo)(
      unsigned int iTypeInfo,
      LCID lcid,
      ITypeInfo FAR* FAR* ppTypeInfo);

    STDMETHOD(GetIDsOfNames)(
      REFIID riid,
      OLECHAR FAR* FAR* rgszNames,
      unsigned int cNames,
      LCID lcid,
      DISPID FAR* rgdispid);

    STDMETHOD(Invoke)(
        DISPID dispidMember,
        REFIID riid,
        LCID lcid,
        unsigned short wFlags,
        DISPPARAMS FAR* pdispparams,
        VARIANT FAR* pvarResult,
        EXCEPINFO FAR* pexcepinfo,
        unsigned int FAR* pwArgErr);

    virtual int Add(int Op1, int Op2);
    virtual int Sub(int Op1, int Op2);
    virtual int Mul(int Op1, int Op2);
    virtual int Div(int Op1, int Op2);

    virtual void Shw( void );

    unsigned long m_refs;
};


Понятно, что реализации всех методов есть.
И его методы нормально зовутся из VBScript и нормально обрабатываются, а вот добиться что бы обрабатывались Property не могу.
С ув. Лариса
Re[3]: Property для ActiveX объекта
От: rus blood Россия  
Дата: 05.07.04 15:37
Оценка:
Здравствуйте, larisa, Вы писали:

L>Понятно, что реализации всех методов есть.


Круто. Реализацию GetIDsOfNames и Invoke покажи, плз.
Имею скафандр — готов путешествовать!
Re[4]: Property для ActiveX объекта
От: larisa Украина  
Дата: 05.07.04 15:48
Оценка:
Здравствуйте, rus blood, Вы писали:


RB>Круто. Реализацию GetIDsOfNames и Invoke покажи, плз.

Постараюсь более или мение корректно выдрать. Ага чт бы не забыть

........................
enum IDMEMBER_MATH {
    IDMEMBER_MATH_ADD = 1,
    IDMEMBER_MATH_SUB = 2,
    IDMEMBER_MATH_MUL = 3,
    IDMEMBER_MATH_DIV = 4,
    IDMEMBER_MATH_SHW = 5,
    IDMEMBER_MATH_PROP_GET = 6,
    IDMEMBER_MATH_PROP_SET = 7,

    IDMEMBER_MATH_MAX
};

........................

STDMETHODIMP
    Math::GetIDsOfNames(
        REFIID riid,

        OLECHAR FAR* FAR* rgszNames,
        unsigned int cNames,
        LCID lcid,
        DISPID FAR* rgdispid)
{

static MEMBERDESC rgmdCPoint[] = {
    {OLESTR("Add"),    IDMEMBER_MATH_ADD,   NULL,   0},
    {OLESTR("Sub"),    IDMEMBER_MATH_SUB,   NULL,   0},
    {OLESTR("Mul"),    IDMEMBER_MATH_MUL,   NULL,   0},
    {OLESTR("Div"),    IDMEMBER_MATH_DIV,   NULL,   0},
    {OLESTR("Shw"),    IDMEMBER_MATH_SHW,   NULL,   0}
};

    // this object only exposed the "default" interface.
    //
    if(!IsEqualIID(riid, IID_NULL))
      return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

    return SPolyGetIDsOfNames(
      rgmdCPoint, DIM(rgmdCPoint), rgszNames, cNames, lcid, rgdispid);
}
//---------------------------------------------------------------------------
STDMETHODIMP Math::Invoke(
        DISPID dispidMember,
        REFIID riid,
        LCID lcid,
        unsigned short wFlags,
        DISPPARAMS FAR* pdispparams,
        VARIANT FAR* pvarResult,
        EXCEPINFO FAR* pexcepinfo,
        unsigned int FAR* puArgErr)
{
    unsigned int uArgErr;
    HRESULT hresult;
    VARIANTARG varg0,varg1;

    VARIANT varResultDummy;

    UNUSED(lcid);
    UNUSED(pexcepinfo);

    // make sure the wFlags are legal
    if(wFlags & ~(DISPATCH_METHOD | DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
      return ResultFromScode(E_INVALIDARG);

    // this object only exposes a "default" interface.
    //
    if(!IsEqualIID(riid, IID_NULL))
      return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

    // this makes the following code a bit simpler

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

    switch(dispidMember){

        case IDMEMBER_MATH_ADD:
            VariantInit(&varg0);
            VariantInit(&varg1);
            // assume the return type is void, unless we find otherwise.
            VariantInit(pvarResult);

            hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
            if(hresult != NOERROR)
                return hresult;
              hresult = DispGetParam(pdispparams, 1, VT_I2, &varg1, puArgErr);
            if(hresult != NOERROR)
                return hresult;

            V_VT(pvarResult) = VT_I2;
            V_I2(pvarResult) = Add(V_I2(&varg0),V_I2(&varg1));
            break;

        case IDMEMBER_MATH_SUB:
            VariantInit(&varg0);
            VariantInit(&varg1);
            // assume the return type is void, unless we find otherwise.
            VariantInit(pvarResult);

            hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
            if(hresult != NOERROR)
                return hresult;
            hresult = DispGetParam(pdispparams, 1, VT_I2, &varg1, puArgErr);
            if(hresult != NOERROR)
                return hresult;

            V_VT(pvarResult) = VT_I2;
            V_I2(pvarResult) = Sub(V_I2(&varg0),V_I2(&varg1));
            break;

        case IDMEMBER_MATH_MUL:
            VariantInit(&varg0);
            VariantInit(&varg1);
            // assume the return type is void, unless we find otherwise.
            VariantInit(pvarResult);

            hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
            if(hresult != NOERROR)
                return hresult;
            hresult = DispGetParam(pdispparams, 1, VT_I2, &varg1, puArgErr);
            if(hresult != NOERROR)
                return hresult;

            V_VT(pvarResult) = VT_I2;
            V_I2(pvarResult) = Mul(V_I2(&varg0),V_I2(&varg1));
            break;

        case IDMEMBER_MATH_DIV:
            VariantInit(&varg0);
            VariantInit(&varg1);
            // assume the return type is void, unless we find otherwise.
            VariantInit(pvarResult);

            hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
            if(hresult != NOERROR)
                return hresult;
            hresult = DispGetParam(pdispparams, 1, VT_I2, &varg1, puArgErr);
            if(hresult != NOERROR)
                return hresult;

            V_VT(pvarResult) = VT_I2;
            V_I2(pvarResult) = Div(V_I2(&varg0),V_I2(&varg1));
            break;

        case IDMEMBER_MATH_SHW:
            Shw();
            break;

        default:
            return ResultFromScode(DISP_E_MEMBERNOTFOUND);
    }
    return NOERROR;
}
//---------------------------------------------------------------------------



Кажется так
С ув. Лариса
Re[5]: Property для ActiveX объекта
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 05.07.04 16:00
Оценка:
Здравствуйте, larisa, Вы писали:

L>Кажется так


есди код отбивать соответствующими тэгами то читается он гораздо приятнее. кажется так
Re[6]: Property для ActiveX объекта
От: larisa Украина  
Дата: 05.07.04 16:04
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>Здравствуйте, larisa, Вы писали:


L>>Кажется так

Ты прав, конечно. Я сегодня уже с этими пропертами так намучалась, что не очень уверена в своем имени
С ув. Лариса
Re[5]: Property для ActiveX объекта
От: Vi2 Удмуртия http://www.adem.ru
Дата: 06.07.04 04:08
Оценка:
Здравствуйте, larisa, Вы писали:

L>    IDMEMBER_MATH_PROP_GET = 6,
L>    IDMEMBER_MATH_PROP_SET = 7,

    IDMEMBER_MATH_PROP = 6,

Свойства должны иметь один DISPID на оба способа: как get, так и set/put (так же как и putref).

L>    Math::GetIDsOfNames(...)
L>{
L>static MEMBERDESC rgmdCPoint[] = {
L>    {OLESTR("Add"),    IDMEMBER_MATH_ADD,   NULL,   0},
L>    {OLESTR("Sub"),    IDMEMBER_MATH_SUB,   NULL,   0},
L>    {OLESTR("Mul"),    IDMEMBER_MATH_MUL,   NULL,   0},
L>    {OLESTR("Div"),    IDMEMBER_MATH_DIV,   NULL,   0},
L>    {OLESTR("Shw"),    IDMEMBER_MATH_SHW,   NULL,   0}

    {OLESTR("Prop"),    IDMEMBER_MATH_PROP,   NULL,   0}

GetIDsOfNames должна реализовать соответствие имен и их DISPIDов независимо от типа функции (метод или свойство). Фактический вызов определяется клиентом.

L>    Math::Invoke(DISPID dispidMember,...,unsigned short wFlags,...)

Вот эта функция и выполняет всю работу. wFlags говорит, что за функциональность требуется от имени, соответствующему dispidMember.

L>    switch(dispidMember){
...
    case IDMEMBER_MATH_PROP:

    if( (wFlags & (DISPATCH_METHOD | DISPATCH_PROPERTYGET)) != 0 )
    {
        // GET свойство - обработка

        // обязательно зполнить pvarResult, если он представлен
        break;
    }
    if( (wFlags & DISPATCH_PROPERTYPUT) != 0 )
    {
        // PUT свойство - обработка

        break;
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Property для ActiveX объекта
От: larisa Украина  
Дата: 06.07.04 07:31
Оценка:
Здравствуйте, Vi2, Вы писали:

Сначала большое спасибо
Vi2>[ccode]
L>> switch(dispidMember){
Vi2>...
Vi2> case IDMEMBER_MATH_PROP:

Vi2> if( (wFlags & (DISPATCH_METHOD | DISPATCH_PROPERTYGET)) != 0 )

Vi2> {
Vi2> // GET свойство — обработка

Vi2> // обязательно зполнить pvarResult, если он представлен

Vi2> break;
C Get все в порядке -- заработало.
Vi2> }
Vi2> if( (wFlags & DISPATCH_PROPERTYPUT) != 0 )
Vi2> {
Vi2> // PUT свойство — обработка

Vi2> break;

А с Put проблема. Как мне получить значение, которое устанавливает пользователь в макросе?
С ув. Лариса
Re[7]: Property для ActiveX объекта
От: Vi2 Удмуртия http://www.adem.ru
Дата: 06.07.04 07:45
Оценка:
Здравствуйте, larisa, Вы писали:

L>А с Put проблема. Как мне получить значение, которое устанавливает пользователь в макросе?


Он передается в нулевом элементе параметра pdispparams.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Property для ActiveX объекта
От: Аноним  
Дата: 06.07.04 08:04
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, larisa, Вы писали:


L>>А с Put проблема. Как мне получить значение, которое устанавливает пользователь в макросе?


Vi2>Он передается в нулевом элементе параметра pdispparams.

При попытке его прочитать

hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);
Мне возвращают ошибку DISP_E_PARAMNOTFOUND
Re[9]: Property для ActiveX объекта
От: Vi2 Удмуртия http://www.adem.ru
Дата: 06.07.04 08:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>При попытке его прочитать hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);

А>Мне возвращают ошибку DISP_E_PARAMNOTFOUND

Я забыл, что ты пользуешься DispGetParam.
[MSDN]
If you have used DispGetParam to get the right side of a property put operation, the second parameter should be DISPID_PROPERTYPUT. For example:
DispGetParam(&dispparams, DISPID_PROPERTYPUT, VT_BOOL, &varResult, &uiArg)
[/MSDN]
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: Property для ActiveX объекта
От: larisa Украина  
Дата: 06.07.04 08:32
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Аноним, Вы писали:


А>>При попытке его прочитать hresult = DispGetParam(pdispparams, 0, VT_I2, &varg0, puArgErr);

А>>Мне возвращают ошибку DISP_E_PARAMNOTFOUND

Vi2>Я забыл, что ты пользуешься DispGetParam.

Vi2>[MSDN]
Vi2>If you have used DispGetParam to get the right side of a property put operation, the second parameter should be DISPID_PROPERTYPUT. For example:
Vi2>
Vi2>DispGetParam(&dispparams, DISPID_PROPERTYPUT, VT_BOOL, &varResult, &uiArg)
Vi2>
[/MSDN]

Все заработало -- я просто на прямую взяла нужный параметр, но этот способ тоже сейчас попробую.
Всем огромное спасибо! А тебе, Vi2, особое. Будешь в Киеве за мной пиво

С ув. Лариса
С ув. Лариса
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.