// //---------------------------------------------------------------------------- // ObjectComponents // (C) Copyright 1994 by Borland International, All Rights Reserved // // OLE Automation Client Implementation //---------------------------------------------------------------------------- #include #include TAutoProxyArgs::~TAutoProxyArgs() { while (Count >= 0) ::VariantClear((VARIANT far*)((TAutoVal*)(this+1)+Count--)); } void TAutoProxy::Bind(const char far* progid) { PRECONDITION(progid); GUID guid; TXOle::Check(CLSIDFromProgID(OleStr(progid), &guid), progid); Bind(guid); } void TAutoProxy::Bind(const GUID& guid) { IUnknown* unk; HRESULT stat = ::CoCreateInstance(guid,0,CLSCTX_SERVER,IID_IUnknown,(void FAR*FAR*)&unk); if (stat != HR_NOERROR) { char guidBuf[60]; TClassId copy(guid); lstrcpy (guidBuf, copy); TXOle::Check(stat, guidBuf); } Bind(unk); } void TAutoProxy::Bind(IUnknown* unk) { if (!unk) return; IDispatch* dsp; HRESULT stat = unk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp); unk->Release(); TXOle::Check(stat, "IUnknown"); Bind(dsp); } void TAutoProxy::Bind(IDispatch* dsp) { Unbind(); That = dsp; } void TAutoProxy::Bind(IUnknown& unk) { IDispatch* dsp; TXOle::Check(unk.QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp), "IUnknown"); Bind(dsp); } void TAutoProxy::Bind(IDispatch& obj) { Unbind(); obj.AddRef(); That = &obj; } void TAutoProxy::Bind(TAutoVal& val) { if (val.GetDataType() == atVoid) That = 0; else Bind((IDispatch&)val); // throws exception if fails } void TAutoProxy::MustBeBound() { if (!That) throw TXAuto(TXAuto::xNotIDispatch); } long TAutoProxy::Lookup(const char far* name) { if (!name) name = "(null)"; // force controlled failure long id; MustBeBound(); #if defined(BI_OLECHAR_WIDE) TString tsname(name); wchar_t* wname = tsname; TXOle::Check(That->GetIDsOfNames(IID_NULL, &wname, 1, Lang, &id), name); #else TXOle::Check(That->GetIDsOfNames(IID_NULL, &const_cast(name), 1, Lang, &id), name); #endif return id; } void TAutoProxy::Lookup(const char far* names, long* ids, unsigned count) { MustBeBound(); #if defined(BI_OLECHAR_WIDE) const char far* pc = names; for (int i = 0; i < count; i++) { pc += strlen(pc) + 1; } wchar_t* wnames = TUString::ConvertAtoW(names, pc-names-1); wchar_t** args = new wchar_t far*[count]; wchar_t* pw = wnames; for (i = 0; i < count; i++) { args[i] = pw; pw += lstrlenW(pw) + 1; } HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids); delete wnames; #else char far** args = new char far*[count]; const char far* pc = names; for (int i = 0; i < count; i++) { args[i] = (char far*)pc; // for non-unicode, names separated by null bytes pc += strlen(pc) + 1; } HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids); #endif delete [] args; if (stat) { int bad = 0; if ((stat = HR_DISP_UNKNOWNNAME) != HR_NOERROR) while (bad < count && ids[bad] != DISPID_UNKNOWN) { bad++; names += (strlen(names) + 1); } TXOle::Check(stat, names); } } TAutoVal& TAutoProxy::Invoke(uint16 attr, TAutoProxyArgs& args, long* ids, unsigned named) { EXCEPINFO errinfo; unsigned int errarg; VARIANT far* retval = 0; MustBeBound(); if (!(attr & (acPropSet | acVoidRet))) { retval = args; ::VariantInit(retval); } DISPID funcId = ids[0]; DISPPARAMS params; params.cArgs = args; params.cNamedArgs = named; params.rgvarg = args; params.rgdispidNamedArgs = ids; if (attr & acPropSet) { ids[0] = DISPID_PROPERTYPUT; params.cNamedArgs++; params.cArgs++; } else { params.rgdispidNamedArgs++; params.rgvarg++; } HRESULT stat = That->Invoke(funcId, IID_NULL, Lang, uint16(attr & (acMethod | acPropSet | acPropGet)), ¶ms, retval, &errinfo, &errarg); ids[0] = funcId; // restore function id incase PropSet if (stat != HR_NOERROR) { char buf[50]; wsprintf(buf, "Invoke Id = %ld", funcId); TXOle::Check(stat, buf); } return args; } TAutoEnumeratorBase::TAutoEnumeratorBase(const TAutoEnumeratorBase& copy) { Current.Copy(copy.Current); Iterator = copy.Iterator; if (Iterator) TXOle::Check(Iterator->Clone(&Iterator)); } void TAutoEnumeratorBase::operator =(const TAutoEnumeratorBase& copy) { Current.Copy(copy.Current); Unbind(); Iterator = copy.Iterator; if (Iterator) TXOle::Check(Iterator->Clone(&Iterator)); } void TAutoEnumeratorBase::Bind(TAutoVal& val) { Unbind(); IUnknown& unk = val; TXOle::Check(unk.QueryInterface(IID_IEnumVARIANT, (void far* far*) &Iterator), "_NewEnum"); } bool TAutoEnumeratorBase::Step() { Clear(); if (!Iterator) TXOle::Check(HR_NOINTERFACE, "_NewEnum"); else if (HRIsOK(Iterator->Next(1,(VARIANT far*)&Current,0))) return true; return false; }