⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wxactivex.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// can return a const reference, which is neccessary for event tables

typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap;
static ActiveXDISPIDEventMap sg_dispIdEventMap;

const wxEventType& RegisterActiveXEvent(DISPID event)
{
    ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event);
    if (it == sg_dispIdEventMap.end())
    {
        wxEventType  *et = new wxEventType(wxNewEventType());
        sg_dispIdEventMap[event] = et;

        return *et;
    };

    return *(it->second);
};

// one off class for automatic freeing of activeX eventtypes
class ActiveXEventMapFlusher
{
public:
    ~ActiveXEventMapFlusher()
    {
        // Named events
        ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end();
        while (it != sg_NamedEventMap.end())
        {
            delete it->second;
            it++;
        };
        sg_NamedEventMap.clear();

        // DISPID events
        ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end();
        while (dit != sg_dispIdEventMap.end())
        {
            delete dit->second;
            dit++;
        };
        sg_dispIdEventMap.clear();
    };
};

static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;


//////////////////////////////////////////////////////
VARTYPE wxTypeToVType(const wxVariant& v)
{
    wxString type = v.GetType();
    if (type == wxT("bool"))
        return VT_BOOL;
    else if (type == wxT("char"))
        return VT_I1;
    else if (type == wxT("datetime"))
        return VT_DATE;
    else if (type == wxT("double"))
        return VT_R8;
    else if (type == wxT("list"))
        return VT_ARRAY;
    else if (type == wxT("long"))
        return VT_I4;
    else if (type == wxT("string"))
        return VT_BSTR;
    else if (type == wxT("stringlist"))
        return VT_ARRAY;
    else if (type == wxT("date"))
        return VT_DATE;
    else if (type == wxT("time"))
        return VT_DATE;
    else if (type == wxT("void*"))
        return VT_VOID | VT_BYREF;
    else
        return VT_NULL;
};

bool wxDateTimeToDATE(wxDateTime dt, DATE& d)
{
    SYSTEMTIME st;
    memset(&st, 0, sizeof(st));

    st.wYear = dt.GetYear();
    st.wMonth = dt.GetMonth() + 1;
    st.wDay = dt.GetDay();
    st.wHour = dt.GetHour();
    st.wMinute = dt.GetMinute();
    st.wSecond = dt.GetSecond();
    st.wMilliseconds = dt.GetMillisecond();
    return SystemTimeToVariantTime(&st, &d) != FALSE;
};

bool wxDateTimeToVariant(wxDateTime dt, VARIANTARG& va)
{
    return wxDateTimeToDATE(dt, va.date);
};

