Пример #1
0
wxVariant &wxActiveXEvent::operator [](size_t idx)
{
    wxASSERT(idx < ParamCount());
    wxActiveXEventNativeMSW *native=GetNativeParameters();
    // 'native' will always be != if the event has been created
    // for an actual active X event.
    // But it may be zero if the event has been created by wx program code.
    if (native)
    {
        while ( m_params.GetCount()<=idx )
        {
            m_params.Append(wxActiveXEvents::ms_invalidEntryMarker);
        }

        wxVariant& vx = m_params[idx];
        if ( vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) &&
                vx == wxActiveXEvents::ms_invalidEntryMarker)
        {
            // copy the _real_ parameter into this one
            // NOTE: m_params stores the parameters in *reverse* order.
            // Whyever, but this was the case in the original implementation of
            // wxActiveXEvents::Invoke
            // Keep this convention.
            VARIANTARG& va = native->pDispParams->rgvarg[ native->pDispParams->cArgs - idx - 1 ];
            wxConvertOleToVariant(va, vx);
        }
        return vx;
    }
    return m_params[idx];
}
Пример #2
0
WXDLLEXPORT bool
wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant, long flags)
{
    bool ok = true;
    if ( oleVariant.vt & VT_ARRAY )
    {
        if ( flags & wxOleConvertVariant_ReturnSafeArrays  )
        {
            variant.SetData(new wxVariantDataSafeArray(oleVariant.parray));
        }
        else
        {
            switch (oleVariant.vt & VT_TYPEMASK)
            {
                case VT_I2:
                    ok = wxSafeArray<VT_I2>::ConvertToVariant(oleVariant.parray, variant);
                    break;
                case VT_I4:
                    ok = wxSafeArray<VT_I4>::ConvertToVariant(oleVariant.parray, variant);
                    break;
                case VT_R4:
                    ok = wxSafeArray<VT_R4>::ConvertToVariant(oleVariant.parray, variant);
                    break;
                case VT_R8:
                    ok = wxSafeArray<VT_R8>::ConvertToVariant(oleVariant.parray, variant);
                    break;
                case VT_VARIANT:
                    ok = wxSafeArray<VT_VARIANT>::ConvertToVariant(oleVariant.parray, variant);
                    break;
                case VT_BSTR:
                    {
                        wxArrayString strings;
                        if ( wxSafeArray<VT_BSTR>::ConvertToArrayString(oleVariant.parray, strings) )
                            variant = strings;
                        else
                            ok = false;
                    }
                    break;
                default:
                    ok = false;
                    break;
            }
            if ( !ok )
            {
                wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
                           oleVariant.vt & VT_TYPEMASK);
                variant = wxVariant();
            }
        }
    }
    else if ( oleVariant.vt & VT_BYREF )
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_VARIANT:
                {
                    VARIANTARG& oleReference = *((LPVARIANT)oleVariant.byref);
                    if (!wxConvertOleToVariant(oleReference,variant))
                        return false;
                    break;
                }

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
                            oleVariant.vt);
                return false;
        }
    }
    else // simply type (not array or reference)
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_ERROR:
                variant.SetData(new wxVariantDataErrorCode(oleVariant.scode));
                break;

            case VT_CY:
                variant.SetData(new wxVariantDataCurrency(oleVariant.cyVal));
                break;

            case VT_BSTR:
                {
                    wxString str(wxConvertStringFromOle(oleVariant.bstrVal));
                    variant = str;
                }
                break;

            case VT_DATE:
#if wxUSE_DATETIME
                {
                    SYSTEMTIME st;
                    VariantTimeToSystemTime(oleVariant.date, &st);

                    wxDateTime date;
                    date.SetFromMSWSysTime(st);
                    variant = date;
                }
#endif // wxUSE_DATETIME
                break;

#if wxUSE_LONGLONG
            case VT_I8:
                variant = wxLongLong(oleVariant.llVal);
                break;
