Beispiel #1
0
    STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
                        LCID lcid,
                          WORD wFlags, DISPPARAMS * pDispParams,
                          VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
                          unsigned int * puArgErr)
    {
        if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
            return E_NOTIMPL;

        wxASSERT(m_activeX);

        // ActiveX Event

        // Dispatch Event
        wxActiveXEvent  event;
        event.SetEventType(wxEVT_ACTIVEX);
        // Create an empty list of Variants
        // Note that the event parameters use lazy evaluation
        // They are not actually created until wxActiveXEvent::operator[] is called
        event.m_params.NullList();
        event.m_dispid = dispIdMember;

        // save the native (MSW) event parameters for event handlers that need to access them
        // this can be done on the stack since wxActiveXEvent is also allocated on the stack
        wxActiveXEventNativeMSW eventParameters(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
        event.SetClientData(&eventParameters);

        // The event parameters are not copied to event.m_params until they are actually
        // referenced in wxActiveXEvent::operator[]
        // This increases performance and avoids error messages and/or crashes
        // when the event has parameters that are not (yet or never) supported
        // by wxConvertOleToVariant

        // process the events from the activex method
        m_activeX->ProcessEvent(event);
        for (DWORD i = 0; i < pDispParams->cArgs; i++)
        {
            size_t params_index = pDispParams->cArgs - i - 1;
            if (params_index < event.m_params.GetCount()) {
                wxVariant &vx = event.m_params[params_index];
                // copy the result back to pDispParams only if the event has been accessed
                //  i.e.  if vx != ms_invalidEntryMarker
                if (!vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) || vx!=ms_invalidEntryMarker) {
                    VARIANTARG& va = pDispParams->rgvarg[i];
                    wxConvertVariantToOle(vx, va);
                }
            }
        }

        if(event.GetSkipped())
            return DISP_E_MEMBERNOTFOUND;

        return S_OK;
    }
