//----------------------------------------------------------------------------
// ObjectComponents
// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
/// \file
/// OLE Automation Class Definitions
//----------------------------------------------------------------------------
 
#if !defined(OCF_AUTODEFS_H)
#define OCF_AUTODEFS_H
 
#include <owl/private/defs.h>
#if defined(BI_HAS_PRAGMA_ONCE)
# pragma once
#endif
 
#include <ocf/defs.h>
#include <owl/lclstrng.h>   // TLocaleString and TRegItem/TRegList
#include <owl/string.h>     // TString and TUString
#include <ocf/oleutil.h>
 
#if !defined(_OLECTL_H_)
# if defined(__BIVBX_H) && !defined(NO_VBX_PICTURES)
#   error BIVBX.H LPPICTURE is incompatible with OLECTL.H - define NO_VBX_PICTURES
# else
#   define  NO_VBX_PICTURES     // Make sure we're BIVBX's compatible
#   include <olectl.h>          // Ole Controls definitions
# endif
#endif
 
 
 
namespace ocf {
 
//
// Class modifier for inherited classes or members within user C++ classes
// if ambient class model is not used, this macro must be defined to match
//
#if !defined(_AUTOCLASS)
# define  _AUTOCLASS
#endif
 
//
// Forward class references
//
class _AUTOCLASS TAutoDetach;
class _AUTOCLASS TAutoBase;
class _ICLASS TAppDescriptor;  // defined in appdesc.h
class _ICLASS TServedObject;
class _ICLASS TAutoIterator;
class    TAutoCreator;
class    TAutoCommand;
struct  TAutoSymbol;
class    TAutoString;
class    TAutoStack;
class  TAutoVal;
class    TXAuto;
class    TAutoEnum;
 
_OCFFUNC(const void *) DynamicCast(const void * obj, const std::type_info& src,
                                                  const std::type_info& dst);
 
_OCFFUNC(const void *) MostDerived(const void * obj, const std::type_info& src);
//
// Global function to invalidate external references, class model-independent
//
_OCFFUNC(void) SendObituary(const void * obj, const std::type_info& typeInfo);
 
//----------------------------------------------------------------------------
// Automation typedefs
//
 
typedef unsigned long TLocaleId;   // locale ID - same as NT LCID
 
class _AUTOCLASS TAutoBase {   // default base for automatable objects
  public:
    virtual ~TAutoBase();// only member is virtual destructor for unregistration
};
 
class _AUTOCLASS TAutoDetach { // default base for detach notification objects
  protected:
    void Notify(int offset, const std::type_info& typeInfo);  // sends obituary
};          // the size of this object must be 0 to not affect enclosing class
 
typedef void* ObjectPtr;  // generic opaque object pointer
 
//
// Generic conversion function for changing between inherited classes
 
//
template <class T, class B> struct TTypeConvert {
  static ObjectPtr Cast(ObjectPtr from) { return
   reinterpret_cast<ObjectPtr>( dynamic_cast<T*>(reinterpret_cast<B*>(from)));
  }
};
 
typedef ObjectPtr      (*TAutoSymTypeConvert) (ObjectPtr obj);
typedef TAutoCommand*  (*TAutoCommandBuild)(ObjectPtr obj,int attr,TAutoStack&);
typedef TAutoCommand*  (*TAutoCommandBuildDtr)(ObjectPtr obj, int attr);
typedef TAutoIterator* (*TAutoIteratorBuild)(ObjectPtr obj,
                                             TAutoCreator& creator,
                                             IUnknown* owner, owl::TLangId lang);
typedef IUnknown&      (*TAggregator)(ObjectPtr obj, TUnknown& inner);
 
#if defined(BI_COMP_BORLANDC)
extern "C" const GUID __cdecl IID_TServedObject;
#else
EXTERN_C const GUID  IID_TServedObject; // check it !!!!!!!!!!!!!!!!!!!!!!!!
#endif
 
//
/// \class TXAuto
// ~~~~~ ~~~~~~
/// Automation exception object
//
class _OCFCLASS TXAuto : public owl::TXBase {
  public:
    enum TError {
      xNoError,                 //  0
      xConversionFailure,       //  1
      xNotIDispatch,            //  2
      xForeignIDispatch,        //  3
      xTypeMismatch,            //  4
      xNoArgSymbol,             //  5
      xParameterMissing,        //  6
      xNoDefaultValue,          //  7
      xValidateFailure,         //  8
      xExecutionFailure,        //  9
      xErrorStatus,             // 10
    };
    TXAuto(TError err);
           void Throw();
    static void  Raise(TError err);
 
  public:
    TError ErrorCode;
};
 
//----------------------------------------------------------------------------
// TAutoType, TAutoClass - automation type/class descriptor
//
 
struct _OCFCLASS TAutoType {
    owl::uint16 GetType() const {return Type;}
    owl::uint16 Type;
};
 
class _OCFCLASS TAutoClass : public TAutoType {
  public:
    TAutoClass(TAutoSymbol* table, TAutoSymbol* classSymbol,
               const std::type_info& typeInfo, TAggregator aggregator=0);
   ~TAutoClass();
 
    short         CountCommands();    // forces counts to be set on first call
    TAutoSymbol*  Lookup(LPTSTR name, owl::TLangId lang, short symFlags, long & id);
    TAutoSymbol*  LookupArg(LPTSTR name, owl::TLangId lang, TAutoSymbol* cmd,
                            long & retid);
    TAutoSymbol*  FindId(long id, ObjectPtr& objptr);
    TAutoSymbol*  FindFunction(unsigned index, MEMBERID& retId);
    TAutoSymbol*  FindVariable(unsigned index, MEMBERID& retId);
    TXAuto::TError Dispatch(ObjectPtr obj, TAutoCreator& creator,
                            TUnknown& owner, int attr, TAutoStack& args,
                            TAutoVal* retval);
    TAutoSymbol*          GetTable() const;
    TAutoSymbol*          GetClassSymbol() const;
    short                 GetArgCount(TAutoSymbol& sym);
    TAutoCommandBuildDtr  GetDestructor() const;
    const std::type_info& GetTypeInfo() const;
    LPCTSTR               GetName(owl::TLangId lang = owl::TLocaleString::UserDefaultLangId) const;
    LPCTSTR               GetDoc (owl::TLangId lang = owl::TLocaleString::UserDefaultLangId) const;
    unsigned long         GetHelpId() const;
    unsigned short        GetTypeFlags() const;
    int                   GetImplTypeFlags() const;
    unsigned short        GetCoClassFlags() const;
    TAggregator           GetAggregator() const;
    IUnknown&             Aggregate(ObjectPtr obj, TUnknown& inner);
 
  protected:
    TAggregator Aggregator;  ///< aggregator function for C++ COM classes
    short CommandCount;      ///< command count including bases, 0 if uncounted
    short FunctionCount;     ///< number of symbols exposed as typelib functions
    short VariableCount;     ///< number of symbols exposed as typelib variables
    bool  AutoIds;           ///< generate ID's automatically if true (default)
    TAutoSymbol* Table;      ///< pointer to array of symbol entries
    TAutoSymbol* ClassSymbol;///< pointer to class symbol (terminator)
    const std::type_info& TypeInfo;///< for validating type of data pointers
    friend class TServedObject;
 
  private:
    struct TAutoClassRef {   ///< element used for array of TAutoClass objects
      TAutoClass* Class;
      int         GuidOffset;
    };
    struct TExtLink;      // fwd declaration
    static struct TClassList { ///< module-static TAutoClass data
      int  CountAutoClasses();  // walks list in attatched DLLs
      TAutoClassRef* MergeAutoClasses(TAutoClassRef* array);
      TAutoClass* List;   ///< chain of autoclasses in THIS module
      int         Count;  ///< count of classes in THIS module
      TExtLink*   Link;   ///< chain of TAutoClass data for loaded DLLs
    } ClassList;
    struct TExtLink {      // doubly-linked list of external DLL data
      TExtLink(TClassList* list, HINSTANCE module);
     ~TExtLink();
      TClassList* Classes;
      HINSTANCE   Module; // module handle if dynmaically loaded, else 0
      TExtLink*   Next;
      TExtLink**  Prev;
    };
    TAutoClass*   NextClass;          ///< link to next class
    friend struct TExtLink;            ///< access to ClassList
    friend struct TClassList;          ///< access to TAutoClassRef
    friend class  TAppDescriptor;      ///< access to linkage information
    friend class _ICLASS TTypeLibrary;///< access to TAutoClassRef
    friend class _ICLASS TCoClassInfo;///< access to TAutoClassRef
    friend class _ICLASS TOcControlEvent;     ///< access to AutoIds bool
};
 
//----------------------------------------------------------------------------
// TAuto(type) automation datatype encapsulations
//
 
//
// Class to implement assignent of void to TAutoVal
//
struct _OCFCLASS TAutoVoid {
  static TAutoType ClassInfo;
};
 
//
// Class to implement assignment of VT_ERROR/DISP_E_PARAMNOTFOUND
// (i.e. Optional arguments) to TAutoVal
//
struct _OCFCLASS TNoArg {
   //
   // Dummy structure
};
 
//
// Wrapper class to disambiguate automation date type from double
//
#  if defined(BI_COMP_BORLANDC)
#    pragma warn -inl
#  endif
struct _OCFCLASS TAutoDate {
  TAutoDate() : Date(0) {}
  TAutoDate(double d) : Date(d) {}
  operator double() { return Date; }
  double Date;      // same as OLE DATE
  static TAutoType ClassInfo;
};
 
//struct TAutoCurrency : public CY {
struct _OCFCLASS TAutoCurrency {
  owl::uint32 Lo;
  owl::int32  Hi;
 
  operator CY& () {return *reinterpret_cast<CY*>(this);}
 