#endif // wxUSE_LONGLONG

            case VT_I4:
                variant = (long) oleVariant.lVal;
                break;

            case VT_I2:
                variant = (long) oleVariant.iVal;
                break;

            case VT_BOOL:
                variant = oleVariant.boolVal != 0;
                break;

            case VT_R4:
                variant = oleVariant.fltVal;
                break;

            case VT_R8:
                variant = oleVariant.dblVal;
                break;

            case VT_DISPATCH:
                variant = (void*) oleVariant.pdispVal;
                break;

            case VT_NULL:
            case VT_EMPTY:
                variant.MakeNull();
                break;

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
                           oleVariant.vt,oleVariant.vt&VT_TYPEMASK);
                return false;
        }
    }

    return ok;
}
Пример #3
0
WXDLLEXPORT bool
wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant)
{
    bool ok = true;
    if ( oleVariant.vt & VT_ARRAY )
    {
        // TODO: We currently return arrays as wxVariant of the list type
        //       containing the flattened form of array but we should allow
        //       getting it as wxVariantDataSafeArray instead. Doing this is
        //       simple, we'd just need to do something like this:
        //
        //  if ( oleVariant.parray && SafeArrayGetDim(oleVariant.parray) > 1 )
        //  {
        //      variant.SetData(new wxVariantDataSafeArray(oleVariant.parray));
        //  }
        //
        //      but currently we don't do it for compatibility reasons.
        switch (oleVariant.vt & VT_TYPEMASK)
        {
            case VT_I2:
                ok = wxSafeArray<VT_I2>::ConvertToVariant(oleVariant.parray, variant);
                break;
            case VT_I4:
                ok = wxSafeArray<VT_I4>::ConvertToVariant(oleVariant.parray, variant);
                break;
            case VT_R4:
                ok = wxSafeArray<VT_R4>::ConvertToVariant(oleVariant.parray, variant);
                break;
            case VT_R8:
                ok = wxSafeArray<VT_R8>::ConvertToVariant(oleVariant.parray, variant);
                break;
            case VT_VARIANT:
                ok = wxSafeArray<VT_VARIANT>::ConvertToVariant(oleVariant.parray, variant);
                break;
            case VT_BSTR:
                {
                    wxArrayString strings;
                    if ( wxSafeArray<VT_BSTR>::ConvertToArrayString(oleVariant.parray, strings) )
                        variant = strings;
                    else
                        ok = false;
                }
                break;
            default:
                ok = false;
                break;
        }
        if ( !ok )
        {
            wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
                       oleVariant.vt & VT_TYPEMASK);
            variant = wxVariant();
        }
    }
    else if ( oleVariant.vt & VT_BYREF )
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_VARIANT:
                {
                    VARIANTARG& oleReference = *((LPVARIANT)oleVariant.byref);
                    if (!wxConvertOleToVariant(oleReference,variant))
                        return false;
                    break;
                }

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
                            oleVariant.vt);
                return false;
        }
    }
    else // simply type (not array or reference)
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
            case VT_ERROR:
                variant.SetData(new wxVariantDataErrorCode(oleVariant.scode));
                break;

            case VT_CY:
                variant.SetData(new wxVariantDataCurrency(oleVariant.cyVal));
                break;

            case VT_BSTR:
                {
                    wxString str(wxConvertStringFromOle(oleVariant.bstrVal));
                    variant = str;
                }
                break;

            case VT_DATE:
#if wxUSE_DATETIME
                {
                    SYSTEMTIME st;
                    VariantTimeToSystemTime(oleVariant.date, &st);

                    wxDateTime date;
                    date.SetFromMSWSysTime(st);
                    variant = date;
                }
#endif // wxUSE_DATETIME
                break;

                // See the comment before the __VISUALC6__ test above.
#if wxUSE_LONGLONG && !defined(__VISUALC6__)
            case VT_I8:
                variant = wxLongLong(oleVariant.llVal);
                break;