bool DATEToWxDateTime(DATE date, wxDateTime& dt)
{
    SYSTEMTIME st;
    if (! VariantTimeToSystemTime(date, &st))
        return false;

    dt = wxDateTime(
        st.wDay, 
        wxDateTime::Month(int(wxDateTime::Jan) + st.wMonth - 1), 
        st.wYear, 
        st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

    return true;
};

bool VariantToWxDateTime(VARIANTARG va, wxDateTime& dt)
{
    HRESULT hr = VariantChangeType(&va, &va, 0, VT_DATE);
    if (! SUCCEEDED(hr))
        return false;

    return DATEToWxDateTime(va.date, dt);
};

bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx)
{
    bool byRef = false;
    VARTYPE vt = va.vt;

    if (vt & VT_ARRAY)
        return false; // don't support arrays yet

    if (vt & VT_BYREF)
    {
        byRef = true;
        vt &= ~(VT_BYREF);
    };


    switch(vt)
    {
    case VT_VARIANT:
        if (byRef)
            return MSWVariantToVariant(*va.pvarVal, vx);
        else
        {
            VARIANT tmp = va;
            VariantChangeType(&tmp, &tmp, 0, wxTypeToVType(vx));
            bool rc = MSWVariantToVariant(tmp, vx);
            VariantClear(&tmp);
            return rc;
        };

    // 1 byte chars
    case VT_I1:
    case VT_UI1:
        if (byRef)
            vx = (char) *va.pbVal;
        else
            vx = (char) va.bVal;
        return true;

    // 2 byte shorts
    case VT_I2:
    case VT_UI2:
        if (byRef)
            vx = (long) *va.puiVal;
        else
            vx = (long) va.uiVal;
        return true;

    // 4 bytes longs
    case VT_I4:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_ERROR:
        if (byRef)
            vx = (long) *va.pulVal;
        else
            vx = (long) va.ulVal;
        return true;
    

    // 4 byte floats
    case VT_R4:
        if (byRef)
            vx = *va.pfltVal;
        else
            vx = va.fltVal;
        return true;

    // 8 byte doubles
    case VT_R8:
        if (byRef)
            vx = *va.pdblVal;
        else
            vx = va.dblVal;
        return true;

    case VT_BOOL:
        if (byRef)
            vx = (*va.pboolVal ? true : false);
        else
            vx = (va.boolVal ? true : false);
        return true;

    case VT_CY:
        vx.MakeNull();
        return false; // what the hell is a CY ?

    case VT_DECIMAL:
        {
            double d = 0;
            HRESULT hr;
            if (byRef)
                hr = VarR8FromDec(va.pdecVal, &d);
            else
                hr = VarR8FromDec(&va.decVal, &d);

            vx = d;
            return SUCCEEDED(hr);
        };

    case VT_DATE:
        {
            wxDateTime dt;
            bool rc =  false;
            if (byRef)
                rc = DATEToWxDateTime(*va.pdate, dt);
            else
                rc = VariantToWxDateTime(va, dt);
            vx = dt;
            return rc;
        };

    case VT_BSTR:
        if (byRef)
            vx = wxString(*va.pbstrVal);
        else
            vx = wxString(va.bstrVal);
        return true;

    case VT_UNKNOWN: // should do a custom wxVariantData for this
        if (byRef)
            vx = (void *) *va.ppunkVal;
        else
            vx = (void *) va.punkVal;
        return false;

    case VT_DISPATCH: // should do a custom wxVariantData for this
        if (byRef)
            vx = (void *) *va.ppdispVal;
        else
            vx = (void *) va.pdispVal;
        return false;

    default:
        vx.MakeNull();
        return false;
    };
};

bool VariantToMSWVariant(const wxVariant& vx, VARIANTARG& va)
{
    bool byRef = false;
    VARTYPE vt = va.vt;

    if (vt & VT_ARRAY)
        return false; // don't support arrays yet

    if (vt & VT_BYREF)
    {
        byRef = true;
        vt &= ~(VT_BYREF);
    };

    switch(vt)
    {
    case VT_VARIANT:
        if (byRef)
            return VariantToMSWVariant(vx, *va.pvarVal);
        else
        {
            va.vt = wxTypeToVType(vx);
            return VariantToMSWVariant(vx, va);
        };

    // 1 byte chars
    case VT_I1:
    case VT_UI1:
        if (byRef)
            *va.pbVal = (char) vx;
        else
            va.bVal = (char) vx;
        return true;

    // 2 byte shorts
    case VT_I2:
    case VT_UI2:
        if (byRef)
            *va.puiVal = (long) vx;
        else
            va.uiVal = (long) vx;
        return true;

    // 4 bytes longs
    case VT_I4:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
    case VT_ERROR:
        if (byRef)
            *va.pulVal = (long) vx;
        else
            va.ulVal = (long) vx;
        return true;
    

    // 4 byte floats
    case VT_R4:
        if (byRef)
            *va.pfltVal = (double) vx;
        else
            va.fltVal = (double) vx;
        return true;

    // 8 byte doubles
    case VT_R8:
        if (byRef)
            *va.pdblVal = (double) vx;
        else
            va.dblVal = (double) vx;
        return true;

    case VT_BOOL:
        if (byRef)
            *va.pboolVal = ((bool) vx) ? TRUE : FALSE;
        else
            va.boolVal = ((bool) vx) ? TRUE : FALSE;
        return true;

    case VT_CY:
        return false; // what the hell is a CY ?

    case VT_DECIMAL:
        if (byRef)
            return SUCCEEDED(VarDecFromR8(vx, va.pdecVal));
        else
            return SUCCEEDED(VarDecFromR8(vx, &va.decVal));

    case VT_DATE:
        if (byRef)
            return wxDateTimeToDATE(vx, *va.pdate);
        else
            return wxDateTimeToVariant(vx,va);

    case VT_BSTR:
        if (byRef)
            *va.pbstrVal = SysAllocString(vx.GetString().wc_str(wxConvUTF8));
        else
            va.bstrVal = SysAllocString(vx.GetString().wc_str(wxConvUTF8));
        return true;

    case VT_UNKNOWN: // should do a custom wxVariantData for this
        if (byRef)
            *va.ppunkVal = (IUnknown *) (void *) vx;
        else
            va.punkVal = (IUnknown *) (void *) vx;
        return false;

    case VT_DISPATCH: // should do a custom wxVariantData for this
        if (byRef)
            *va.ppdispVal = (IDispatch *) (void *) vx;
        else
            va.pdispVal = (IDispatch *) (void *) vx;
        return false;

    default:
        return false;
    };
};