  static TAutoType ClassInfo;
};
 
struct _OCFCLASS TAutoBool      { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoBoolRef   { static TAutoType ClassInfo; };
 
//
// The following types do not hold data, but only provide static type codes
//
struct _OCFCLASS TAutoShort      { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoDouble     { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoFloat      { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoLong       { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoByte       { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoUnknown    { static TAutoType ClassInfo; };  // for raw IUnknown*
struct _OCFCLASS TAutoDispatch   { static TAutoType ClassInfo; };  // for raw IDispatch*
struct _OCFCLASS TAutoVariant    { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoShortRef   { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoLongRef    { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoFloatRef   { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoDoubleRef  { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoCurrencyRef{ static TAutoType ClassInfo; };
struct _OCFCLASS TAutoDateRef    { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoStringRef  { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoVariantRef { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoSafeArray  { static TAutoType ClassInfo; };
struct _OCFCLASS TAutoByteRef    { static TAutoType ClassInfo; };
//#if (MAXINT==MAXSHORT)
//  typedef TAutoShort    TAutoInt;
//  typedef TAutoShortRef TAutoIntRef;
//#else
  typedef TAutoLong    TAutoInt;
  typedef TAutoLongRef TAutoIntRef;
//#endif
 
//----------------------------------------------------------------------------
/// Attribute flags for automation symbols and command objects
//
enum AutoSymFlag {
  asAnyCommand     = 0x0017,  ///< any command: method, property get/set, build
  asOleType        = 0x0007,  ///< method or property exposed for OLE
  asMethod         = 0x0001,  ///< method     (same as OLE INVOKE_FUNC)
  asGet            = 0x0002,  ///< returns property value (INVOKE_PROPERTYGET)
  asIterator       = 0x000A,  ///< iterator property (_NewEnum)
  asSet            = 0x0004,  ///< set property value     (INVOKE_PROPERTYSET)
  asGetSet         = 0x0006,  ///< can get or set property(...GET + ...SET)
  asBuild          = 0x0010,  ///< contructor command (unsupported by OLE 2.01)
  asFactory        = 0x0020,  ///< for creating objects or class determination
  asClass          = 0x0040,  ///< extension to another class symbol table
  asArgument       = 0x0080,  ///< property returning an object
  asNotTerminator  = 0x00FF,  ///< any symbol except terminator with class info
 
  asBindable       = 0x0400,  ///< sends OnChanged notification
  asRequestEdit    = 0x0800,  ///< sends OnRequest edit before change
  asDisplayBind    = 0x1000,  ///< user-display of bindable
  asDefaultBind    = 0x2000,  ///< this property only is the default (redundant)
  asHidden         = 0x4000,  ///< not visible to normal browsing
  asPersistent     = 0x8000,  ///< property is persistent
};
 
//
/// Automation datatypes and flags - same as OLE 2 definitions
//
enum AutoDataType {
  atVoid              = VT_EMPTY,     //  0x0000,   //  void
  atNull              = VT_NULL,      //  0x0001,   //  SQL style Null
  atShort             = VT_I2,        //  0x0002,   //  2 byte signed int
  atLong              = VT_I4,        //  0x0003,   //  4 byte signed int
  atFloat             = VT_R4,        //  0x0004,   //  4 byte real
  atDouble            = VT_R8,        //  0x0005,   //  8 byte real
  atCurrency          = VT_CY,        //  0x0006,   //  currency
  atDatetime          = VT_DATE,      //  0x0007,   //  datetime as double
  atString            = VT_BSTR,      //  0x0008,   //  String preceeded by length
  atObject            = VT_DISPATCH,  //  0x0009,   //  IDispatch*
  atError             = VT_ERROR,     //  0x000A,   //  SCODE
  atBool              = VT_BOOL,      //  0x000B,   //  True=-1, False=0
  atVariant           = VT_VARIANT,   //  0x000C,   //  VARIANT*
  atUnknown           = VT_UNKNOWN,   //  0x000D,   //  IUnknown*
  atByte              = VT_UI1,       //  0x0011,   //  byte, unsigned char
  atArray             = VT_ARRAY,     //
  atObjectDesc        = 0x001D,   //  object precursor state (internal use only)
  atLoanedBSTR        = 0x001A,   //  BSTR owned by TUString (internal use only)
  atTypeMask          = 0x001F,   //  base type code without bit flags
  atOLE2Mask          = 0x601F,   //  type code with bit flags
};
const owl::uint16 atSafeArray= 0x2000;
const owl::uint16 atByRef    = 0x4000;
const owl::uint16 atEnum     = 0x1000; // non-OLE, enumeration for data of a type
const owl::uint16 atAutoClass= 0x0800; // non-OLE, class object is a TAutoClass
 
//----------------------------------------------------------------------------
// Automated class type info flags - corresponding to OLE 2.02 definitions
//    flags set in END_AUTOCLASS, END_AUTOAGGREGATE, END_AUTOEVENTCLASS macros
//
 
//
// Flags set on any autoclass, but apply only to enclosing coclass type info.
// Autoclasses with any of these bits set will be members of generated coclass.
// These flags from all autoclasses are combined to form the coclass type flags
 
//
const owl::uint16 tfAppObject     =   1; // TYPEFLAG_FAPPOBJECT, set on COCLASS
const owl::uint16 tfCanCreate     =   2; // TYPEFLAG_FCANCREATE, set on COCLASS
const owl::uint16 tfLicensed      =   4; // TYPEFLAG_FLICENSED,  set on COCLASS
const owl::uint16 tfPredeclared   =   8; // TYPEFLAG_FPREDECLID, set on COCLASS
const owl::uint16 tfControl       =  32; // TYPEFLAG_FCONTROL,   set on COCLASS
const owl::uint16 tfCoClassXfer   =  tfAppObject|tfCanCreate|tfLicensed|tfControl|tfPredeclared;
 
//
// Flags set on any autoclass, but used when class is a member of a coclass.
// Autoclasses with any of these bits set will be members of generated coclass.
// Flags from each class are set on the corresponding interfaces in the coclass
 
//
const owl::uint16 tfDefault      = (1<<12); // IMPLTYPEFLAG_FDEFAULT << 12
const owl::uint16 tfEventSource  = (2<<12); // IMPLTYPEFLAG_FSOURCE << 12
const owl::uint16 tfRestricted   = (4<<12); // IMPLTYPEFLAG_FRESTRICTED << 12
const owl::uint16 tfImplFlagXfer = (tfDefault | tfEventSource | tfRestricted);
 
//
// Flags set on individual autoclasses, transferred to corresponding __OWL_TYPEINFOs
 
//
const owl::uint16 tfHidden        =  16;  // TYPEFLAG_FHIDDEN
const owl::uint16 tfNonextensible = 128;  // TYPEFLAG_FNONEXTENSIBLE
const owl::uint16 tfAutoClassMask =  tfHidden|tfNonextensible;
 
//
// Flags defined by OLE, but not applicable to dispatch interfaces
 
//
const owl::uint16 tfDual          =  64;  // TYPEFLAG_FDUAL
const owl::uint16 tfAutomation    = 256;  // TYPEFLAG_FOLEAUTOMATION
 
//
// Default typeflags value for autoclass not exposed as part of the coclass
 
//
const owl::uint16 tfNormal        =   0;  // automated classes not at app level
 
//
/// \class TAutoSymbol
// ~~~~~ ~~~~~~~~~~~
/// Symbol table element
//
struct _OCFCLASS TAutoSymbol {
  owl::TLocaleString Name;         ///< name of symbol, initially untranslated
  owl::TLocaleString Doc;          ///< documentation string, initially untranslated
  owl::uint32 Attr;                ///< attributes: enum AutoSymFlag, as???? (could be owl::uint16)
  union {
    long  DispId;             ///< reserved dispatch ID, if not 0
    short SymCount;           ///< asClass only: symbol count, 0 = uncounted yet
    unsigned short TypeFlags; ///< class symbol only (terminator)
  };
  TAutoType* Type;                  ///< pointer to class/type/enum descriptor
  union {
    TAutoCommandBuild  Build;       ///< asAnyCommand only: address of command builder
    TAutoIteratorBuild BuildIter;   ///< asIterator only: address of iterator builder
    TAutoSymTypeConvert Convert;    ///< asFactory/asClass: function to perform cast
    TAutoCommandBuildDtr BuildDtr;  ///< terminator only: destructor command builder
    void*      DefaultArg;          ///< asArgument: default value, extends to 8 bytes
  };
  owl::ulong HelpId;                     ///< help context ID, not for asArgument
 
  // Inline data member accessor functions
  //
  void         SetFlag(owl::uint16 mask);
  void         ClearFlag(owl::uint16 mask);
  bool         TestFlag(owl::uint16 mask) const;
  owl::uint16       GetFlags() const;
  bool         IsEnum() const;
  bool         IsByRef() const;
  bool         IsArray() const;
  bool         IsIterator() const;
  bool         IsTerminator() const;
  owl::uint16       GetDataType() const;
  TAutoClass*  GetClass() const;
  TAutoEnum*   GetEnum() const;
 