Beispiel #2
0
WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant)
{
    VariantInit(&oleVariant);
    if (variant.IsNull())
    {
        oleVariant.vt = VT_NULL;
        return true;
    }

    wxString type(variant.GetType());


    if (type == wxT("long"))
    {
        oleVariant.vt = VT_I4;
        oleVariant.lVal = variant.GetLong() ;
    }
    else if (type == wxT("char"))
    {
        oleVariant.vt=VT_I1;            // Signed Char
        oleVariant.cVal=variant.GetChar();
    }
    else if (type == wxT("double"))
    {
        oleVariant.vt = VT_R8;
        oleVariant.dblVal = variant.GetDouble();
    }
    else if (type == wxT("bool"))
    {
        oleVariant.vt = VT_BOOL;
        oleVariant.boolVal = variant.GetBool();
    }
    else if (type == wxT("string"))
    {
        wxString str( variant.GetString() );
        oleVariant.vt = VT_BSTR;
        oleVariant.bstrVal = wxConvertStringToOle(str);
    }
#if wxUSE_DATETIME
    else if (type == wxT("datetime"))
    {
        wxDateTime date( variant.GetDateTime() );
        oleVariant.vt = VT_DATE;

        SYSTEMTIME st;
        date.GetAsMSWSysTime(&st);

        SystemTimeToVariantTime(&st, &oleVariant.date);
    }
#endif
    else if (type == wxT("void*"))
    {
        oleVariant.vt = VT_DISPATCH;
        oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr();
    }
    else if (type == wxT("list") || type == wxT("stringlist"))
    {
        oleVariant.vt = VT_VARIANT | VT_ARRAY;

        SAFEARRAY *psa;
        SAFEARRAYBOUND saBound;
        VARIANTARG *pvargBase;
        VARIANTARG *pvarg;
        int i, j;

        int iCount = variant.GetCount();

        saBound.lLbound = 0;
        saBound.cElements = iCount;

        psa = SafeArrayCreate(VT_VARIANT, 1, &saBound);
        if (psa == NULL)
            return false;

        SafeArrayAccessData(psa, (void**)&pvargBase);

        pvarg = pvargBase;
        for (i = 0; i < iCount; i++)
        {
            // copy each string in the list of strings
            wxVariant eachVariant(variant[i]);
            if (!wxConvertVariantToOle(eachVariant, * pvarg))
            {
                // memory failure:  back out and free strings alloc'ed up to
                // now, and then the array itself.
                pvarg = pvargBase;
                for (j = 0; j < i; j++)
                {
                    SysFreeString(pvarg->bstrVal);
                    pvarg++;
                }
                SafeArrayDestroy(psa);
                return false;
            }
            pvarg++;
        }

        SafeArrayUnaccessData(psa);

        oleVariant.parray = psa;
    }
    else
    {
        oleVariant.vt = VT_NULL;
        return false;
    }
    return true;
}
Beispiel #3
0
// For Put/Get, no named arguments are allowed.
bool wxAutomationObject::Invoke(const wxString& member, int action,
        wxVariant& retValue, int noArgs, wxVariant args[], const wxVariant* ptrArgs[]) const
{
    if (!m_dispatchPtr)
        return false;

    int ch = member.Find('.');
    if (ch != -1)
    {
        // Use dot notation to get the next object
        wxString member2(member.Left((size_t) ch));
        wxString rest(member.Right(member.length() - ch - 1));
        wxAutomationObject obj;
        if (!GetObject(obj, member2))
            return false;
        return obj.Invoke(rest, action, retValue, noArgs, args, ptrArgs);
    }

    VARIANTARG vReturn;
    VariantInit(& vReturn);

    VARIANTARG* vReturnPtr = & vReturn;

    // Find number of names args
    int namedArgCount = 0;
    int i;
    for (i = 0; i < noArgs; i++)
        if ( !INVOKEARG(i).GetName().empty() )
        {
            namedArgCount ++;
        }

    int namedArgStringCount = namedArgCount + 1;
    BSTR* argNames = new BSTR[namedArgStringCount];
    argNames[0] = wxConvertStringToOle(member);

    // Note that arguments are specified in reverse order
    // (all totally logical; hey, we're dealing with OLE here.)

    int j = 0;
    for (i = 0; i < namedArgCount; i++)
    {
        if ( !INVOKEARG(i).GetName().empty() )
        {
            argNames[(namedArgCount-j)] = wxConvertStringToOle(INVOKEARG(i).GetName());
            j ++;
        }
    }

    // + 1 for the member name, + 1 again in case we're a 'put'
    DISPID* dispIds = new DISPID[namedArgCount + 2];

    HRESULT hr;
    DISPPARAMS dispparams;
    unsigned int uiArgErr;

    // Get the IDs for the member and its arguments.  GetIDsOfNames expects the
    // member name as the first name, followed by argument names (if any).
    hr = ((IDispatch*)m_dispatchPtr)->GetIDsOfNames(IID_NULL, argNames,
                                1 + namedArgCount, LOCALE_SYSTEM_DEFAULT, dispIds);
    if (FAILED(hr))
    {
        ShowException(member, hr);
        delete[] argNames;
        delete[] dispIds;
        return false;
    }

    // if doing a property put(ref), we need to adjust the first argument to have a
    // named arg of DISPID_PROPERTYPUT.
    if (action & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
    {
        namedArgCount = 1;
        dispIds[1] = DISPID_PROPERTYPUT;
        vReturnPtr = NULL;
    }

    // Convert the wxVariants to VARIANTARGs
    VARIANTARG* oleArgs = new VARIANTARG[noArgs];
    for (i = 0; i < noArgs; i++)
    {
        // Again, reverse args
        if (!wxConvertVariantToOle(INVOKEARG((noArgs-1) - i), oleArgs[i]))
        {
            delete[] argNames;
            delete[] dispIds;
            delete[] oleArgs;
            return false;
        }
    }

    dispparams.rgdispidNamedArgs = dispIds + 1;
    dispparams.rgvarg = oleArgs;
    dispparams.cArgs = noArgs;
    dispparams.cNamedArgs = namedArgCount;

    EXCEPINFO excep;
    wxZeroMemory(excep);

    hr = ((IDispatch*)m_dispatchPtr)->Invoke(dispIds[0], IID_NULL, LOCALE_SYSTEM_DEFAULT,
                        (WORD)action, &dispparams, vReturnPtr, &excep, &uiArgErr);

    for (i = 0; i < namedArgStringCount; i++)
    {
        SysFreeString(argNames[i]);
    }
    delete[] argNames;
    delete[] dispIds;

    for (i = 0; i < noArgs; i++)
        VariantClear(& oleArgs[i]) ;
    delete[] oleArgs;

    if (FAILED(hr))
    {
        // display the exception information if appropriate:
        ShowException(member, hr, &excep, uiArgErr);

        // free exception structure information
        SysFreeString(excep.bstrSource);
        SysFreeString(excep.bstrDescription);
        SysFreeString(excep.bstrHelpFile);

        if (vReturnPtr)
            VariantClear(vReturnPtr);
        return false;
    }
    else
    {
        if (vReturnPtr)
        {
            // Convert result to wxVariant form
            wxConvertOleToVariant(vReturn, retValue);
            // Mustn't release the dispatch pointer
            if (vReturn.vt == VT_DISPATCH)
            {
                vReturn.pdispVal = NULL;
            }
            VariantClear(& vReturn);
        }
    }
    return true;
}