//-----------------------------------------------------------------------------------------------// STDMETHODIMP CMyTrackPriceInfoWithNotify::CancelLastQuote(VARIANT Params) { ATLTRACE(_T("CMyTrackPriceInfoWithNotify::CancelLastQuote\n")); try { if (V_ERROR(&Params) == DISP_E_PARAMNOTFOUND) { _Module.GetMyTrackCore ()->CancelLastQuote (static_cast<CBaseNotifier*>(this),NULL); return S_OK; } else if (V_RECORD(&Params)) { _bstr_t bstrSymbol; _QuoteUpdateParams qup(Params); bstrSymbol = qup->Symbol; _Module.GetMyTrackCore ()->CancelLastQuote (static_cast<CBaseNotifier*>(this),(LPCSTR)bstrSymbol); { _QuoteUpdateParams params(Params); _bstr_t bsFullSymbol = params->Symbol; bsFullSymbol +=_T("_"); bsFullSymbol += params->Exchange; if(params->Type == enOPT) bsFullSymbol +=_T("_"); CCriticalSectionWrapper r(m_csResponce); RESPONCE::iterator iter = m_Responce.begin(); while(iter!=m_Responce.end()) { if(iter->m_enType == CResponce::enLastQuote && iter->m_bsFullSymbol == bstrSymbol) { m_Responce.erase(iter); iter = m_Responce.begin(); } iter++; } } return S_OK; } return DISP_E_BADVARTYPE; } catch (_com_error &err) { return eg_lib::utils::ComError2ErrInfo (err,this); } catch (...) { return DISP_E_BADVARTYPE; } }
BOOL PyObject_AsVARIANTRecordInfo(PyObject *ob, VARIANT *pv) { if (!PyRecord_Check(ob)) { PyErr_SetString(PyExc_TypeError, "Only com_record objects can be used as records"); return NULL; } PyRecord *pyrec = (PyRecord *)ob; HRESULT hr = pyrec->pri->RecordCreateCopy(pyrec->pdata, &V_RECORD(pv)); if (FAILED(hr)) { PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); return FALSE; } V_RECORDINFO(pv) = pyrec->pri; pyrec->pri->AddRef(); return TRUE; }
PyObject *PyRecord::getattro(PyObject *self, PyObject *obname) { PyObject *res; PyRecord *pyrec = (PyRecord *)self; char *name=PYWIN_ATTR_CONVERT(obname); if (name==NULL) return NULL; if (strcmp(name, "__members__")==0) { ULONG cnames = 0; HRESULT hr = pyrec->pri->GetFieldNames(&cnames, NULL); if (FAILED(hr)) return PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); BSTR *strs = (BSTR *)malloc(sizeof(BSTR) * cnames); if (strs==NULL) return PyErr_NoMemory(); hr = pyrec->pri->GetFieldNames(&cnames, strs); if (FAILED(hr)) { free(strs); return PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); } res = PyList_New(cnames); for (ULONG i=0;i<cnames && res != NULL;i++) { PyObject *item = PyWinCoreString_FromString(strs[i]); SysFreeString(strs[i]); if (item==NULL) { Py_DECREF(res); res = NULL; } else PyList_SET_ITEM(res, i, item); // ref count swallowed. } free(strs); return res; } res = PyObject_GenericGetAttr(self, obname); if (res != NULL) return res; PyErr_Clear(); WCHAR *wname; if (!PyWinObject_AsWCHAR(obname, &wname)) return NULL; VARIANT vret; VariantInit(&vret); void *sub_data = NULL; PY_INTERFACE_PRECALL; HRESULT hr = pyrec->pri->GetFieldNoCopy(pyrec->pdata, wname, &vret, &sub_data); PyWinObject_FreeWCHAR(wname); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { if (hr == TYPE_E_FIELDNOTFOUND){ // This is slightly suspect - throwing a unicode // object for an AttributeError in py2k - but this // is the value we asked COM for, so it makes sense... // (and PyErr_Format doesn't handle unicode in py2x) PyErr_SetObject(PyExc_AttributeError, obname); return NULL; } return PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); } // Short-circuit sub-structs and arrays here, so we dont allocate a new chunk // of memory and copy it - we need sub-structs to persist. if (V_VT(&vret)==(VT_BYREF | VT_RECORD)) return new PyRecord(V_RECORDINFO(&vret), V_RECORD(&vret), pyrec->owner); else if (V_VT(&vret)==(VT_BYREF | VT_ARRAY | VT_RECORD)) { SAFEARRAY *psa = *V_ARRAYREF(&vret); int d = SafeArrayGetDim(psa); if (sub_data==NULL) return PyErr_Format(PyExc_RuntimeError, "Did not get a buffer for the array!"); if (SafeArrayGetDim(psa) != 1) return PyErr_Format(PyExc_TypeError, "Only support single dimensional arrays of records"); IRecordInfo *sub = NULL; long ubound, lbound, nelems; int i; BYTE *this_data; PyObject *ret_tuple = NULL; ULONG element_size = 0; hr = SafeArrayGetUBound(psa, 1, &ubound); if (FAILED(hr)) goto array_end; hr = SafeArrayGetLBound(psa, 1, &lbound); if (FAILED(hr)) goto array_end; hr = SafeArrayGetRecordInfo(psa, &sub); if (FAILED(hr)) goto array_end; hr = sub->GetSize(&element_size); if (FAILED(hr)) goto array_end; nelems = ubound-lbound; ret_tuple = PyTuple_New(nelems); if (ret_tuple==NULL) goto array_end; this_data = (BYTE *)sub_data; for (i=0;i<nelems;i++) { PyTuple_SET_ITEM(ret_tuple, i, new PyRecord(sub, this_data, pyrec->owner)); this_data += element_size; } array_end: if (sub) sub->Release(); if (FAILED(hr)) return PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); return ret_tuple; } // This default conversion we use is a little slow (but it will do!) // For arrays, the pparray->pvData member is *not* set, since the actual data // pointer from the record is returned in sub_data, so set it here. if (V_ISARRAY(&vret) && V_ISBYREF(&vret)) (*V_ARRAYREF(&vret))->pvData = sub_data; PyObject *ret = PyCom_PyObjectFromVariant(&vret); // VariantClear(&vret); return ret; }