  // Inline static functions solely to provide type-safety initializing symbols
  //
  static TAutoCommandBuild InitTypeConvert(TAutoSymTypeConvert f);
  static TAutoCommandBuild InitAutoIterator(TAutoIteratorBuild f);
  static TAutoCommandBuild InitAutoDestructor(TAutoCommandBuildDtr f);
};
 
//
/// \struct TObjectDescriptor
// ~~~~~~ ~~~~~~~~~~~~~~~~~
/// Precursor to TServedObject containing object info
/// \note Cannot have a constructor and must limit to 8 bytes for TAutoVal union
//
struct _OCFCLASS TObjectDescBase {   ///< ONLY for use when storing in TAutoVal union
  const void* Object;      ///< pointer to C++ object
  TAutoClass* Class;       ///< class descriptor, contains type info
  const void* MostDerived() {
    return ocf::MostDerived(Object, Class->GetTypeInfo());
  }
};
 
// Double check size of TObjectDescBase
//
#if defined(BI_COMP_BORLANDC) && !defined(__clang__)
  #if sizeof(TObjectDescBase) > 8
    #error Sizeof TObjectDescBase must be 8 bytes - it is a TAutoVal union member
  #endif
#endif
 
//
// struct TObjectDescriptor
// ~~~~~~ ~~~~~~~~~~~~~~~~~
struct _OCFCLASS TObjectDescriptor : public TObjectDescBase {
  enum TDestruct     { ///< behavior when an automation helper is freed
    Quiet = 0,         ///< automation object quietly goes away without notice
    Delete = 1,        ///< automation object deletes the C++ object serviced
    PostQuit = 2       ///< automation object posts a quit message to application
  };
  TDestruct Destruct;
  TObjectDescriptor(const void* obj, TAutoClass& classobj,
                    TDestruct destruct = Quiet)
                    { Object = obj; Class = &classobj; Destruct = destruct; }
  private:
    TObjectDescriptor() {}    // uninitialized struct
  friend class TAutoClass;    // restrict access to uninitialized constructor
  friend class TAutoIterator;
};
 
 
//
/// \class TAutoString
// ~~~~~ ~~~~~~~~~~~
/// Based on reference counted TString with added automation functionality
//
class _OCFCLASS TAutoString : public owl::TString {
  public:
    TAutoString(const char* s = 0) : owl::TString(s) {}
    TAutoString(const wchar_t* s)      : owl::TString(s) {}
    TAutoString(BSTR s, bool loan)     : owl::TString(s) {}
    TAutoString(const owl::tstring& s) : owl::TString(s) {}
    TAutoString(owl::TUString* s)     : owl::TString(s) {}
    explicit TAutoString(TAutoVal& val);
    TAutoString(const TAutoString& src) : owl::TString(src.S) {++*S;}
 
    TAutoString& operator =(const char* s) {S = S->Assign(s); return *this;}
    TAutoString& operator =(const TAutoString& s) {S = S->Assign(*s.S); return *this;}
    TAutoString& operator =(char* s)           {S = S->Assign(s); return *this;}
    TAutoString& operator =(const wchar_t* s)  {S = S->Assign(s); return *this;}
    TAutoString& operator =(wchar_t* s)        {S = S->Assign(s); return *this;}
    TAutoString& operator =(TAutoVal& val);
 
    static TAutoType ClassInfo;              // automation type code
};
 
 
//
/// \class TAutoVal
// ~~~~~ ~~~~~~~~
/// Automation data element (same data as OLE/BASIC VARIANT)
//
/// This class simply duplicates and adds access methods to the system VARIANT
/// Data members or virtual functions cannot be added.
/// We rely on the fact that we can cast a VARIANT safely to/from a TAutoVal.
//
 
#  if defined(BI_COMP_BORLANDC)
#    pragma warn -inl
#  endif
class _OCFCLASS TAutoVal {
  public:
 
    // Default constructors/assignment operators/destructors
    //
    TAutoVal();
    TAutoVal(const TAutoVal& src);
  const TAutoVal& operator =(const TAutoVal& src);
    ~TAutoVal();
 
    // Constructors to create a TAutoVal/VARIANT from a C++ type
    //
    TAutoVal(unsigned char      i){ *this = i; };
    TAutoVal(signed char        i){ *this = i; };
    TAutoVal(char               i){ *this = i; };
    explicit TAutoVal(unsigned char* p){ *this = p; };
    explicit TAutoVal(signed char*   p){ *this = p; };
    explicit TAutoVal(char*          p){ *this = p; };
    TAutoVal(const char*        p){ *this = p; };
    TAutoVal(int                i){ *this = i; };
    TAutoVal(int*               p){ *this = p; };
    TAutoVal(unsigned int       i){ *this = i; };
    TAutoVal(unsigned int*      p){ *this = p; };
    TAutoVal(unsigned short     i){ *this = i; };
    TAutoVal(unsigned short*    p){ *this = p; };
    TAutoVal(long               i){ *this = i; };
    TAutoVal(long*              p){ *this = p; };
    TAutoVal(unsigned long      i){ *this = i; };
    TAutoVal(unsigned long*     p){ *this = p; };
    TAutoVal(short              i){ *this = i; };
    TAutoVal(short*             p){ *this = p; };
    TAutoVal(float              i){ *this = i; };
    TAutoVal(float*             p){ *this = p; };
    TAutoVal(double             i){ *this = i; };
    TAutoVal(double*            p){ *this = p; };
    TAutoVal(void*              p){ *this = p; };
    TAutoVal(owl::TBool         i){ *this = i; };
    TAutoVal(owl::TBool*        p){ *this = p; };
    TAutoVal(const owl::tstring& s){ *this = s; };
#pragma warn -inl
    TAutoVal(TAutoString        s){ *this = s; };
#pragma warn .inl
    TAutoVal(owl::TString       s){ *this = s; };
    TAutoVal(TAutoCurrency      i){ *this = i; };
    TAutoVal(TAutoCurrency*     p){ *this = p; };
    TAutoVal(TAutoDate          i){ *this = i; };
    TAutoVal(TAutoDate*         i){ *this = i; };
    TAutoVal(IDispatch*       ifc){ *this = ifc; };
    TAutoVal(IDispatch**      ifc){ *this = ifc; };
    TAutoVal(IUnknown*        ifc){ *this = ifc; };
    TAutoVal(IUnknown**       ifc){ *this = ifc; };
    TAutoVal(IPictureDisp*    ifc){ *this = ifc; };
    TAutoVal(IFontDisp*       ifc){ *this = ifc; };
    TAutoVal(VARIANT&           v){ *this = v; };
    TAutoVal(const TNoArg&      n){ *this = n; };
 
    // The following constructors are added to complement the functionality of
    // TAutoVal
    TAutoVal(BSTR*              p){ *this = p; };
    TAutoVal(TBSTR*             p){ *this = p; };
    TAutoVal(TAutoVal*          p){ *this = p; };
    TAutoVal(LARGE_INTEGER      v){ *this = v; };
    TAutoVal(ULARGE_INTEGER     v){ *this = v; };
    TAutoVal(SAFEARRAY*         v) { *this = v; }
#if defined(_WIN64)
    TAutoVal(ULONG_PTR          v){ *this = v; };
#endif	
 
    // Operators to extract a C++ type from a TAutoVal/VARIANT
    //
    operator unsigned char();
    operator signed char();
    operator char();
    operator unsigned char*();
    operator signed char*();
    operator char*();
    operator int();
    operator int*();
    operator unsigned int();
    operator short();
    operator short*();
    operator unsigned short();
    operator unsigned short*();
    operator long();
    operator long*();
    operator unsigned long();
    operator unsigned long*();
    operator float();
    operator float*();
    operator double();
    operator double*();
    operator void*();
    operator owl::TBool();
    operator owl::TBool*();
    operator TAutoCurrency();
    operator TAutoCurrency*();
    operator TAutoDate();
    operator TAutoDate*();
    operator owl::tstring();
    operator owl::TUString*();
    operator owl::TString();
    operator TAutoString();
    operator IUnknown*();
    operator IDispatch*();
    operator IPictureDisp*();
    operator IFontDisp*();
    operator IPictureDisp&();
    operator IFontDisp&();
    operator IUnknown&();
    operator IDispatch&();
    // The following operators are added to complement the functionality of
    // TAutoVal
    operator BSTR();
    operator BSTR*();
    operator TBSTR*();
    operator SAFEARRAY*();
    operator IUnknown**();
    operator IDispatch**();
    operator TAutoVal*();
    operator LARGE_INTEGER();
    operator ULARGE_INTEGER();
#if defined(_WIN64)
    operator ULONG_PTR();
#endif
 
    // Assignment operators to initialize a TAutoVal/VARIANT with the contents
    // of a instance of a C++ type.
    //
    void operator =(unsigned char      i);
    void operator =(signed char        i);
    void operator =(char               i);
    void operator =(unsigned char*     p);
    void operator =(signed char*       p);
    void operator =(char*              p);
    void operator =(const char*        p);
    void operator =(int                i);
    void operator =(int*               p);
    void operator =(unsigned int       i);
    void operator =(unsigned int*      p);
    void operator =(unsigned short     i);
    void operator =(unsigned short*    p);
    void operator =(long               i);
    void operator =(long*              p);
    void operator =(unsigned long      i);
    void operator =(unsigned long*     p);
    void operator =(short              i);
    void operator =(short*             p);
    void operator =(float              i);
    void operator =(float*             p);
    void operator =(double             i);
    void operator =(double*            p);
    void operator =(void*              p);
    void operator =(owl::TBool         i);
    void operator =(owl::TBool*        p);
    void operator =(const owl::tstring& s);
    void operator =(TAutoString        s);
    void operator =(owl::TString       s);
    void operator =(TAutoCurrency      i);
    void operator =(TAutoCurrency*     p);
    void operator =(TAutoDate          i);
    void operator =(TAutoDate*         i);
    void operator =(IUnknown*        ifc);
    void operator =(IDispatch*       ifc);
    void operator =(IPictureDisp*    ifc);
    void operator =(IFontDisp*       ifc);
    void operator =(VARIANT&           v);
    void operator =(TObjectDescriptor od);
    void operator =(TAutoVoid           );
    void operator =(const TNoArg&      n);
    // The following operators are added to complement the functionality of
    // TAutoVal
    void operator =(BSTR*              p);
    void operator =(TBSTR*             p);
    void operator =(IUnknown**         p);
    void operator =(IDispatch**        p);
    void operator =(TAutoVal*          p);
    void operator =(LARGE_INTEGER      v);
    void operator =(ULARGE_INTEGER     v);
    void operator =(SAFEARRAY*         p);
#if defined(_WIN64)
    void operator =(ULONG_PTR          v);
#endif	
 
    // Query/Manipulate VARIANT object
    //
    int         GetDataType() const;   // Returns variant type
    void        Init();                // Initializes VARIANT/TAutoVal to 0s
    void        Clear();               // Free refs, set type to atVoid
    void        Restore();             // Revert non-OLE changes to original types
    void        Copy(const TAutoVal& copy);
    HRESULT     ChangeType(VARTYPE type, TAutoVal* src = 0);
    bool        IsRef() const;
 
