home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OCFSRC.PAK / AUTOCLI.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  5KB  |  214 lines

  1. //
  2. //----------------------------------------------------------------------------
  3. // ObjectComponents
  4. // (C) Copyright 1994 by Borland International, All Rights Reserved
  5. //
  6. // OLE Automation Client Implementation
  7. //----------------------------------------------------------------------------
  8. #include <ocf/ocfpch.h>
  9. #include <ocf/autodefs.h>
  10.  
  11. TAutoProxyArgs::~TAutoProxyArgs()
  12. {
  13.   while (Count >= 0)
  14.     ::VariantClear((VARIANT far*)((TAutoVal*)(this+1)+Count--));
  15. }
  16.  
  17. void TAutoProxy::Bind(const char far* progid)
  18. {
  19.   PRECONDITION(progid);
  20.  
  21.   GUID guid;
  22.   TXOle::Check(CLSIDFromProgID(OleStr(progid), &guid), progid);
  23.   Bind(guid);
  24. }
  25.  
  26. void TAutoProxy::Bind(const GUID& guid)
  27. {
  28.   IUnknown* unk;
  29.   HRESULT stat = ::CoCreateInstance(guid,0,CLSCTX_SERVER,IID_IUnknown,(void FAR*FAR*)&unk);
  30.   if (stat != HR_NOERROR) {
  31.     char guidBuf[60];
  32.     TClassId copy(guid);
  33.     lstrcpy (guidBuf, copy);
  34.     TXOle::Check(stat, guidBuf);
  35.   }
  36.   Bind(unk);
  37. }
  38.  
  39. void TAutoProxy::Bind(IUnknown* unk)
  40. {
  41.   if (!unk)
  42.     return;
  43.   IDispatch* dsp;
  44.   HRESULT stat = unk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp);
  45.   unk->Release();
  46.   TXOle::Check(stat, "IUnknown");
  47.   Bind(dsp);
  48. }
  49.  
  50. void TAutoProxy::Bind(IDispatch* dsp)
  51. {
  52.   Unbind();
  53.   That = dsp;
  54. }
  55.  
  56. void TAutoProxy::Bind(IUnknown& unk)
  57. {
  58.   IDispatch* dsp;
  59.   TXOle::Check(unk.QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp), "IUnknown");
  60.   Bind(dsp);
  61. }
  62.  
  63. void TAutoProxy::Bind(IDispatch& obj)
  64. {
  65.   Unbind();
  66.   obj.AddRef();
  67.   That = &obj;
  68. }
  69.  
  70. void TAutoProxy::Bind(TAutoVal& val)
  71. {
  72.   if (val.GetDataType() == atVoid)
  73.     That = 0;
  74.   else
  75.     Bind((IDispatch&)val);  // throws exception if fails
  76. }
  77.  
  78. void TAutoProxy::MustBeBound()
  79. {
  80.   if (!That)
  81.     throw TXAuto(TXAuto::xNotIDispatch);
  82. }
  83.  
  84. long TAutoProxy::Lookup(const char far* name)
  85. {
  86.   if (!name)
  87.     name = "(null)";  // force controlled failure
  88.   long id;
  89.  
  90.   MustBeBound();
  91. #if defined(BI_OLECHAR_WIDE)
  92.   TString tsname(name);
  93.   wchar_t* wname = tsname;
  94.   TXOle::Check(That->GetIDsOfNames(IID_NULL, &wname, 1, Lang, &id), name);
  95. #else
  96.   TXOle::Check(That->GetIDsOfNames(IID_NULL, &const_cast<char far*>(name), 1, Lang, &id), name);
  97. #endif
  98.   return id;
  99. }
  100.  
  101. void TAutoProxy::Lookup(const char far* names, long* ids, unsigned count)
  102. {
  103.   MustBeBound();
  104.  
  105. #if defined(BI_OLECHAR_WIDE)
  106.   const char far* pc = names;
  107.   for (int i = 0; i < count; i++) {
  108.     pc += strlen(pc) + 1;
  109.   }
  110.   wchar_t* wnames = TUString::ConvertAtoW(names, pc-names-1);
  111.   wchar_t** args = new wchar_t far*[count];
  112.   wchar_t* pw = wnames;
  113.   for (i = 0; i < count; i++) {
  114.     args[i] = pw;
  115.     pw += lstrlenW(pw) + 1;
  116.   }
  117.   HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids);
  118.   delete wnames;
  119. #else
  120.   char far** args = new char far*[count];
  121.   const char far* pc = names;
  122.   for (int i = 0; i < count; i++) {
  123.     args[i] = (char far*)pc; // for non-unicode, names separated by null bytes
  124.     pc += strlen(pc) + 1;
  125.   }
  126.   HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids);
  127. #endif
  128.   delete [] args;
  129.   if (stat) {
  130.     int bad = 0;
  131.     if ((stat = HR_DISP_UNKNOWNNAME) != HR_NOERROR)
  132.       while (bad < count && ids[bad] != DISPID_UNKNOWN) {
  133.         bad++;
  134.         names += (strlen(names) + 1);
  135.       }
  136.     TXOle::Check(stat, names);
  137.   }
  138. }
  139.  
  140. TAutoVal&
  141. TAutoProxy::Invoke(uint16 attr, TAutoProxyArgs& args, long* ids, unsigned named)
  142. {
  143.   EXCEPINFO errinfo;
  144.   unsigned int errarg;
  145.   VARIANT far* retval = 0;
  146.  
  147.   MustBeBound();
  148.   if (!(attr & (acPropSet | acVoidRet))) {
  149.     retval = args;
  150.     ::VariantInit(retval);
  151.   }
  152.   DISPID funcId = ids[0];
  153.   DISPPARAMS params;
  154.   params.cArgs = args;
  155.   params.cNamedArgs = named;  
  156.   params.rgvarg = args;
  157.   params.rgdispidNamedArgs = ids;
  158.   if (attr & acPropSet) {
  159.     ids[0] = DISPID_PROPERTYPUT;
  160.     params.cNamedArgs++;
  161.     params.cArgs++;
  162.   } else {
  163.     params.rgdispidNamedArgs++;
  164.     params.rgvarg++;
  165.   }
  166.   HRESULT stat = That->Invoke(funcId, IID_NULL, Lang,
  167.                               uint16(attr & (acMethod | acPropSet | acPropGet)),
  168.                               ¶ms, retval, &errinfo, &errarg);
  169.   ids[0] = funcId;         // restore function id incase PropSet
  170.   if (stat != HR_NOERROR) {
  171.     char buf[50];
  172.     wsprintf(buf, "Invoke Id = %ld", funcId);
  173.     TXOle::Check(stat, buf);
  174.   }
  175.   return args;
  176. }
  177.  
  178. TAutoEnumeratorBase::TAutoEnumeratorBase(const TAutoEnumeratorBase& copy)
  179. {
  180.   Current.Copy(copy.Current);
  181.   Iterator = copy.Iterator;
  182.   if (Iterator)
  183.     TXOle::Check(Iterator->Clone(&Iterator));
  184. }
  185.  
  186. void TAutoEnumeratorBase::operator =(const TAutoEnumeratorBase& copy)
  187. {
  188.   Current.Copy(copy.Current);
  189.   Unbind();
  190.   Iterator = copy.Iterator;
  191.   if (Iterator)
  192.     TXOle::Check(Iterator->Clone(&Iterator));
  193. }
  194.  
  195. void TAutoEnumeratorBase::Bind(TAutoVal& val)
  196. {
  197.   Unbind();
  198.   IUnknown& unk = val;
  199.   TXOle::Check(unk.QueryInterface(IID_IEnumVARIANT, (void far* far*) &Iterator),
  200.                "_NewEnum");
  201. }
  202.  
  203. bool TAutoEnumeratorBase::Step()
  204. {
  205.   Clear();
  206.   if (!Iterator)
  207.     TXOle::Check(HR_NOINTERFACE, "_NewEnum");
  208.   else if (HRIsOK(Iterator->Next(1,(VARIANT far*)&Current,0)))
  209.     return true;
  210.   return false;
  211. }
  212.  
  213.  
  214.