#endif // wxUSE_LONGLONG

            case VT_I4:
                variant = (long) oleVariant.lVal;
                break;

            case VT_I2:
                variant = (long) oleVariant.iVal;
                break;

            case VT_BOOL:
                variant = oleVariant.boolVal != 0;
                break;

            case VT_R4:
                variant = oleVariant.fltVal;
                break;

            case VT_R8:
                variant = oleVariant.dblVal;
                break;

            case VT_DISPATCH:
                variant = (void*) oleVariant.pdispVal;
                break;

            case VT_NULL:
                variant.MakeNull();
                break;

            case VT_EMPTY:
                break;    // Ignore Empty Variant, used only during destruction of objects

            default:
                wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
                           oleVariant.vt,oleVariant.vt&VT_TYPEMASK);
                return false;
        }
    }

    return ok;
}
Пример #4
0
WXDLLEXPORT bool
wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant)
{
    bool ok = true;
    if ( oleVariant.vt & VT_ARRAY )
    {

        // Compute the total number of elements in all array dimensions
        int cElements = 1;
        for ( int cDims = 0; cDims < oleVariant.parray->cDims; cDims++ )
            cElements *= oleVariant.parray->rgsabound[cDims].cElements;

        // Get a pointer to the data
        void* pvdata;
        HRESULT hr = SafeArrayAccessData(oleVariant.parray, &pvdata);
        if ( FAILED(hr) )
            return false;

        switch (oleVariant.vt & VT_TYPEMASK)
        {
        case VT_VARIANT:
        {
            variant.ClearList();
            VARIANTARG *variant_data=(VARIANTARG*)pvdata;
            for ( int i = 0; i < cElements; i++ )
            {
                VARIANTARG& oleElement = variant_data[i];
                wxVariant vElement;
                if ( !wxConvertOleToVariant(oleElement, vElement) )
                {
                    ok = false;
                    variant.ClearList();
                    break;
                }

                variant.Append(vElement);
            }
        }
        break;

        case VT_BSTR:
        {
            wxArrayString strings;
            BSTR *string_val=(BSTR*)pvdata;
            for ( int i = 0; i < cElements; ++i )
            {
                wxString str=wxConvertStringFromOle(*string_val);
                strings.Add(str);
                ++string_val;
            }
            variant=strings;
        }
        break;

        default:
            wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"),
                       oleVariant.vt & VT_TYPEMASK);
            variant = wxVariant();
            ok = false;
            break;
        }

        SafeArrayUnaccessData(oleVariant.parray);
    }
    else if ( oleVariant.vt & VT_BYREF )
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
        case VT_VARIANT:
        {
            VARIANTARG& oleReference = *((LPVARIANT)oleVariant.byref);
            if (!wxConvertOleToVariant(oleReference,variant))
                return false;
            break;
        }

        default:
            wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),
                       oleVariant.vt);
            return false;
        }
    }
    else // simply type (not array or reference)
    {
        switch ( oleVariant.vt & VT_TYPEMASK )
        {
        case VT_BSTR:
        {
            wxString str(wxConvertStringFromOle(oleVariant.bstrVal));
            variant = str;
        }
        break;

        case VT_DATE:
#if wxUSE_DATETIME
        {
            SYSTEMTIME st;
            VariantTimeToSystemTime(oleVariant.date, &st);

            wxDateTime date;
            date.SetFromMSWSysTime(st);
            variant = date;
        }
#endif // wxUSE_DATETIME
        break;

        case VT_I4:
            variant = (long) oleVariant.lVal;
            break;

        case VT_I2:
            variant = (long) oleVariant.iVal;
            break;

        case VT_BOOL:
            variant = oleVariant.boolVal != 0;
            break;

        case VT_R8:
            variant = oleVariant.dblVal;
            break;

        case VT_DISPATCH:
            variant = (void*) oleVariant.pdispVal;
            break;

        case VT_NULL:
            variant.MakeNull();
            break;

        case VT_EMPTY:
            break;    // Ignore Empty Variant, used only during destruction of objects

        default:
            wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),
                       oleVariant.vt,oleVariant.vt&VT_TYPEMASK);
            return false;
        }
    }

    return ok;
}
Пример #5
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;
}