    // Retrieve VARIANT object catering for VT_VARIANT|VT_BYREF
    //
    TAutoVal*   DereferenceVariant();
 
    void        SetLocale(TLocaleId);   // Associate locale with appropriate pointers
    TLocaleId    GetLocale() const;        // Retrieve locale from appropriate pointers
    owl::TLangId      GetLanguage() const;      // Retrieve language from pointer types
    owl::TString      StrVal();                 // Returns internal string pointer if atString
    bool        GetObjDesc(TObjectDescriptor&); // Return temp obj info or false
    SAFEARRAY*  GetArray();               // Return array pointer, or 0
    void*       SetByRef(AutoDataType);   // Set type, return pointer to data loc
 
  private:
 
    // The following members follow the layout of the actual VARIANT type
    //
    unsigned short vt;
    unsigned short Reserved1;
    unsigned short Reserved2;
    unsigned short Reserved3;
    union {
      unsigned char bVal;             // VT_UI1
      short         iVal;             // VT_I2
      long          lVal;             // VT_I4
      float         fltVal;           // VT_R4
      double        dblVal;           // VT_R8
      VARIANT_BOOL  boolVal;          // VT_BOOL
      SCODE         scode;            // VT_ERROR
      TAutoCurrency cyVal;            // VT_CY
      DATE          date;             // VT_DATE
      BSTR          bstrVal;          // VT_BSTR
      IUnknown*     punkVal;          // VT_UNKNOWN
      IDispatch*    pdispVal;         // VT_DISPATCH
      SAFEARRAY* parray;              // VT_ARRAY
      unsigned char* pbVal;           // VT_BYREF|VT_UI1
      short        * piVal;           // VT_BYREF|VT_I2
      long         * plVal;           // VT_BYREF|VT_I4
      float        * pfltVal;         // VT_BYREF|VT_R4
      double       * pdblVal;         // VT_BYREF|VT_R8
      VARIANT_BOOL * pbool;           // VT_BYREF|VT_BOOL
      SCODE        * pscode;          // VT_BYREF|VT_ERROR
      TAutoCurrency* pcyVal;          // VT_BYREF|VT_CY
      DATE         * pdate;           // VT_BYREF|VT_DATE
      BSTR         * pbstrVal;        // VT_BYREF|VT_BSTR
      IUnknown*    * ppunkVal;        // VT_BYREF|VT_UNKNOWN
      IDispatch*   * ppdispVal;       // VT_BYREF|VT_DISPATCH
      SAFEARRAY*   * pparray;         // VT_BYREF|VT_ARRAY
      VARIANT      * pvarVal;         // VT_BYREF|VT_VARIANT
      void         * byref;           // Generic ByRef
 
      // The following entries are enhancements to the VARIANT type allowing
      // OCF to 'carry' additional information. NOTE: These members make it
      // impractical to have TAutoVal derive from the VARIANT type.
      //
      struct {                       ///< Added locale info for BSTR/IDispatch
        void* Val;
        LCID  Locale;                ///< Unused 4 bytes for pointer types
      } p;
 
      struct {                      ///< Added info when loaned BSTR ownership
        BSTR      Val;
        owl::TUString* Holder;     ///< String holder sharing current BSTR
      } s;
 
      TObjectDescBase ObjDesc;       ///< Temporary space for returning object
 
      LARGE_INTEGER  hVal;           ///< Also support LARGE_INTEGER
      ULARGE_INTEGER uhVal;          ///< Also support ULARGE_INTEGER
#if defined(_WIN64)
      ULONG_PTR uptrVal;          ///< Also support ULONG_PTR
#endif	  
    };
 
    void ConvRef(int type);
};
#  if defined(BI_COMP_BORLANDC)
#    pragma warn .inl
#  endif
 
 
// Check that TAutoVal is 'size-wise' VARIANT compatible
//
#if defined(BI_COMP_BORLANDC) && !defined(__clang__)
# if sizeof(TAutoVal) != sizeof(VARIANT)
#    Error Sizeof(TAutoVal) must match Sizeof(VARIANT)
# endif
#endif
 
 
//
/// \class TAutoStack
// ~~~~~ ~~~~~~~~~~
/// Automation argument stack abstraction
//
class _OCFCLASS TAutoStack {
  public:
    enum {SetValue = -3};     // Special arg index for property set value
    TAutoStack(DISPID dispid, VARIANT* stack, TLocaleId locale,
               int argcount,
               int namedcount, long* map, TServedObject* owner);
   ~TAutoStack();
    TAutoVal& operator[](int index);
 
    TAutoSymbol*    Symbol;      ///< Symbol of method/prop, args follow
    int             CurrentArg;  ///< Index of last arg requested by operator[]
    int             ArgCount;
    int             ArgSymbolCount;
    DISPID          DispId;
    owl::TLangId    LangId;
    TServedObject*  Owner;
    long            ErrorCode;   ///< Set if TXAuto::xErrorStatus returned
    LPCTSTR         ErrorMsg;    ///< Set if TXAuto::xErrorStatus returned
 
  protected:
    int              NamedCount;
    long*            NamedIds;
    TAutoVal         Default;
    TAutoVal*        Stack;
};
 
struct _OCFCLASS TAutoTransfer;              // Persistence transfer parameter structure
 
//
/// \class TAutoCommand
// ~~~~~ ~~~~~~~~~~~~
/// Automation abstract base class for command objects
//
class _OCFCLASS TAutoCommand {
  public:
    TAutoCommand(int attr);          // Construtor called from derived classes
 
    virtual ~TAutoCommand() {}
    virtual TAutoCommand* Undo();             // generate command for undo stack
    virtual int           Record(TAutoStack& q); // record command and arguments
    virtual TAutoCommand& Invoke();           // invoke all command processing
    virtual bool          Validate();         // validate parameters
    virtual void          Execute();          // perform action on C++ object
    virtual long          Report();           // check result of execution
    virtual void          Return(TAutoVal& v);// convert return value to variant
    virtual void          Transfer(TAutoTransfer& x); // stream data in or out
            void          Fail(TXAuto::TError);// throw designated exception
 
    // Non-virtual hook functions
    //
    typedef LPCTSTR (*TErrorMsgHook)(long errCode);
    static TErrorMsgHook SetErrorMsgHook(TErrorMsgHook callback);
 
    typedef bool (*TCommandHook)(TAutoCommand& cmdObj);
    static TCommandHook SetCommandHook(TCommandHook callback);
 
    // inline data member accessor functions
    //
    static LPCTSTR LookupError(long errCode);
    void SetFlag(int mask);
    void ClearFlag(int mask);
    bool TestFlag(int mask);
    bool IsPropSet();
    TAutoSymbol* GetSymbol();
    void SetSymbol(TAutoSymbol* sym);
 
  protected:
    TAutoSymbol* Symbol;      // Symbol entry generating this command
    int          Attr;        // Attribute and state flags, asXXXXXX
};
extern _OCFDATA(TAutoCommand::TErrorMsgHook) TAutoCommand_ErrorLookup;
extern _OCFDATA(TAutoCommand::TCommandHook)  TAutoCommand_InvokeHook;
 
//
// Build function for application Quit command implementation
//
_OCFFUNC(TAutoCommand*) AutoQuitBuild(ObjectPtr obj, int attr, TAutoStack& args);
 
//----------------------------------------------------------------------------
// TAutoEnum - automation enumeration descriptor
//
 
template <class T> struct TAutoEnumVal {
  owl::TLocaleString Name;         ///< Name of symbol, enumeration text
  T             Val;          ///< Enumeration internal value
};
 
class TAutoEnum : public TAutoType {
  public:
    virtual bool Convert(TAutoVal& txtVal, TAutoVal& numVal) = 0;
    virtual bool Convert(TAutoVal& numVal, owl::TLangId langId) = 0;
 
  protected:
    TAutoEnum(int count, int type);
    int Count;              ///< length of this symbol table
};
 
template <class T> class TAutoEnumT : public TAutoEnum {
  public:
    TAutoEnumT(TAutoEnumVal<T>* table, int symcount, int type);
    bool Convert(TAutoVal& txtVal, TAutoVal& numVal);
    bool Convert(TAutoVal& numVal, owl::TLangId langId);
 
  protected:
    TAutoEnumVal<T>* Table; ///< pointer to array of symbol entries
};
 
//____________________________________________________________________________
//
/// \class TAutoCreator
/// Object responsible for creating automation COM object
class TAutoCreator {
  public:
    TAutoCreator() {}
    virtual TUnknown*  CreateObject(TObjectDescriptor objDesc,
                                    IUnknown* outer = 0) = 0;
    virtual IDispatch* CreateDispatch(TObjectDescriptor objDesc,
                                      IUnknown* outer = 0) = 0;
    virtual void       Attach(TServedObject& obj) {}
    virtual void       Detach(TServedObject& obj) {}
};
 
class _OCFCLASS TServedObjectCreator : public TAutoCreator {
  public:
    TServedObjectCreator(TAppDescriptor& appDesc);
    TUnknown*  CreateObject(TObjectDescriptor objDesc, IUnknown* outer = 0);
    IDispatch* CreateDispatch(TObjectDescriptor objDesc, IUnknown* outer = 0);
    void       Attach(TServedObject& obj);
    void       Detach(TServedObject& obj);
 
    TAppDescriptor& GetAppDesc()    { return AppDesc;    }
    TServedObject*  GetAppObject()  { return AppObject;  }
 
  protected:
    TAppDescriptor& AppDesc;
    TServedObject*  AppObject;
 
  private:
    int ObjCount;
 
