📄 automtn.cpp
字号:
obj.SetDispatchPtr(dispatch); return true; } else return false;}// A way of initialising another wxAutomationObject with a dispatch objectbool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& property, int noArgs, const wxVariant **args) const{ WXIDISPATCH* dispatch = GetDispatchProperty(property, noArgs, args); if (dispatch) { obj.SetDispatchPtr(dispatch); return true; } else return false;}// Get a dispatch pointer from the current object associated// with a class idbool wxAutomationObject::GetInstance(const wxString& classId) const{ if (m_dispatchPtr) return false; CLSID clsId; IUnknown * pUnk = NULL; wxBasicString unicodeName(classId.mb_str()); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { wxLogWarning(wxT("Cannot obtain CLSID from ProgID")); return false; } if (FAILED(GetActiveObject(clsId, NULL, &pUnk))) { wxLogWarning(wxT("Cannot find an active object")); return false; } if (pUnk->QueryInterface(IID_IDispatch, (LPVOID*) &m_dispatchPtr) != S_OK) { wxLogWarning(wxT("Cannot find IDispatch interface")); return false; } return true;}// Get a dispatch pointer from a new object associated// with the given class idbool wxAutomationObject::CreateInstance(const wxString& classId) const{ if (m_dispatchPtr) return false; CLSID clsId; wxBasicString unicodeName(classId.mb_str()); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { wxLogWarning(wxT("Cannot obtain CLSID from ProgID")); return false; } // start a new copy of Excel, grab the IDispatch interface if (FAILED(CoCreateInstance(clsId, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&m_dispatchPtr))) { wxLogWarning(wxT("Cannot start an instance of this class.")); return false; } return true;}WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant){ ClearVariant(&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() ; } // cVal not always present#ifndef __GNUWIN32__ else if (type == wxT("char")) { oleVariant.vt=VT_I1; // Signed Char oleVariant.cVal=variant.GetChar(); }#endif else if (type == wxT("double")) { oleVariant.vt = VT_R8; oleVariant.dblVal = variant.GetDouble(); } else if (type == wxT("bool")) { oleVariant.vt = VT_BOOL; // 'bool' required for VC++ 4 apparently#if (defined(__VISUALC__) && (__VISUALC__ <= 1000)) oleVariant.bool = variant.GetBool();#else oleVariant.boolVal = variant.GetBool();#endif } 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; long dosDateTime = date.GetAsDOS(); short dosDate = short((dosDateTime & 0xFFFF0000) >> 16); short dosTime = short(dosDateTime & 0xFFFF); DosDateTimeToVariantTime(dosDate, dosTime, & 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;}#ifndef VT_TYPEMASK#define VT_TYPEMASK 0xfff#endifWXDLLEXPORT bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant){ switch (oleVariant.vt & VT_TYPEMASK) { case VT_BSTR: { wxString str(wxConvertStringFromOle(oleVariant.bstrVal)); variant = str; break; } case VT_DATE: {#if wxUSE_DATETIME unsigned short dosDate = 0; unsigned short dosTime = 0; VariantTimeToDosDateTime(oleVariant.date, & dosDate, & dosTime); long dosDateTime = (dosDate << 16) || dosTime; wxDateTime date; date.SetFromDOS(dosDateTime); variant = date;#endif break; } case VT_I4: { variant = (long) oleVariant.lVal; break; } case VT_I2: { variant = (long) oleVariant.iVal; break; } case VT_BOOL: {#if (defined(_MSC_VER) && (_MSC_VER <= 1000) && !defined(__MWERKS__) ) //GC#ifndef HAVE_BOOL // Can't use bool operator if no native bool type variant = (long) (oleVariant.bool != 0);#else variant = (bool) (oleVariant.bool != 0);#endif#else#ifndef HAVE_BOOL // Can't use bool operator if no native bool type variant = (long) (oleVariant.boolVal != 0);#else variant = (bool) (oleVariant.boolVal != 0);#endif#endif break; } case VT_R8: { variant = oleVariant.dblVal; break; } case VT_ARRAY: { variant.ClearList(); int cDims, cElements, i; VARIANTARG* pvdata; // Iterate the dimensions: number of elements is x*y*z for (cDims = 0, cElements = 1; cDims < oleVariant.parray->cDims; cDims ++) cElements *= oleVariant.parray->rgsabound[cDims].cElements; // Get a pointer to the data HRESULT hr = SafeArrayAccessData(oleVariant.parray, (void HUGEP* FAR*) & pvdata); if (hr != NOERROR) return false; // Iterate the data. for (i = 0; i < cElements; i++) { VARIANTARG& oleElement = pvdata[i]; wxVariant vElement; if (!wxConvertOleToVariant(oleElement, vElement)) return false; variant.Append(vElement); } SafeArrayUnaccessData(oleVariant.parray); 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")); return false; } } return true;}/* * ClearVariant * * Zeros a variant structure without regard to current contents */static void ClearVariant(VARIANTARG *pvarg){ pvarg->vt = VT_EMPTY; pvarg->wReserved1 = 0; pvarg->wReserved2 = 0; pvarg->wReserved3 = 0; pvarg->lVal = 0;}/* * ReleaseVariant * * Clears a particular variant structure and releases any external objects * or memory contained in the variant. Supports the data types listed above. */static void ReleaseVariant(VARIANTARG *pvarg){ VARTYPE vt; VARIANTARG _huge *pvargArray; LONG lLBound, lUBound, l; vt = (VARTYPE)(pvarg->vt & 0xfff); // mask off flags // check if an array. If so, free its contents, then the array itself. if (V_ISARRAY(pvarg)) { // variant arrays are all this routine currently knows about. Since a // variant can contain anything (even other arrays), call ourselves // recursively. if (vt == VT_VARIANT) { SafeArrayGetLBound(pvarg->parray, 1, &lLBound); SafeArrayGetUBound(pvarg->parray, 1, &lUBound); if (lUBound > lLBound) { lUBound -= lLBound; SafeArrayAccessData(pvarg->parray, (void**)&pvargArray); for (l = 0; l < lUBound; l++) { ReleaseVariant(pvargArray); pvargArray++; } SafeArrayUnaccessData(pvarg->parray); } } else { wxLogWarning(wxT("ReleaseVariant: Array contains non-variant type")); } // Free the array itself. SafeArrayDestroy(pvarg->parray); } else { switch (vt) { case VT_DISPATCH: if (pvarg->pdispVal) pvarg->pdispVal->Release(); break; case VT_BSTR: SysFreeString(pvarg->bstrVal); break; case VT_I2: case VT_I4: case VT_BOOL: case VT_R8: case VT_ERROR: // to avoid erroring on an error return from Excel case VT_EMPTY: // no work for these types break; default: wxLogWarning(wxT("ReleaseVariant: Unknown type")); break; } } ClearVariant(pvarg);}#if 0void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned int uiArgErr){ TCHAR szBuf[512]; switch (GetScode(hr)) { case DISP_E_UNKNOWNNAME: wsprintf(szBuf, L"%s: Unknown name or named argument.", szMember); break; case DISP_E_BADPARAMCOUNT: wsprintf(szBuf, L"%s: Incorrect number of arguments.", szMember); break; case DISP_E_EXCEPTION: wsprintf(szBuf, L"%s: Error %d: ", szMember, pexcep->wCode); if (pexcep->bstrDescription != NULL) lstrcat(szBuf, pexcep->bstrDescription); else lstrcat(szBuf, L"<<No Description>>"); break; case DISP_E_MEMBERNOTFOUND: wsprintf(szBuf, L"%s: method or property not found.", szMember); break; case DISP_E_OVERFLOW: wsprintf(szBuf, L"%s: Overflow while coercing argument values.", szMember); break; case DISP_E_NONAMEDARGS: wsprintf(szBuf, L"%s: Object implementation does not support named arguments.", szMember); break; case DISP_E_UNKNOWNLCID: wsprintf(szBuf, L"%s: The locale ID is unknown.", szMember); break; case DISP_E_PARAMNOTOPTIONAL: wsprintf(szBuf, L"%s: Missing a required parameter.", szMember); break; case DISP_E_PARAMNOTFOUND: wsprintf(szBuf, L"%s: Argument not found, argument %d.", szMember, uiArgErr); break; case DISP_E_TYPEMISMATCH: wsprintf(szBuf, L"%s: Type mismatch, argument %d.", szMember, uiArgErr); break; default: wsprintf(szBuf, L"%s: Unknown error occurred.", szMember); break; } wxLogWarning(szBuf);}#endif#endif // wxUSE_OLE_AUTOMATION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -