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

📄 utilcls.h

📁 实现最短路径算法。 实现最短路径算法。
💻 H
📖 第 1 页 / 共 5 页
字号:
      OLECHECK(src->QueryInterface(GetIID(), (LPVOID*)(&intf)));
    }
    return *this;
  }

#if defined(SYSTOBJ_H)
  template <class I>
  TComInterface<T, piid>& operator=(const DelphiInterface<I>& src)
  {
    _ASSERTE_(/* Need have valid IID to invoke this */GetIID() != GUID_NULL);
    Reset();
    if (src)
    {
      OLECHECK(src->QueryInterface(GetIID(), (LPVOID*)(&intf)));
    }
    return *this;
  }
#endif

  TComInterface<T, piid>& operator=(const TComInterface<T, piid>& src)
  {
    if (src.intf != 0)
      src.intf->AddRef();
    Reset(src.intf);
    return *this;
  }

  bool      operator ! () const  {   return (intf == 0); }
  operator      bool   () const  {   return (intf != 0); }
  bool      IsBound    () const  {   return !!(*this);   }

  HRESULT   CreateInstance(const CLSID& clsid, IUnknown* pOuter = 0, DWORD dwClsContext = CLSCTX_ALL);
  HRESULT   CreateInstance(LPOLESTR progid, IUnknown* pOuter = 0, DWORD dwClsContext = CLSCTX_ALL);


public:
  __property  IID iid = { read = GetIID };

protected:
  T* intf;
};


// Create instance of interface via 'CoCreateInstance' with specified CLSID
//
template <class T, const IID* piid>
HRESULT TComInterface<T, piid>::CreateInstance(const CLSID& clsid, IUnknown* pOuter, DWORD dwClsContext)
{
  Reset();  // Free any interface pointers
  IUnknownPtr punk;
  HRESULT hr = ::CoCreateInstance(clsid, pOuter, dwClsContext, IID_IUnknown, reinterpret_cast<LPVOID*>(&punk));
  if (SUCCEEDED(hr))
  {
    hr = ::OleRun(punk);
    if (SUCCEEDED(hr))
      hr = punk->QueryInterface(GetIID(), reinterpret_cast<LPVOID*>(&intf));
  }
  return hr;
}

// Create instance of interface via 'CoCreateInstance' with specified progid
//
template <class T, const IID* piid>
HRESULT TComInterface<T, piid>::CreateInstance(LPOLESTR progid, IUnknown* pOuter, DWORD dwClsContext)
{
  CLSID clsid;
  HRESULT hr = ::CLSIDFromString(progid, &clsid);
  if (SUCCEEDED(hr))
    return CreateInstance(clsid, pOuter, dwClsContext);
  return hr;
}

// Macro used to create typedefs of smart pointers for interfaces.
// Use this macro to create typedefs for standard interfaces not already
// typedefed.
//
#if !defined(_DEF_SMARTPTR)
#define _DEF_SMARTPTR(intf)           class intf; typedef TComInterface<intf>       intf ## Ptr
#define _DEF_SMARTPTR_IID(intf, iid)  class intf; typedef TComInterface<intf, &iid> intf ## Ptr
#endif

// Typedefs for StdVCL interfaces
//
namespace Stdvcl
{class IStrings; class IStringsDisp; class IProvider; class IProviderDisp; class IDataBroker; class IDataBrokerDisp;}
typedef TComInterface<Stdvcl::IStrings        /*,&IID_Istrings    */>     IStringsPtr;
typedef TComInterface<Stdvcl::IStringsDisp    /*,&IID_IStringsDisp*/>     IStringsDispPtr;
typedef TComInterface<Stdvcl::IProvider       /*,&IID_IProvider   */>     IProviderPtr;
typedef TComInterface<Stdvcl::IProviderDisp   /*,&IID_IProviderDisp*/>    IProviderDispPtr;
typedef TComInterface<Stdvcl::IDataBroker     /*,&IID_IDataBroker   */>   IDataBrokerPtr;
typedef TComInterface<Stdvcl::IDataBrokerDisp /*,&IID_IDataBrokerDisp*/>  IDataBrokerDispPtr;

extern "C"  const IID IID_IFont;
extern "C"  const IID IID_IPicture;
extern "C"  const IID IID_IFontDisp;
extern "C"  const IID IID_IPictureDisp;
extern "C"  const IID CLSID_StdFont;
extern "C"  const IID CLSID_StdPicture;
_DEF_SMARTPTR_IID(IUnknown, IID_IUnknown);
_DEF_SMARTPTR_IID(IDispatch, IID_IDispatch);
_DEF_SMARTPTR_IID(IFont, IID_IFont);
_DEF_SMARTPTR_IID(IPicture, IID_IPicture);
_DEF_SMARTPTR_IID(IFontDisp, IID_IFontDisp);
_DEF_SMARTPTR_IID(IPictureDisp, IID_IPictureDisp);
_DEF_SMARTPTR_IID(IEnumVARIANT, IID_IEnumVARIANT);

typedef IUnknownPtr  TCOMIUnknown;    /* Backwards compatibility */
typedef IDispatchPtr TCOMIDispatch;   /* Backwards compatibility */

// Template used to expose 'factory-like' Create/CreateRemote routines for Clients
//
template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
class TCoClassCreatorT : public CoClassCreator
{
public:
  static TOBJ    Create();
  static HRESULT Create(TOBJ& intfObj);
  static HRESULT Create(INTF** ppintf);

  static TOBJ    CreateRemote(LPCWSTR machineName);
  static HRESULT CreateRemote(LPCWSTR machineName, TOBJ& intfObj);
  static HRESULT CreateRemote(LPCWSTR machineName, INTF** ppIntf);
};

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
TOBJ TCoClassCreatorT<TOBJ, INTF, clsid, iid>::Create()
{
  TOBJ intfObj;
  OLECHECK(Create(intfObj));
  return intfObj;
}

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
HRESULT TCoClassCreatorT<TOBJ, INTF, clsid, iid>::Create(TOBJ& intfObj)
{
  return Create(&intfObj);
}

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
HRESULT TCoClassCreatorT<TOBJ, INTF, clsid, iid>::Create(INTF **ppIntf)
{
  return CoCreateInstance(*clsid, *iid, reinterpret_cast<LPVOID*>(ppIntf));
}

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
TOBJ TCoClassCreatorT<TOBJ, INTF, clsid, iid>::CreateRemote(LPCWSTR machineName)
{
  TOBJ intfObj;
  OLECHECK(CreateRemote(machineName, intfObj));
  return intfObj;
}

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
HRESULT TCoClassCreatorT<TOBJ, INTF, clsid, iid>::CreateRemote(LPCWSTR machineName, INTF **ppIntf)
{
  return CoClassCreator::CreateRemote(machineName, *clsid,*iid, ppIntf);
}

template <class TOBJ, class INTF, const CLSID* clsid, const IID* iid>
HRESULT TCoClassCreatorT<TOBJ, INTF, clsid, iid>::CreateRemote(LPCWSTR machineName, TOBJ& intfObj)
{
  return CreateRemote(machineName, &intfObj);
}


// Helper class for cases where VARIANT* or VARIANT& is expected for optional parameters
//
class TNoParam
{
public:
  TNoParam()
  {
    m_Variant.vt = VT_ERROR;
    V_ERROR(&m_Variant) = DISP_E_PARAMNOTFOUND;
  }

  operator VARIANT*  ()         { return &m_Variant;}
  operator VARIANT&  ()         { return m_Variant; }
  operator TVariant* ()         { return &m_Variant;}
  operator TVariant& ()         { return m_Variant; }

private:
  TVariant m_Variant;
};

// Helper class for default LOCALE values
//
class TDefLCID
{
public:
  TDefLCID(LCID lcid = LOCALE_SYSTEM_DEFAULT) : m_Lcid(lcid) {}
  operator LCID () const { return m_Lcid; }

protected:
  LCID  m_Lcid;
};


// Base class that exposes basic behaviour of our array of Variants
//
class TAutoArgsBase
{
protected:
  TAutoArgsBase(VARIANTOBJ *pVariant, int count) : m_Variant(pVariant), m_Count(count)
  {}

public:
  VARIANTOBJ& operator[](int index) const
  {
    // NOTE: It's OK to use Count - there's an extra Variant for return result
    //       Zero'th entry's reserved for return value.
    //
    _ASSERTE_(index <= m_Count);
    _ASSERTE_(index >= 0);

    // Make up for C++ vs. Basic reverse indexing
    //
    return m_Variant[index ? (m_Count+1-index) : 0];
  }

  VARIANT* GetRetVal() const
  {
    return &m_Variant[0];
  }

  VARIANTOBJ& GetRetVariant()
  {
    return *m_Variant;
  }

  VARIANT* GetArgs() const
  {
    return (VARIANT*)(m_Variant+1);
  }

  int GetCount() const
  {
    return m_Count;
  }

private:
  TAutoArgsBase(const TAutoArgsBase&);
  TAutoArgsBase& operator=(const TAutoArgsBase&);

  VARIANTOBJ *m_Variant;
  int         m_Count;
};


// TAutoArgs - Encapsulates array of Variants. Use for Invoke calls
//
template <int Count>
class TAutoArgs : public TAutoArgsBase
{
public:
  TAutoArgs();
 ~TAutoArgs();

private:
  // Allocate an extra Variant. It's the first entry  and
  // it is reserved for return result. The rest are for parameters
  //
  VARIANTOBJ m_Array[Count+1];
};


// Build an array of Count (actualy Count+1, extra one for return value)
// of VARIANTs.
//
template <int Count>
TAutoArgs<Count>::TAutoArgs() : TAutoArgsBase(m_Array, Count)
{}

// Cleanup array of Variants
//
template <int Count>
TAutoArgs<Count>::~TAutoArgs()
{}

// Enumeration describing DISPATCH type
//
enum DispatchFlag
{
  dfMethod    = DISPATCH_METHOD,
  dfPropGet   = DISPATCH_PROPERTYGET,
  dfPropPut   = DISPATCH_PROPERTYPUT,
  dfPropPutRef= DISPATCH_PROPERTYPUTREF
};

// Sets the value in the returnVariant to the retVal variable if SUCCEEDED(hr)
// Used by DispInterface Code Generated by TLIBIMP
//
template <class T>
HRESULT OutRetValSetterPtr(T* retVal, TAutoArgsBase& args, HRESULT hr)
{
  if (SUCCEEDED(hr))
    *retVal = T(args.GetRetVariant());
  return hr;
}

// Sets the value in the returnVariant to the retVal variable if SUCCEEDED(hr)
// Used by DispInterface Code Generated by TLIBIMP
template <class T>
HRESULT OutRetValSetterRef(T& retVal, TAutoArgsBase& args, HRESULT hr)
{
  if (SUCCEEDED(hr))
    retVal = T(args.GetRetVariant());
  return hr;
}

// (Dummy) Component Fake class
// (This class and the TDispatchDelegate template allows the TEventsDispatcher class to be used for
//  generic [non-VCL, Component, Form-based] event dispatching, as well as be the base class of a
//  Form-based component. The difficulties stem from the [f]rigid rules of VCL classes: no multiple
//  inheritance... not even interfaces (Delphi allow these at least but the C++ side is more Delphiesque
//  than Delphi). In order not to duplicate code in two templates, we'll use some dummy classes that
//  remove IDispatch as a base class [since it can't be a base if TComponent is a base class] and allows
//  for a TComponent-derived based class).
//
class TFakeComponentBase
{
public:
  TFakeComponentBase() {}
  TFakeComponentBase(TFakeComponentBase*) {}
};

// Template to delegate implementation of IDispatch to T
// (To work around not allowing MI in VCL class hierarchy - Compiler should allow interfaces but doesn't - BUG??)
//
template <class T>
class TDispatchDelegate : public IDispatch
{
  T&      m_DispImpl;
public:
  TDispatchDelegate(T& impl) : m_DispImpl(impl) {}

  // IUnknown
  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) { return m_DispImpl.QueryInterface(iid, ppvObject); }
  ULONG   STDMETHODCALLTYPE AddRef()                                     { return m_DispImpl.AddRef();  }
  ULONG   STDMETHODCALLTYPE Release()                                    { return m_DispImpl.Release(); }
  // IDispatch
  // IDispatch
  HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctInfo)
  {
    *pctInfo = 0;
    return S_OK;
  }
  HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT, LCID, ITypeInfo** ppTypeInfo)
  {
    *ppTypeInfo = 0;
    return E_NOTIMPL;
  }
  HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*)
  {
    return E_NOTIMPL;
  }
  HRESULT STDMETHODCALLTYPE Invoke(DISPID dispid, REFIID iid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                                   VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgError)
  {
    return m_DispImpl.Invoke(dispid, iid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgError);
  }
};


// TEventDispatcher<>
// ==================
//
// TEventDispatcher<> offer a simple sink implementation: i.e. an implementation of IDispatch that servers
// can call upon to fire events. The template also exposes routines to allow one to easy connect to and
// disconnect the sink from a Server.
//
template <class T, const IID *pEVENTSIID, class BASE = TFakeComponentBase>
class TEventDispatcher : public BASE
{
  typedef TEventDispatcher<T, pEVENTSIID, BASE> ThisClass;

  int                           m_Ref;          // Ref count holder
  DWORD                         m_EventCookie;  // Event Advise/Unadvise cookie
  TDispatchDelegate<ThisClass>  m_Dispatch;     // IDispatch implementation

protected:
  // To be overriden in derived class to dispatch events
  virtual HRESULT InvokeEvent(DISPID id, TVariant* params = 0) = 0;

public:
  TEventDispatcher() : m_Ref(0), m_EventCookie(0), m_Dispatch(*this)
  {}

  TEventDispatcher(BASE* owner) : BASE(owner), m_Ref(0), m_EventCookie(0), m_Dispatch(*this)
  {}

  // COnnect Event IDispatch to Server
  HRESULT ConnectEvents(IUnknown *server);
  HRESULT DisconnectEvents(IUnknown *server);

  // IUnknown
  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);
  ULONG   STDMETHODCALLTYPE AddRef()    { return ++m_Ref; }
  ULONG   STDMETHODCALLTYPE Release()   { return --m_Ref; }

  HRESULT STDMETHODCALLTYPE Invoke(DISPID dispid, REFIID iid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                                   VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgError);
};

// TEventsDispatcher::IUnknown::QueryInterface
//
template <class T, const IID *pEVENTSIID, class BASE> HRESULT STDMETHODCALLTYPE
TEventDispatcher<T, pEVENTSIID, BASE>::QueryInterface(REFIID iid, void **ppvObject)
{
  *ppvObject = 0;
  if ((iid == IID_IDispatch) || (iid == *pEVENTSIID))
  {
    /*static_cast<T*>*/(this)->AddRef();
    *ppvObject = static_cast<IDispatch*>(&m_Dispatch);
  }
  else if (iid == IID_IUnknown)
  {
    /*static_cast<T*>*/(this)->AddRef();
    *ppvObject = static_cast<IUnknown*>(&m_Dispatch);
  }
  else
    return E_NOINTERFACE;
  return S_OK;
}

// TEventsDispatcher::ConnectEvents
//
template <class T, const IID *pEVENTSIID, class BASE> HRESULT
TEventDispatcher<T, pEVENTSIID, BASE>::ConnectEvents(IUnknown* pServer)
{
  HRESULT hr = E_NOINTERFACE;
  TComInterface<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC;
  pCPC = pServer;
  if (pCPC)
  {
    TComInterface<IConnectionPoint, &IID_IConnectionPoint> pCP;
    hr = pCPC->FindConnectionPoint(*pEVENTSIID, &pCP);
    if (SUCCEEDED(hr))
      if (pCP)
        hr = pCP->Advise(static_cast<IUnknown*>(&m_Dispatch), &m_EventCookie);
  }
  return hr;
}

// TEventsDispatcher::DisconnectEvents
//
template <class T, const IID *pEVENTSIID, class BASE> HRESULT
TEventDispatcher<T, pEVENTSIID, BASE>::DisconnectEvents(IUnknown* pServer)
{
  if (m_EventCookie == 0)
    return CONNECT_E_NOCONNECTION;
  HRESULT hr = E_NOINTERFACE;
  TComInterface<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC;
  pCPC = pServer;
  if (pCPC)
  {
    TComInterface<IConnectionPoint, &IID_IConnectionPoint> pCP;
    hr = pCPC->FindConnectionPoint(*pEVENTSIID, &pCP);
    if (SUCCEEDED(hr))
      if (pCP)
        hr = pCP->Unadvise(m_EventCookie);
    if (SUCCEEDED(hr))
      m_EventCookie = 0;
  }
  return hr;
}

// TEventsDispatcher::IDispatch::Invoke
//
template <class T, const IID *pEVENTSIID, class BASE> HRESULT STDMETHODCALLTYPE
TEventDispatcher<T, pEVENTSIID, BASE>::Invoke(DISPID dispid, REFIID /*iid*/, LCID /*lcid*/,
                                              WORD /*wFlags*/, DISPPARAMS* pDispParams,
                                              VARIANT* /*pVarResult*/, EXCEPINFO* /*pExcepInfo*/,
                                              UINT* /*puArgError*/)
{
  TAPtr<TVariant> pParamArray;
  TVariant *pArrayPtr = 0;
  if (pDispParams->cArgs)
  {
    int count = pDispParams->cArgs;
    pParamArray = new TVariant[count];
    // NOTE: row vs. column major!
    for (UINT i=0; i<pDispParams->cArgs; i++)
      pParamArray[count-(i+1)] = pDispParams->rgvarg[i];
    pArrayPtr = pParamArray;
  }
  return InvokeEvent(dispid, pArrayPtr);
};


// If you want to access the following template you must make sure that CLASSES.HPP
// has been included before UTILCLS.H is included.
//
#if defined(ClassesHPP)

// Declare a macro so we may check if the headers were properly included
//
#define __BASE_OF_COMOBJECT_AS_COMPONENT_DEFINED

// TComponnentofCOMObjectWithEvents<

⌨️ 快捷键说明

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