  friend class TServedObject;
};
 
class _ICLASS TDispatch;
 
class _OCFCLASS TDispatchCreator : public TAutoCreator {
  public:
    TDispatchCreator() {}
    TUnknown*  CreateObject(TObjectDescriptor objDesc, IUnknown* outer = 0);
    IDispatch* CreateDispatch(TObjectDescriptor objDesc, IUnknown* outer = 0);
};
 
//----------------------------------------------------------------------------
/// \class TServedObject
/// OLE object exposed for automated access of internal object
//
 
DECLARE_COMBASES2(TServedCOM, IDispatch, ITypeInfo)
 
class _ICLASS TServedObject : public TServedCOM {
  public:
    TServedObject(TObjectDescriptor& obj, TServedObjectCreator& creator,
                                          IUnknown* outer=0);
   ~TServedObject();
    TServedObject* GetAppObject()        {return Creator.AppObject;}
    TServedObjectCreator& GetCreator()  {return Creator;}
 
    operator IDispatch*();
 
    void*                  Object;        ///< pointer to C++ object instance, 0 if deleted
    const void*            RootObject;    ///< pointer to object of most derived class
    TAutoClass*            Class;        ///< class of which object is an instance
    TServedObjectCreator& Creator;
    owl::TLangId               ReqLang;      ///< language requested by caller
    TObjectDescriptor::TDestruct
                          Destruct;      ///< what to do with C++ object
 
    // Object reference & lifetime managment
    // For internal OCF use only
    //
    owl::ulong   _IFUNC AddRef() {return GetOuter()->AddRef();}
    owl::ulong   _IFUNC Release() {return GetOuter()->Release();}
    HRESULT _IFUNC QueryInterface(const GUID & iid, void** iface)
                     {return GetOuter()->QueryInterface(iid, iface);}
 
  protected:
    // TUnknown overrides
    //
    HRESULT      QueryObject(const IID & iid, void** iface);
 
  private:
    IID                   iidEvent;
    TServedObject*        Next;
    TServedObject**        Prev;
    // need to access local LANGID for type info, either as member or as global
 
    // IDispatch implementation
    HRESULT _IFUNC GetTypeInfoCount(unsigned int* pctinfo);
    HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
                               ITypeInfo** pptinfo);
    HRESULT _IFUNC GetIDsOfNames(const IID & riid, OLECHAR** rgszNames,
                                 owl::uint cNames, LCID lcid,
                                 DISPID* rgdispid);
    HRESULT _IFUNC Invoke(DISPID dispidMember, const IID & riid, LCID lcid,
                                 unsigned short wFlags,
                                 DISPPARAMS* pdispparams,
                                 VARIANT* pvarResult,
                                 EXCEPINFO* pexcepinfo,
                                 unsigned int* puArgErr);
 
    // ITypeInfo implementation
    //
    HRESULT _IFUNC GetTypeAttr(TYPEATTR** pptypeattr);
    HRESULT _IFUNC GetTypeComp(ITypeComp** pptcomp);
    HRESULT _IFUNC GetFuncDesc(unsigned int index, FUNCDESC** ppfuncdesc);
    HRESULT _IFUNC GetVarDesc(unsigned int index, VARDESC** ppvardesc);
    HRESULT _IFUNC GetNames(MEMBERID memid, BSTR* rgbstrNames,
                            unsigned int cMaxNames,
                            unsigned int* pcNames);
    HRESULT _IFUNC GetRefTypeOfImplType(unsigned int index, HREFTYPE* phreftype);
    HRESULT _IFUNC GetImplTypeFlags(unsigned int index, int* pimpltypeflags);
    HRESULT _IFUNC GetIDsOfNames(OLECHAR** rgszNames,
                                 unsigned int cNames,
                                 MEMBERID* rgmemid);
    HRESULT _IFUNC Invoke(void* pvInstance, MEMBERID memid,
                          unsigned short wFlags,
                          DISPPARAMS  *pdispparams,
                          VARIANT  *pvarResult,
                          EXCEPINFO  *pexcepinfo,
                          unsigned int  *puArgErr);
    HRESULT _IFUNC GetDocumentation(MEMBERID memid,
                                    BSTR* pbstrName,
                                    BSTR* pbstrDocString,
                                    owl::ulong* pdwHelpContext,
                                    BSTR* pbstrHelpFile);
    HRESULT _IFUNC GetDllEntry(MEMBERID memid, INVOKEKIND invkind,
                               BSTR* pbstrDllName,
                               BSTR* pbstrName,
                               unsigned short* pwOrdinal);
    HRESULT _IFUNC GetRefTypeInfo(HREFTYPE hreftype,
                                  ITypeInfo** pptinfo);
    HRESULT _IFUNC AddressOfMember(MEMBERID memid, INVOKEKIND invkind,
                                   void** ppv);
    HRESULT _IFUNC CreateInstance(IUnknown* punkOuter, const IID & riid,
                                  void** ppvObj);
    HRESULT _IFUNC GetMops(MEMBERID memid, BSTR* pbstrMops);
    HRESULT _IFUNC GetContainingTypeLib(ITypeLib** pptlib,
                                        owl::uint* pindex);
    void _IFUNC ReleaseTypeAttr(TYPEATTR* ptypeattr);
    void _IFUNC ReleaseFuncDesc(FUNCDESC* pfuncdesc);
    void _IFUNC ReleaseVarDesc(VARDESC* pvardesc);
    HRESULT _IFUNC GetFuncDocFromIndex(unsigned index,
                                       BSTR* retName, BSTR* retDoc,
                                       owl::ulong* retHelpContext,
                                       BSTR* retHelpFile);
    // GetVarDocFromIndex and GetDocFromSym are used to by WriteTypeLib to make
    // type libraries
    HRESULT _IFUNC GetVarDocFromIndex(unsigned index,
                                      BSTR* retName, BSTR* retDoc,
                                      owl::ulong* retHelpContext,
                                      BSTR* retHelpFile);
    HRESULT _IFUNC GetDocFromSym(TAutoSymbol* sym,
                                 BSTR* retName, BSTR* retDoc,
                                 owl::ulong* retHelpContext,
                                 BSTR* retHelpFile);
    friend class _ICLASS TAppDescriptor;   // access to Next,Prev
    friend class _ICLASS TOcxView;         // access to QueryObject
    friend class _ICLASS TOcControl;       // access to QueryObject
};
 
//----------------------------------------------------------------------------
/// \class TDispatch
/// lightweight IDispatch implementation for automation controllers
//
 
DECLARE_COMBASES1(TDispatchCOM, IDispatch)
 
class _ICLASS TDispatch : public TDispatchCOM {
  public:
    TDispatch(const TObjectDescriptor& obj, IUnknown* outer = 0);
    void InvalidateObject() {Object = 0;}
    operator IDispatch*();
 
    void*        Object;      ///< pointer to C++ object instance, 0 if deleted
    TAutoClass*  Class;       ///< class of which object is an instance
  private:
    // IDispatch implementation
    HRESULT _IFUNC GetTypeInfoCount(unsigned int* pctinfo);
    HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
                               ITypeInfo** pptinfo);
    HRESULT _IFUNC GetIDsOfNames(const IID & riid, OLECHAR** rgszNames,
                                 unsigned int cNames, LCID lcid,
                                 DISPID* rgdispid);
    HRESULT _IFUNC Invoke(DISPID dispidMember, const IID & riid, LCID lcid,
                                 unsigned short wFlags,
                                 DISPPARAMS* pdispparams,
                                 VARIANT* pvarResult,
                                 EXCEPINFO* pexcepinfo,
                                 unsigned int* puArgErr);
};
 
//----------------------------------------------------------------------------
/// \class TAutoObject
/// holders for C++ object pointers for automation conversions
//
 
template<class T>
class TAutoObject {
  public:
    void operator=(IDispatch& dp);
    void operator=(T* p) {P=p;}
    void operator=(T& r) {P=&r;}
    T& operator*() {return *P;}
    operator TObjectDescriptor() {return TObjectDescriptor(P, T::ClassInfo);}
    TAutoObject() : P(0) {}
    TAutoObject(T* p) {P=p;}
    TAutoObject(T& r) {P=&r;}
    TAutoObject(IDispatch& dr);
    operator T*() {return P;}
    operator T&() {return *P;}
  protected:
    T* P;
    T F();// only purpose to remove const for typeid incase T is a const class
};
 
template<class T>
TAutoObject<T>::TAutoObject(IDispatch& ifc)
{
  TServedObject* obj;
  if (ifc.QueryInterface(IID_TServedObject, (void**)&obj) != 0)
    throw TXAuto(TXAuto::xForeignIDispatch);
  P = (T*)DynamicCast(obj->Object, obj->Class->GetTypeInfo(), typeid(T));
  if (!P)
    throw TXAuto(TXAuto::xTypeMismatch);
}
 
template<class T> void
TAutoObject<T>::operator=(IDispatch& ifc)
{
  TServedObject* obj;
  if (ifc.QueryInterface(IID_TServedObject, (void**)&obj) != 0)
    throw TXAuto(TXAuto::xForeignIDispatch);
  P = (T*)DynamicCast(obj->Object, obj->Class->GetTypeInfo(), typeid(T));
  if (!P)
    throw TXAuto(TXAuto::xTypeMismatch);
}
 
template<class T>      // for returning objects only, no IDispatch constructor
class TAutoObjectDelete : public TAutoObject<T>{
  public:
    void operator=(T* p) {this->P=p;}
    void operator=(T& r) {this->P=&r;}
    TAutoObjectDelete()     : TAutoObject<T>() {}
    TAutoObjectDelete(T* p) : TAutoObject<T>(p) {}
    TAutoObjectDelete(T& r) : TAutoObject<T>(r) {}
    operator TObjectDescriptor()
        {return TObjectDescriptor(this->P,T::ClassInfo, TObjectDescriptor::Delete);}
};
 
template<class T>      // for returning objects by value
class TAutoObjectByVal : public TAutoObjectDelete<T> {
  public:
    void operator=(T o) {this->P=new T(o);}
    TAutoObjectByVal() : TAutoObjectDelete<T>() {}
    TAutoObjectByVal(T o) : TAutoObjectDelete<T>(new T(o)) {}
};
 
//----------------------------------------------------------------------------
/// \class TAutoIterator
/// automation collection iterator
//
 
 
class _OCFCLASS TAutoIterator : public IEnumVARIANT {
  public:
    // IEnumVARIANT implementation
    HRESULT       _IFUNC QueryInterface(const GUID & iid, void** pif);
    unsigned long _IFUNC AddRef();
    unsigned long _IFUNC Release();
    HRESULT _IFUNC Next(unsigned long count, VARIANT* retvals,
                        unsigned long* retcount);
    HRESULT _IFUNC Skip(unsigned long count);
    HRESULT _IFUNC Reset();
    HRESULT _IFUNC Clone(IEnumVARIANT** retiter);
 
    // specific implementation required by derived classes
    virtual void           Init()=0;   // reset to first item
    virtual bool           Test()=0;   // test if item exists
    virtual void           Step()=0;   // advance to next item
    virtual void           Return(TAutoVal& v)=0;// convert item to variant
    virtual TAutoIterator* Copy()=0;   // return copy of iterator
 
    // inline data member accessor functions
    TAutoSymbol* GetSymbol();
    void SetSymbol(TAutoSymbol* sym);
    operator IUnknown*();     // essentially a quick QueryInterface
 
    virtual ~TAutoIterator();
    TAutoClass* Class;
  protected:
    TAutoSymbol*  Symbol;      // symbol entry generating this command
    TAutoCreator& Creator;    // object to create returned automation objects
    IUnknown*      Owner;          // Release() must be called on destruction
    unsigned      RefCnt;
    owl::TLangId        Lang;
    TAutoIterator(TAutoCreator& creator, IUnknown* owner, owl::TLangId lang); // called from derived
    TAutoIterator(TAutoIterator& copy);  // copy constructor for base class
  };
 
//____________________________________________________________________________
//
/// \class TAutoProxy
/// client C access proxy, base class
//____________________________________________________________________________
 
enum AutoCallFlag {
  acMethod         = 0x0001,  ///< method call, same as OLE2
  acPropGet        = 0x0002,  ///< returns property value, same as OLE2
  acPropSet        = 0x0004,  ///< set property value, same as OLE2
  acVoidRet        = 0x8000,  ///< pass NULL for return variant, not OLE2 flag
};
 
// TAutoProxyArgs is the base class of TAutoArgs.
//
class _OCFCLASS TAutoProxyArgs {
  protected:
    TAutoProxyArgs(int cnt) : Count(cnt) {}
 
    // Provides the address of the Args member which will be added in
    // the derived TAutoArgs template classes.
    //
    virtual TAutoVal* GetArgs() = 0;
 
  public:
    operator  TAutoVal&()    {return *GetArgs();}
    operator  VARIANT* ()    {return  (VARIANT* )GetArgs();}
    operator  unsigned int() {return Count;}
    TAutoVal& operator[](int index);
 
  private:
    int       Count;
};
 
/// \class TAutoArgs
// ~~~~~~~~~~~~~~~
/// The first TAutoVal item of TAutoArgs holds the return value. Items at
/// indices 1 through N+1 represent the first, second, third ... paramters.
/// Of course, these parameters are optional.
//
template <int N>
struct TAutoArgs : public TAutoProxyArgs {
  TAutoVal Args[N+1];
  TAutoArgs() : TAutoProxyArgs(N) {}
 
  protected:
 
    // Provides the address of Args.
    // Implemented as a (pure) virtual function to allow access to the Args
    // member also for TAutoArgs objects which are passed as TAutoProxyArgs.
    //
    virtual TAutoVal* GetArgs() {return Args;}
};
 
 
// class TAutoProxy
// ~~~~~ ~~~~~~~~~~
//
class _OCFCLASS TAutoProxy {
  public:
   ~TAutoProxy();
 
    // Attach to [Detatch from] a dispatch interface
    //
    void        Bind(IUnknown* obj);
    void        Bind(IUnknown& obj);
    void        Bind(const GUID& guid);
    void        Bind(LPCTSTR progid);
    void        Bind(TAutoVal& val);
    void        Bind(IDispatch* obj);
    void        Bind(IDispatch& obj);
    void        Unbind(bool release = true);
 
    // Check/Querry binding
    //
    void        MustBeBound();
    bool        IsBound()  {return owl::ToBool(That != 0);}
 
    // Check it there's a running copy of an object which supports IDispatch
    //
    static IDispatch*  GetObject(LPCTSTR progid);
 
    // Locale support
    //
    void        SetLang(owl::TLangId lang) {Lang = lang;}
 
    // Access to dispatch interface
    //
    operator    IDispatch*();
    operator    IDispatch&();
 
    // Retrieve dispId
    //
    long        Lookup(const long id) {return id;}
    long        Lookup(LPCTSTR name);
    void        Lookup(LPCTSTR names, long* ids, unsigned count);
 
  protected:
    TAutoProxy(owl::TLangId lang) : That(0), Lang(lang) {}
 
    // Invoke (IDispatch::Invoke)
    //
    TAutoVal&   Invoke(owl::uint16 attr, TAutoProxyArgs& args, long* ids, unsigned named=0);
 
    IDispatch*    That;
    owl::TLangId        Lang;
};
 
struct _OCFCLASS TAutoDispId {
  TAutoDispId(TAutoProxy* prx, LPCTSTR name) : Id(prx->Lookup(name)) {}
  TAutoDispId(TAutoProxy*, long id) : Id(id) {}
  operator long*()    {return &Id;}
  operator unsigned() {return   0;}
 
  long     Id;
};
 
template <int N> struct TAutoDispIds {
  TAutoDispIds(TAutoProxy* prx, LPCTSTR names) {prx->Lookup(names, Ids);}
  long Ids[N+1];
  operator long*()    {return Ids;}
  operator unsigned() {return N;}
};
 
class _OCFCLASS TAutoEnumeratorBase {
  public:
    void Bind(TAutoVal& val);
    void Unbind()   { if (Iterator) Iterator->Release(); Iterator=0; Clear();}
    bool Step();
    void Clear()      { Current.Clear(); }
    bool IsValid()    { return Current.GetDataType() != atVoid; }
    void Object(TAutoProxy& prx) { prx.Bind(Current); }
    void operator =(const TAutoEnumeratorBase& copy);
   ~TAutoEnumeratorBase() { Unbind(); }
  protected:
    TAutoEnumeratorBase() : Iterator(0) {Current = TAutoVoid();}
    TAutoEnumeratorBase(const TAutoEnumeratorBase& copy);
    IEnumVARIANT*     Iterator;
    TAutoVal          Current;
};
 
template <class T>
class TAutoEnumerator : public TAutoEnumeratorBase {
  public:
    TAutoEnumerator() : TAutoEnumeratorBase() {}
    TAutoEnumerator(const TAutoEnumerator<T>& cpy) : TAutoEnumeratorBase(cpy) {}
    void Value(T& v);
    operator T();
};
 
//____________________________________________________________________________
//
// Inline implementations for automation controller
//____________________________________________________________________________
 
//
//
inline TAutoVal& TAutoProxyArgs::operator[](int index)
{
  // NOTE: It's OK to use Count as subscript since there's always one
  //       addition TAutoVal/VARIANT for the return value.
  //
  PRECONDITION(index <= Count);
 
  // NOTE: The logic below takes care of the difference in the C and
  //       Automation calling conventions.
  //
  return *(GetArgs()+(index ? Count+1-index : 0));
}
 
//
//
inline TAutoProxy::operator IDispatch&()
{
  // Following conditional avoid function call overhead - specially since
  // method is inline
  //
  if (!That)
    MustBeBound();
  return *That;
}
 
//
//
inline TAutoProxy::operator IDispatch*()
{
  if (That)
    That->AddRef();
  return That;
}
 
//
//
inline void TAutoProxy::Unbind(bool release)
{
  if (release && That)
    That->Release();
  That = 0;
}
 
//
//
inline TAutoProxy::~TAutoProxy()
{
  Unbind();
}
 
template<>
inline void TAutoEnumerator<short>::Value(short& v) { v = Current; }
 
template<>
inline void TAutoEnumerator<long>::Value(long& v)   { v = Current; }
 
template<>
inline void TAutoEnumerator<bool>::Value(bool& v)   { v = Current; }
 
template<>
inline void TAutoEnumerator<TAutoString>::Value(TAutoString& v)
                                                    { v = Current; }
template<>
inline TAutoEnumerator<short>::operator short() { return (short)Current; }
 
template<>
inline TAutoEnumerator<long>::operator long()   { return (long)Current; }
 
template<>
inline TAutoEnumerator<bool>::operator bool()   { return (bool)Current; }
 
template<>
inline TAutoEnumerator<TAutoString>::operator TAutoString()
                                                { return (TAutoString)Current; }
//____________________________________________________________________________
//
// Inline implementations for automation server - part 1
//____________________________________________________________________________
 
// TAutoClass inlines
 
inline TAutoSymbol* TAutoClass::GetTable() const {
  return Table;
}
inline TAutoSymbol* TAutoClass::GetClassSymbol() const {
  return ClassSymbol;
}
inline TAutoCommandBuildDtr TAutoClass::GetDestructor() const {
  return ClassSymbol->BuildDtr;
}
inline const std::type_info&  TAutoClass::GetTypeInfo() const {
  return TypeInfo;
}
inline LPCTSTR TAutoClass::GetName(owl::TLangId id) const {
  return ClassSymbol->Name.Translate(id);
}
inline LPCTSTR TAutoClass::GetDoc (owl::TLangId id) const {
  return ClassSymbol->Doc.Translate(id);
}
inline unsigned long TAutoClass::GetHelpId() const {
  return ClassSymbol->HelpId;
}
inline unsigned short TAutoClass::GetTypeFlags() const {
  return ClassSymbol->TypeFlags & tfAutoClassMask;
}
inline int TAutoClass::GetImplTypeFlags() const {
  return ClassSymbol->TypeFlags>>12;
}
inline unsigned short TAutoClass::GetCoClassFlags() const {
  return ClassSymbol->TypeFlags & tfCoClassXfer;
}
inline TAggregator TAutoClass::GetAggregator() const {
  return Aggregator;
}
inline IUnknown& TAutoClass::Aggregate(ObjectPtr obj, TUnknown& inner) {
  return obj && Aggregator ? Aggregator(obj, inner) : (IUnknown&)inner;
}
 
//____________________________________________________________________________
 
// TAutoSymbol inlines
 
inline void TAutoSymbol::SetFlag(owl::uint16 mask) {
 Attr |= mask;
}
inline void TAutoSymbol::ClearFlag(owl::uint16 mask) {
  Attr &= owl::uint16(~mask);
}
inline bool TAutoSymbol::TestFlag(owl::uint16 mask) const {
  return (Attr&mask)? true : false;
}
inline owl::uint16 TAutoSymbol::GetFlags() const {
  return (owl::uint16)Attr;
}
inline bool TAutoSymbol::IsEnum() const {
  return (Type->GetType() & atEnum)? true : false;
}
inline bool TAutoSymbol::IsByRef() const {
  return (Type->GetType() & atByRef)? true:false;
}
inline bool TAutoSymbol::IsArray() const {
  return (Type->GetType() & atSafeArray)? true : false;
}
inline bool TAutoSymbol::IsIterator() const {
  return ((Attr&asIterator)==asIterator) ? true : false;
}
inline bool TAutoSymbol::IsTerminator() const {
  return ((Attr & asNotTerminator)== 0) ? true : false;
}
inline owl::uint16 TAutoSymbol::GetDataType() const {
  return owl::uint16(Type->GetType() & atTypeMask);
}
inline TAutoClass* TAutoSymbol::GetClass() const {
  return (Type->GetType() & atAutoClass)? (TAutoClass*)Type : 0;
}
inline TAutoEnum* TAutoSymbol::GetEnum() const {
  return (Type->GetType() & atEnum) ? (TAutoEnum*)Type : 0;
}
inline TAutoCommandBuild TAutoSymbol::InitTypeConvert(TAutoSymTypeConvert f)
                                         { return (TAutoCommandBuild)f;}
inline TAutoCommandBuild TAutoSymbol::InitAutoIterator(TAutoIteratorBuild f)
                                         { return (TAutoCommandBuild)f;}
inline TAutoCommandBuild TAutoSymbol::InitAutoDestructor(TAutoCommandBuildDtr f)
                                         { return (TAutoCommandBuild)f;}
//____________________________________________________________________________
// TAutoString
inline TAutoString::TAutoString(TAutoVal& val)
:
  owl::TString(val.operator owl::TString())
//#if defined(BI_COMP_MSC)
//  TString((TString)val.operator TString())
//#else
//  TString((TString)val)
//#endif
{
}
inline TAutoString& TAutoString::operator =(TAutoVal& val){
  --*S; S = val; return *this;
}
 
//____________________________________________________________________________
// TAutoVal inlines
 
//
//
inline TAutoVal::TAutoVal()
{
  Init();
}
 
//
//
inline TAutoVal::~TAutoVal()
{
  Clear();
}
 
//
//
inline TAutoVal::TAutoVal(const TAutoVal& src)
{
  Init();
  ::VariantCopy((VARIANT*)this, (VARIANT*)&src);
}
 
//
//
inline const TAutoVal& TAutoVal::operator=(const TAutoVal& src)
{
  // NOTE: 'VariantCopy' takes care of 'freeing' the destination
  //
  ::VariantCopy((VARIANT*)this, (VARIANT*)&src);
  return *this;
}
 
inline TAutoVal::operator unsigned long(){return (unsigned long)operator long();}
//#if (MAXINT==MAXSHORT)
//inline TAutoVal::operator int()          {return operator short();}
//inline TAutoVal::operator unsigned int() {return operator unsigned short();}
//inline TAutoVal::operator int*()         {return (int*)operator short*();}
//#else
inline TAutoVal::operator int()          {return operator long(); }
inline TAutoVal::operator unsigned int() {return (unsigned long)(long)*this;}
inline TAutoVal::operator int*()         {return (int*)operator long*();}
//#endif
 
inline TAutoVal::operator signed char()  {return operator unsigned char();}
inline TAutoVal::operator char()         {return operator unsigned char();}
inline TAutoVal::operator char*()        {return (char*)operator unsigned char*();}
inline TAutoVal::operator signed char*() {return (signed char*)operator unsigned char*();}
 
inline void TAutoVal::operator =(IUnknown*     ifc){vt=atUnknown; punkVal=ifc;}
inline void TAutoVal::operator =(IDispatch*    ifc){vt=atObject; pdispVal=ifc;}
 
inline void TAutoVal::operator =(IPictureDisp* ifc){vt=atObject; pdispVal=ifc;}
inline void TAutoVal::operator =(IFontDisp*    ifc){vt=atObject; pdispVal=ifc;}
 
inline void TAutoVal::operator =(VARIANT&        v){vt=atVariant; pvarVal= &v;}
inline void TAutoVal::operator =(unsigned char   v){vt=atByte;   bVal  = v;}
inline void TAutoVal::operator =(signed   char   v){vt=atByte;   bVal  = v;}
inline void TAutoVal::operator =(char            v){vt=atByte;   bVal  = v;}
inline void TAutoVal::operator =(short           v){vt=atShort;  iVal  = v;}
inline void TAutoVal::operator =(long            v){vt=atLong;   lVal  = v;}
inline void TAutoVal::operator =(float           v){vt=atFloat;  fltVal= v;}
inline void TAutoVal::operator =(double          v){vt=atDouble; dblVal= v;}
inline void TAutoVal::operator =(owl::TBool           v){vt=atBool;   boolVal = short(v ? -1 : 0);}
inline void TAutoVal::operator =(TAutoDate     v){vt=atDatetime; date = v;}
inline void TAutoVal::operator =(TAutoCurrency v){vt=atCurrency; cyVal = v;}
inline void TAutoVal::operator =(TAutoVoid      ){vt=atVoid;}
inline void TAutoVal::operator =(const TNoArg&  ){vt=atError; scode=DISP_E_PARAMNOTFOUND;}
 
inline void TAutoVal::operator =(unsigned char* p){vt=atByte+atByRef; pbVal=p;}
inline void TAutoVal::operator =(signed char*   p){vt=atByte+atByRef; pbVal=(unsigned char*) p;}
inline void TAutoVal::operator =(char*          p){vt=atByte+atByRef; pbVal=(unsigned char*) p;}
inline void TAutoVal::operator =(short*         p){vt=atShort+atByRef; piVal=p;}
inline void TAutoVal::operator =(long*          p){vt=atLong+atByRef;  plVal=p;}
inline void TAutoVal::operator =(owl::TBool*         p){vt=atBool+atByRef;  pbool=(VARIANT_BOOL*)p;}
inline void TAutoVal::operator =(float*         p){vt=atFloat+atByRef; pfltVal=p;}
inline void TAutoVal::operator =(double*        p){vt=atDouble+atByRef;pdblVal=p;}
inline void TAutoVal::operator =(void*          p){vt=atVoid+atByRef;byref=p;}
inline void TAutoVal::operator =(TAutoDate*     p){vt=atDatetime+atByRef;pdate=(double*)p;}
inline void TAutoVal::operator =(TAutoCurrency* p){vt=atCurrency+atByRef;pcyVal=p;}
 
inline void TAutoVal::operator =(unsigned short  v){vt=atLong; lVal = (long)v;}
inline void TAutoVal::operator =(unsigned short* p){vt=atShort+atByRef; piVal = (short*)p;}
inline void TAutoVal::operator =(unsigned long   v){vt=atLong; lVal = (long)v;}
inline void TAutoVal::operator =(unsigned long*  p){vt=atLong+atByRef; plVal = (long*)p;}
//#if (MAXINT==MAXSHORT)
//inline void TAutoVal::operator =(int           v){vt=atShort; iVal=v;}
//inline void TAutoVal::operator =(int*          p){vt=atShort+atByRef; piVal=(short*)p;}
//inline void TAutoVal::operator =(unsigned int  v){operator =((unsigned short)v);}
//inline void TAutoVal::operator =(unsigned int* p){operator =((unsigned short*)p);}
//#else
inline void TAutoVal::operator =(int           v){vt=atLong; lVal=v;}
inline void TAutoVal::operator =(int*          p){vt=atLong+atByRef; plVal = (long*)p;}
inline void TAutoVal::operator =(unsigned int  v){operator =((unsigned long)v);}
inline void TAutoVal::operator =(unsigned int* p){operator =((unsigned long*)p);}
//#endif
 
// The following operators are added to complement the functionality of TAutoVal
inline void TAutoVal::operator =(BSTR*          p){vt=atString+atByRef; pbstrVal=p;}
inline void TAutoVal::operator =(TBSTR*         p){vt=atString+atByRef; pbstrVal=(BSTR*)p;}
inline void TAutoVal::operator =(IUnknown**     p){vt=atUnknown+atByRef; ppunkVal=p;}
inline void TAutoVal::operator =(IDispatch**    p){vt=atObject+atByRef; ppdispVal=p;}
inline void TAutoVal::operator =(TAutoVal*      p){vt=atVariant+atByRef; pvarVal=(VARIANT*)p;}
inline void TAutoVal::operator =(LARGE_INTEGER  v){vt=VT_I8; hVal=v;}
inline void TAutoVal::operator =(ULARGE_INTEGER v){vt=VT_UI8; uhVal=v;}
inline void TAutoVal::operator =(SAFEARRAY* p) { SafeArrayGetVartype(p, &vt); vt |= VT_ARRAY; parray = p; }
#if defined(_WIN64)
inline void TAutoVal::operator =(ULONG_PTR      v){vt=VT_UI8; uptrVal=v;}
#endif
//
//
 
inline void TAutoVal::operator =(TObjectDescriptor od)
{
  vt = atObjectDesc;
  ObjDesc.Object= od.Object;
  ObjDesc.Class = od.Class;
  if (od.Destruct == TObjectDescriptor::Delete)
    vt |= atByRef;
}
 
//
//
inline int TAutoVal::GetDataType() const {
  return vt;
}
 
//
//
inline void TAutoVal::Init()
{
  memset(this, 0, sizeof(*this));
}
 
//
//
inline void TAutoVal::Clear()
{
  if ((vt & ~atByRef) == atLoanedBSTR) {
    s.Holder->ReleaseBstr((vt & atByRef) ? *pbstrVal : bstrVal);
    vt = owl::uint16(atString | (vt & atByRef));
  }
  ::VariantClear((VARIANT*)this);
}
 
//
//
inline void TAutoVal::Restore()
{
  if ((vt & ~atByRef) == atLoanedBSTR) {
    s.Holder->RevokeBstr((vt & atByRef) ? *pbstrVal : bstrVal);
    vt = owl::uint16(atString | (vt & atByRef));
  } else if (vt == owl::uint16(atBool | atByRef) && *pbool != 0) {
    *pbool = -1;
  }
 
  // Need to check if atObjectDesc? Should never happen as it is temporary
}
 
//
//
inline void TAutoVal::Copy(const TAutoVal& copy)
{
  vt = copy.vt;
  p  = copy.p;
  if (vt == atUnknown || vt == atObject)
    punkVal->AddRef();
  if (vt == atString)
    bstrVal = ::SysAllocString(bstrVal);
}
 
/// Converts TAutoVal/VARIANT to another type
/// \note Converts in-place if source is not specified
//
inline HRESULT TAutoVal::ChangeType(VARTYPE varType, TAutoVal* src) {
   return ::VariantChangeType((VARIANT*)this, src ? (VARIANT*)src : (VARIANT*)this, 0, varType);
}
 
/// Is TAutoVal Object (i.e. VARIANT) passing data by reference
//
inline bool TAutoVal::IsRef() const {
  return (vt & atByRef) ? true : false;
}
 
//
//
inline TAutoVal* TAutoVal::DereferenceVariant() {
  return vt==atVariant+atByRef ? (TAutoVal*)pvarVal : this;
}
 
//
//
inline owl::TString TAutoVal::StrVal() {
  return vt==atString ? bstrVal : 0;
}
 
//
//
inline bool TAutoVal::GetObjDesc(TObjectDescriptor& od)
{
  if ((char)vt != atObjectDesc)
    return false;
  od.Object = ObjDesc.Object;
  od.Class  = ObjDesc.Class;
  od.Destruct = IsRef() ? TObjectDescriptor::Delete : TObjectDescriptor::Quiet;
  return true;
}
 
//
//
inline SAFEARRAY* TAutoVal::GetArray()
{
  if ((vt & atSafeArray) == 0)
  {
    return 0;
  }
 
  return (vt & atByRef ? *pparray : parray);
 
/*
  if (vt == atSafeArray)
    return parray;
  if (vt == (atSafeArray|atByRef))
    return *pparray;
  return 0;
*/
}
 
//
//
inline void* TAutoVal::SetByRef(AutoDataType datatype)
{
  if (vt == atVariant)
    return this;
  vt = owl::uint16(datatype);
  return &byref;
}
 
//____________________________________________________________________________
// TServedObject inlines
 
inline TServedObject::operator IDispatch*()
{
  AddRef();
  return (IDispatch*)this;  // essentially a quick QueryInterface on the obj
}
 
// TDispatch inlines
 
inline TDispatch::operator IDispatch*()
{
  AddRef();
  return (IDispatch*)this;  // essentially a quick QueryInterface on the obj
}
 
//____________________________________________________________________________
 
// TAutoCommand inlines
 
inline TAutoCommand::TAutoCommand(int attr) : Attr(attr), Symbol(0) {}
inline void TAutoCommand::SetFlag(int mask) {Attr |= mask;}
inline void TAutoCommand::ClearFlag(int mask) {Attr&=(~mask);}
inline bool TAutoCommand::TestFlag(int mask) {return owl::ToBool((Attr&mask)==mask);}
inline bool TAutoCommand::IsPropSet() {return TestFlag(asSet);}
inline TAutoSymbol* TAutoCommand::GetSymbol() {return Symbol;}
inline void TAutoCommand::SetSymbol(TAutoSymbol* sym) {Symbol = sym;}
inline LPCTSTR TAutoCommand::LookupError(long errCode)
    {return TAutoCommand_ErrorLookup ? TAutoCommand_ErrorLookup(errCode) : 0;}
//____________________________________________________________________________
 
// TAutoEnum inlines and template function definitions
 
inline TAutoEnum::TAutoEnum(int count, int type)
                        : Count(count) { Type = short(type + atEnum); }
 
template <class T> inline
TAutoEnumT<T>::TAutoEnumT(TAutoEnumVal<T>* table, int symcount, int type)
: TAutoEnum(symcount, type), Table(table) {}
 
// incoming enumeration string localized lookup
//
template <class T> bool
TAutoEnumT<T>::Convert(TAutoVal& txtVal, TAutoVal& numVal)
{
  const owl::TString& stringRef = txtVal.StrVal();  // 0 if not string type
  const _TCHAR* str = stringRef;
  if (str) {
    owl::TLangId langId = txtVal.GetLanguage();
    for (int i = 0; i < Count; i++) {
      if (Table[i].Name.Compare(str, langId) == 0) {
        numVal = Table[i].Val;
        return true;
      }
    }
  }
  return false;
}
 
// outgoing enumeration translation to localized string
//
template <class T> bool
TAutoEnumT<T>::Convert(TAutoVal& numVal, owl::TLangId langId)
{
  T val;
  val = numVal;  // perhaps we should put a try/catch here!!
  for (int i = 0; i < Count; i++) {
    if (Table[i].Val == val) {
      numVal = Table[i].Name.Translate(langId);
      numVal.SetLocale(langId);
      return true;
    }
  }
  return false;
}
 
// special case for outgoing string enumerations
//
/// BGM: PRON 1325 (compiler bug) prevents this \#pragma for working
/// with some templatized functions.  Deferred for Ebony.
#pragma warn -inl
template<>
inline bool
TAutoEnumT<LPCTSTR>::Convert(TAutoVal& numVal, owl::TLangId langId)
{
  LPCTSTR str = numVal.StrVal();  // 0 if not string type
  if (str)
    for (int i = 0; i < Count; i++) {
      if (lstrcmp(Table[i].Val, str) == 0) {
        numVal = Table[i].Name.Translate(langId);
        numVal.SetLocale(langId);
        return true;
      }
    }
  return false;
}
#pragma warn .inl
 
//____________________________________________________________________________
 
// TAutoIterator inlines
 
inline TAutoIterator::operator IUnknown*() {RefCnt++; return this;}
inline TAutoSymbol* TAutoIterator::GetSymbol() {return Symbol;}
inline void TAutoIterator::SetSymbol(TAutoSymbol* sym) {Symbol = sym;}
 
//____________________________________________________________________________
//
// Inline implementations for automation server - part 2
//   These are inline only for the purpose of allowing _AUTOCLASS
//   to be specified at compile time without rebuilding OCF library
//   This applies to classes: TAutoBase, TAutoCommand, TAutoDetach
//____________________________________________________________________________
 
inline TAutoBase::~TAutoBase()
{
  ::ocf::SendObituary(this, typeid(TAutoBase));
}
 
inline void TAutoDetach::Notify(int offset, const std::type_info& typeInfo)
{
  ::ocf::SendObituary((char*)this-offset, typeInfo);
}
//____________________________________________________________________________
 
// TAutoCommand implementation specified inline to avoid _AUTOCLASS link errors
 
inline void TAutoCommand::Fail(TXAuto::TError err) { throw TXAuto(err); }
 
inline bool TAutoCommand::Validate() { return true; }
 
inline TAutoCommand& TAutoCommand::Invoke()
{
  if (!TAutoCommand_InvokeHook || TAutoCommand_InvokeHook(*this))
    Execute();
  return *this;
}
 
inline void TAutoCommand::Execute()
{
}
 
inline long TAutoCommand::Report()
{
  return 0;
}
 
inline void TAutoCommand::Return(TAutoVal& v)
{
  v = TAutoVoid();
}
 
inline void TAutoCommand::Transfer(TAutoTransfer& x)
{
}
 
inline TAutoCommand* TAutoCommand::Undo() {return 0;}
 
inline int TAutoCommand::Record(TAutoStack&) {return 0;}
 
inline TAutoCommand::TErrorMsgHook
TAutoCommand::SetErrorMsgHook(TAutoCommand::TErrorMsgHook callback){
  TErrorMsgHook hook = TAutoCommand_ErrorLookup;
  TAutoCommand_ErrorLookup = callback;
  return hook;
}
 
inline TAutoCommand::TCommandHook
TAutoCommand::SetCommandHook(TAutoCommand::TCommandHook callback){
  TCommandHook hook = TAutoCommand_InvokeHook;
  TAutoCommand_InvokeHook = callback;
  return hook;
}
 
#  if defined(BI_COMP_BORLANDC)
#    pragma warn .inl
#  endif
 
 
} // OCF namespace
 
 
#endif  // OCF_AUTODEFS_H
 
 

V302 Member operator[] of 'TAutoStack' class has a 32-bit type argument. Use memsize-type here.

V302 Member operator[] of 'TAutoProxyArgs' class has a 32-bit type argument. Use memsize-type here.

V1032 The pointer 'p' is cast to a more strictly aligned pointer type.

V690 The 'TAutoIterator' class implements a copy constructor, but lacks the copy assignment operator. It is dangerous to use such a class.

V1027 Pointer to an object of the 'TUnknown' class is cast to unrelated 'IUnknown' class.

V1027 Pointer to an object of the 'tagVARIANT' class is cast to unrelated 'TAutoVal' class.

V832 It's better to use '= default;' syntax instead of empty constructor body.

V802 On 32-bit platform, structure size can be reduced from 72 to 64 bytes by rearranging the fields according to their sizes in decreasing order.