IMPLEMENT_CLASS(wxActiveXEvent, wxCommandEvent)

class wxActiveXEvents : public IDispatch
{
private:
    DECLARE_OLE_UNKNOWN(wxActiveXEvents);


    wxActiveX   *m_activeX;
    IID         m_customId;
    bool        m_haveCustomId;

    friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);

public:
    wxActiveXEvents(wxActiveX *ax) : m_activeX(ax), m_haveCustomId(false) {}
    wxActiveXEvents(wxActiveX *ax, REFIID iid) : m_activeX(ax), m_haveCustomId(true), m_customId(iid) {}
    virtual ~wxActiveXEvents() 
    {
    }

    //IDispatch
    STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
    { 
        return E_NOTIMPL;
    };

    STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
    { 
        return E_NOTIMPL;
    };

    STDMETHODIMP GetTypeInfoCount(unsigned int* i)
    { 
        return E_NOTIMPL;
    };


    void DispatchEvent(wxActiveX::FuncX &func, const wxEventType& eventType, DISPPARAMS * pDispParams)
    {
        wxActiveXEvent  event;
        event.SetId(m_activeX->GetId());
        event.SetEventType(eventType);
        event.m_params.NullList();
        event.m_params.SetName(func.name);

        // arguments
        if (pDispParams)
        {
            // cdecl call
            // sometimes the pDispParams does not match the param info for a activex control
            int nArg = wxMin(func.params.size(), pDispParams->cArgs);
            for (int i = nArg - 1; i >= 0; i--)
            {
                VARIANTARG& va = pDispParams->rgvarg[i];
                wxActiveX::ParamX &px = func.params[nArg - i - 1];
                wxVariant vx;

                vx.SetName(px.name);
                MSWVariantToVariant(va, vx);
                event.m_params.Append(vx);
            };
        };

        if (func.hasOut)
        {
            int nArg = wxMin(func.params.size(), pDispParams->cArgs);
            m_activeX->GetEventHandler()->ProcessEvent(event);
            for (int i = 0; i < nArg; i++)
            {
                VARIANTARG& va = pDispParams->rgvarg[i];
                wxActiveX::ParamX &px = func.params[nArg - i - 1];

                if (px.IsOut())
                {
                    wxVariant& vx = event.m_params[nArg - i - 1];
                    
                    VariantToMSWVariant(vx, va);
                };
            };
        }
        else
            m_activeX->GetEventHandler()->AddPendingEvent(event);

    };

    STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
                          WORD wFlags, DISPPARAMS * pDispParams,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -