- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1482 lines
60 KiB
C++
1482 lines
60 KiB
C++
//
|
|
//----------------------------------------------------------------------------
|
|
// ObjectComponents
|
|
// (C) Copyright 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// OLE Automation Class Definitions
|
|
//----------------------------------------------------------------------------
|
|
#if !defined(OCF_AUTODEFS_H)
|
|
#define OCF_AUTODEFS_H
|
|
|
|
#if !defined(OCF_OCDEFS_H)
|
|
# include <ocf/ocdefs.h>
|
|
#endif
|
|
#if !defined(OSL_LOCALE_H)
|
|
# include <osl/locale.h> // TLocaleString and TRegItem/TRegList
|
|
#endif
|
|
#if !defined(OSL_USTRING_H)
|
|
# include <osl/ustring.h> // TString and TUString
|
|
#endif
|
|
#if !defined(__TYPEINFO_H)
|
|
# include <typeinfo.h>
|
|
#endif
|
|
|
|
// 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;
|
|
class TAutoSymbol;
|
|
class TAutoString;
|
|
class TAutoStack;
|
|
class far TAutoVal;
|
|
class TXAuto;
|
|
class TAutoEnum;
|
|
|
|
const void far* DynamicCast(const void far* obj, const typeinfo& src,
|
|
const typeinfo& dst);
|
|
const void far* MostDerived(const void far* obj, const typeinfo& src);
|
|
|
|
// global function to invalidate external references, class model-independent
|
|
//
|
|
void SendObituary(const void far* obj, const typeinfo& 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 typeinfo& 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, TLangId lang);
|
|
typedef IUnknown& (*TAggregator)(ObjectPtr obj, TUnknown& inner);
|
|
|
|
extern "C" const GUID __cdecl IID_TServedObject;
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TXAuto - automation exception object
|
|
//____________________________________________________________________________
|
|
|
|
class TXAuto : public TXBase {
|
|
public:
|
|
enum TError {
|
|
xNoError,
|
|
xConversionFailure,
|
|
xNotIDispatch,
|
|
xForeignIDispatch,
|
|
xTypeMismatch,
|
|
xNoArgSymbol,
|
|
xParameterMissing,
|
|
xNoDefaultValue,
|
|
xValidateFailure,
|
|
xExecutionFailure,
|
|
xErrorStatus,
|
|
};
|
|
TXAuto(TXAuto::TError err)
|
|
: TXBase("Automation Exception"), ErrorCode(err) {}
|
|
TError ErrorCode;
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoType, TAutoClass - automation type/class descriptor
|
|
//____________________________________________________________________________
|
|
|
|
struct TAutoType {
|
|
uint16 GetType() const {return Type;}
|
|
uint16 Type;
|
|
};
|
|
|
|
class TAutoClass : public TAutoType {
|
|
public:
|
|
TAutoClass(TAutoSymbol* table, TAutoSymbol* classSymbol,
|
|
const typeinfo& typeInfo, TAggregator aggregator=0);
|
|
~TAutoClass();
|
|
|
|
short CountCommands(); // forces counts to be set on first call
|
|
TAutoSymbol* Lookup(char far* name, TLangId lang, short symFlags, long far& id);
|
|
TAutoSymbol* LookupArg(char far* name, TLangId lang, TAutoSymbol* cmd,
|
|
long far& retid);
|
|
TAutoSymbol* FindId(short id, ObjectPtr& objptr);
|
|
TAutoSymbol* FindFunction(unsigned index, int& retId);
|
|
TAutoSymbol* FindVariable(unsigned index, int& retId);
|
|
TXAuto::TError Dispatch(ObjectPtr obj, TAutoCreator& creator,
|
|
TUnknown& owner, int attr, TAutoStack& args,
|
|
TAutoVal far* retval);
|
|
TAutoSymbol* GetTable();
|
|
TAutoSymbol* GetClassSymbol();
|
|
short GetArgCount(TAutoSymbol& sym);
|
|
TAutoCommandBuildDtr GetDestructor();
|
|
const typeinfo& GetTypeInfo();
|
|
const char* GetName(TLangId lang = TLocaleString::UserDefaultLangId);
|
|
const char* GetDoc (TLangId lang = TLocaleString::UserDefaultLangId);
|
|
unsigned long GetHelpId();
|
|
unsigned short GetTypeFlags();
|
|
int GetImplTypeFlags();
|
|
unsigned short GetCoClassFlags();
|
|
TAggregator GetAggregator();
|
|
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
|
|
TAutoSymbol* Table; // pointer to array of symbol entries
|
|
TAutoSymbol* ClassSymbol;// pointer to class symbol (terminator)
|
|
const typeinfo& 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 class TExtLink; // access to ClassList
|
|
friend class TClassList; // access to TAutoClassRef
|
|
friend class _ICLASS TTypeLibrary;// access to TAutoClassRef
|
|
friend class _ICLASS TCoClassInfo;// access to TAutoClassRef
|
|
friend class TAppDescriptor; // access to linkage information
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAuto(type) automation datatype encapsulations
|
|
//____________________________________________________________________________
|
|
|
|
struct TAutoVoid { // purpose to implement assignent of void to TAutoVal
|
|
static TAutoType ClassInfo;
|
|
};
|
|
|
|
struct TAutoDate { // purpose to disambiguate type from double
|
|
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 {
|
|
static TAutoType ClassInfo;
|
|
};
|
|
|
|
struct TAutoBool { // for suppressing compiler warnings until bool is a type
|
|
TAutoBool() : B(0) {}
|
|
TAutoBool(bool b) : B(b) {}
|
|
TAutoBool(TBool b) : B(static_cast<bool>(b)) {}
|
|
operator bool() {return B;}
|
|
operator TBool() {return static_cast<TBool>(B);}
|
|
void operator =(bool b) {B = b;}
|
|
void operator =(TBool b) {B = static_cast<bool>(b);}
|
|
bool B;
|
|
static TAutoType ClassInfo;
|
|
};
|
|
|
|
struct TAutoBoolRef { // needed for automating bool far* until bool is a type
|
|
TAutoBoolRef() : P(0) {}
|
|
TAutoBoolRef(bool far* p) : P(p) {}
|
|
TAutoBoolRef(TBool far* p) : P((bool far*)p) {}
|
|
operator bool far*() {return P;}
|
|
void operator =(bool far* p) {P = p;}
|
|
void operator =(TBool far* p){P = (bool far*)p;}
|
|
bool far* P;
|
|
static TAutoType ClassInfo;
|
|
};
|
|
|
|
// the following types do no hold data, but only provide static type codes
|
|
|
|
struct TAutoShort { static TAutoType ClassInfo; };
|
|
struct TAutoDouble { static TAutoType ClassInfo; };
|
|
struct TAutoFloat { static TAutoType ClassInfo; };
|
|
struct TAutoLong { static TAutoType ClassInfo; };
|
|
struct TAutoByte { static TAutoType ClassInfo; };
|
|
struct TAutoUnknown { static TAutoType ClassInfo; }; // for raw IUnknown*
|
|
struct TAutoDispatch { static TAutoType ClassInfo; }; // for raw IDispatch*
|
|
struct TAutoShortRef { static TAutoType ClassInfo; };
|
|
struct TAutoLongRef { static TAutoType ClassInfo; };
|
|
struct TAutoFloatRef { static TAutoType ClassInfo; };
|
|
struct TAutoDoubleRef { static TAutoType ClassInfo; };
|
|
struct TAutoCurrencyRef{ static TAutoType ClassInfo; };
|
|
struct TAutoDateRef { static TAutoType ClassInfo; };
|
|
struct TAutoStringRef { static TAutoType ClassInfo; };
|
|
struct TAutoVariantRef { static TAutoType ClassInfo; };
|
|
struct 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 = 0x0000, // void
|
|
atNull = 0x0001, // SQL style Null
|
|
atShort = 0x0002, // 2 byte signed int
|
|
atLong = 0x0003, // 4 byte signed int
|
|
atFloat = 0x0004, // 4 byte real
|
|
atDouble = 0x0005, // 8 byte real
|
|
atCurrency = 0x0006, // currency
|
|
atDatetime = 0x0007, // datetime as double
|
|
atString = 0x0008, // BSTR, string preceeded by length
|
|
atObject = 0x0009, // IDispatch*
|
|
atError = 0x000A, // SCODE
|
|
atBool = 0x000B, // True=-1, False=0
|
|
atVariant = 0x000C, // VARIANT FAR*
|
|
atUnknown = 0x000D, // IUnknown*
|
|
atByte = 0x0011, // byte, unsigned char
|
|
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 uint16 atSafeArray = 0x2000;
|
|
const uint16 atByRef = 0x4000;
|
|
const uint16 atEnum = 0x1000; // non-OLE, enumeration for data of a type
|
|
const uint16 atAutoClass = 0x0800; // non-OLE, class object is a TAutoClass
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Automated class typeinfo 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 typeinfo.
|
|
// 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 uint16 tfAppObject = 1; // TYPEFLAG_FAPPOBJECT, set on COCLASS
|
|
const uint16 tfCanCreate = 2; // TYPEFLAG_FCANCREATE, set on COCLASS
|
|
const uint16 tfLicensed = 4; // TYPEFLAG_FLICENSED, set on COCLASS
|
|
const uint16 tfPredeclared = 8; // TYPEFLAG_FPREDECLID, set on COCLASS
|
|
const uint16 tfControl = 32; // TYPEFLAG_FCONTROL, set on COCLASS
|
|
const 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 uint16 tfDefault = (1<<12); // IMPLTYPEFLAG_FDEFAULT << 12
|
|
const uint16 tfEventSource = (2<<12); // IMPLTYPEFLAG_FSOURCE << 12
|
|
const uint16 tfRestricted = (4<<12); // IMPLTYPEFLAG_FRESTRICTED << 12
|
|
const uint16 tfImplFlagXfer = (tfDefault | tfEventSource | tfRestricted);
|
|
|
|
// Flags set on individual autoclasses, transferred to corresponding typeinfos
|
|
|
|
const uint16 tfHidden = 16; // TYPEFLAG_FHIDDEN
|
|
const uint16 tfNonextensible = 128; // TYPEFLAG_FNONEXTENSIBLE
|
|
const uint16 tfAutoClassMask = tfHidden|tfNonextensible;
|
|
|
|
// Flags defined by OLE, but not applicable to dispatch interfaces
|
|
|
|
const uint16 tfDual = 64; // TYPEFLAG_FDUAL
|
|
const uint16 tfAutomation = 256; // TYPEFLAG_FOLEAUTOMATION
|
|
|
|
// Default typeflags value for autoclass not exposed as part of the coclass
|
|
|
|
const uint16 tfNormal = 0; // automated classes not at app level
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoSymbol - symbol table element
|
|
//____________________________________________________________________________
|
|
|
|
struct TAutoSymbol {
|
|
TLocaleString Name; // name of symbol, initially untranslated
|
|
TLocaleString Doc; // documentation string, initially untranslated
|
|
uint16 Attr; // attributes: enum AutoSymFlag, as????
|
|
union {
|
|
short 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 far* DefaultArg; // asArgument: default value, extends to 8 bytes
|
|
};
|
|
ulong HelpId; // help context ID, not for asArgument
|
|
|
|
// inline data member accessor functions
|
|
void SetFlag(uint16 mask);
|
|
void ClearFlag(uint16 mask);
|
|
bool TestFlag(uint16 mask);
|
|
uint16 GetFlags();
|
|
bool IsEnum();
|
|
bool IsByRef();
|
|
bool IsArray();
|
|
bool IsIterator();
|
|
bool IsTerminator();
|
|
uint16 GetDataType();
|
|
TAutoClass* GetClass();
|
|
TAutoEnum* GetEnum();
|
|
|
|
// 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);
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TObjectDescriptor - precursor to TServedObject containing object info
|
|
//____________________________________________________________________________
|
|
|
|
struct TObjectDescBase { // ONLY for use when storing in TAutoVal union
|
|
const void* Object; // pointer to C++ object
|
|
TAutoClass* Class; // class descriptor, contains typeinfo
|
|
const void far* MostDerived()
|
|
{return ::MostDerived(Object, Class->GetTypeInfo());}
|
|
}; // cannot have a constructor and must limit to 8 bytes for TAutoVal union
|
|
|
|
struct 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,
|
|
TObjectDescriptor::TDestruct destruct = Quiet)
|
|
{ Object = obj; Class = &classobj; Destruct = destruct; }
|
|
private:
|
|
TObjectDescriptor() {} // uninitialized struct
|
|
friend class TAutoClass; // restrict access to uninitialized constructor
|
|
friend class TAutoIterator;
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// 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.
|
|
|
|
class far TAutoVal {
|
|
public:
|
|
operator unsigned char();
|
|
operator signed char();
|
|
operator char();
|
|
operator unsigned char far*();
|
|
operator signed char far*();
|
|
operator char far*();
|
|
operator int();
|
|
operator int far*();
|
|
operator unsigned int();
|
|
operator short();
|
|
operator short far*();
|
|
operator unsigned short();
|
|
operator unsigned short far*();// Note:VARIANT can't distinguish from short*
|
|
operator long();
|
|
operator long far*();
|
|
operator unsigned long();
|
|
operator unsigned long far*();// Note:VARIANT can't distinguish from long*
|
|
operator float();
|
|
operator float far*();
|
|
operator double();
|
|
operator double far*();
|
|
operator TBool();
|
|
operator TBool far*();
|
|
operator TAutoBool();
|
|
operator TAutoBoolRef();
|
|
operator TAutoCurrency();
|
|
operator TAutoCurrency far*();
|
|
operator TAutoDate();
|
|
operator TAutoDate far*();
|
|
operator string();
|
|
operator TUString*();
|
|
operator IDispatch*();
|
|
operator IUnknown*();
|
|
operator IDispatch&();
|
|
operator IUnknown&();
|
|
|
|
void operator =(unsigned char i);
|
|
void operator =(signed char i);
|
|
void operator =(char i);
|
|
void operator =(unsigned char far* p);
|
|
void operator =(signed char far* p);
|
|
void operator =(char far* p);
|
|
void operator =(int i);
|
|
void operator =(int far* p);
|
|
void operator =(unsigned int i);
|
|
void operator =(unsigned int far* p);
|
|
void operator =(unsigned short i);
|
|
void operator =(unsigned short far*p);
|
|
void operator =(long i);
|
|
void operator =(long far* p);
|
|
void operator =(unsigned long i);
|
|
void operator =(unsigned long far* p);
|
|
void operator =(short i);
|
|
void operator =(short far* p);
|
|
void operator =(float i);
|
|
void operator =(float far* p);
|
|
void operator =(double i);
|
|
void operator =(double far* p);
|
|
void operator =(TBool i);
|
|
void operator =(TBool far* p);
|
|
void operator =(TAutoBool i);
|
|
void operator =(TAutoBoolRef p);
|
|
void operator =(const string& s);
|
|
void operator =(TAutoString s);
|
|
void operator =(TAutoCurrency i);
|
|
void operator =(TAutoCurrency far* p);
|
|
void operator =(TAutoDate i);
|
|
void operator =(TAutoDate far* i);
|
|
void operator =(IDispatch* ifc);
|
|
void operator =(IUnknown* ifc);
|
|
void operator =(TObjectDescriptor od);
|
|
void operator =(TAutoVoid);
|
|
|
|
int GetDataType();
|
|
void Clear(); // free any references, set type to atVoid
|
|
void Restore(); // convert any non-OLE changes back to original types
|
|
void Copy(const TAutoVal& copy);
|
|
bool IsRef();
|
|
TAutoVal far* DereferenceVariant();
|
|
void SetLocale(TLocaleId); // associate locale with appropriate pointers
|
|
TLocaleId GetLocale() const;// retrieve locale from appropriate pointers
|
|
TLangId GetLanguage() const; // retrieve language from pointer types
|
|
TString StrVal(); // returns internal string pointer if atString
|
|
bool GetObjDesc(TObjectDescriptor&);// return temp object info, else false
|
|
SAFEARRAY far* GetArray(); // return array pointer, null if not array
|
|
void far* SetByRef(AutoDataType); // set type, return pointer to data loc
|
|
|
|
private:
|
|
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 far* parray; // VT_ARRAY|*
|
|
|
|
unsigned char far* pbVal; // VT_BYREF|VT_UI1
|
|
short far* piVal; // VT_BYREF|VT_I2
|
|
long far* plVal; // VT_BYREF|VT_I4
|
|
float far* pfltVal; // VT_BYREF|VT_R4
|
|
double far* pdblVal; // VT_BYREF|VT_R8
|
|
VARIANT_BOOL far* pbool; // VT_BYREF|VT_BOOL
|
|
SCODE far* pscode; // VT_BYREF|VT_ERROR
|
|
TAutoCurrency far* pcyVal; // VT_BYREF|VT_CY
|
|
DATE far* pdate; // VT_BYREF|VT_DATE
|
|
BSTR far* pbstrVal; // VT_BYREF|VT_BSTR
|
|
IUnknown* far* ppunkVal; // VT_BYREF|VT_UNKNOWN
|
|
IDispatch* far* ppdispVal; // VT_BYREF|VT_DISPATCH
|
|
SAFEARRAY far* far* pparray; // VT_BYREF|VT_ARRAY|*
|
|
VARIANT far* pvarVal; // VT_BYREF|VT_VARIANT
|
|
void far* byref; // Generic ByRef
|
|
|
|
struct { // added locale info for BSTR/IDispatch
|
|
void far* Val;
|
|
LCID Locale; // unused 4 bytes for pointer types
|
|
} p;
|
|
|
|
struct { // added info when loaned BSTR ownership
|
|
BSTR Val;
|
|
TUString* Holder; // string holder sharing current BSTR
|
|
} s;
|
|
|
|
TObjectDescBase ObjDesc; // temporary space for returning object
|
|
};
|
|
void ConvRef(int type);
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoString class - based on reference counted TString with added automation
|
|
// functionality
|
|
//
|
|
class TAutoString : public TString {
|
|
public:
|
|
TAutoString(const char far* s = 0) : TString(s) {}
|
|
#if defined(BI_HAS_WCHAR)
|
|
TAutoString(const wchar_t* s) : TString(s) {}
|
|
#endif
|
|
TAutoString(BSTR s, bool loan) : TString(s) {}
|
|
TAutoString(const string& s) : TString(s) {}
|
|
TAutoString(TUString* s) : TString(s) {}
|
|
TAutoString(TAutoVal& val) : TString(val) {}
|
|
TAutoString(const TAutoString& src) : TString(src.S) {++*S;}
|
|
|
|
TAutoString& operator =(const char far* 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;}
|
|
#if defined(BI_HAS_WCHAR)
|
|
TAutoString& operator =(const wchar_t* s) {S = S->Assign(s); return *this;}
|
|
TAutoString& operator =(wchar_t* s) {S = S->Assign(s); return *this;}
|
|
#endif
|
|
TAutoString& operator =(TAutoVal& val) {--*S; S = val; return *this;}
|
|
|
|
static TAutoType ClassInfo; // automation type code
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoStack - automation argument stack abstraction
|
|
//____________________________________________________________________________
|
|
|
|
class TAutoStack {
|
|
public:
|
|
enum {SetValue = -3}; // special arg index for property set value
|
|
TAutoStack(VARIANT far* stack, TLocaleId locale, int argcount,
|
|
int namedcount, long far* map, TServedObject* owner);
|
|
~TAutoStack();
|
|
TAutoVal& operator[](int index);
|
|
TAutoSymbol* Symbol; // symbol of method/prop, args follow
|
|
int ArgSymbolCount;
|
|
TLangId LangId;
|
|
int CurrentArg; // index of last arg requested by operator[]
|
|
const int ArgCount;
|
|
TServedObject* Owner;
|
|
long ErrorCode; // set if TXAuto::xErrorStatus returned
|
|
const char* ErrorMsg; // set if TXAuto::xErrorStatus returned
|
|
protected:
|
|
TAutoVal far* Stack;
|
|
int NamedCount;
|
|
long far* NamedIds;
|
|
TAutoVal Default;
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Automation abstract base class for command objects
|
|
//____________________________________________________________________________
|
|
|
|
struct TAutoTransfer; // persistence transfer parameter structure
|
|
|
|
class 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 const char* (*TErrorMsgHook)(long errCode);
|
|
static TErrorMsgHook SetErrorMsgHook(TErrorMsgHook callback);
|
|
|
|
typedef bool (*TCommandHook)(TAutoCommand& cmdObj);
|
|
static TCommandHook SetCommandHook(TCommandHook callback);
|
|
|
|
// inline data member accessor functions
|
|
static const char* 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 TAutoCommand::TErrorMsgHook TAutoCommand_ErrorLookup;
|
|
extern TAutoCommand::TCommandHook TAutoCommand_InvokeHook;
|
|
|
|
// Build function for application Quit command implementation
|
|
TAutoCommand* AutoQuitBuild(ObjectPtr obj, int attr, TAutoStack& args);
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoEnum - automation enumeration descriptor
|
|
//____________________________________________________________________________
|
|
|
|
template <class T>
|
|
struct TAutoEnumVal {
|
|
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, 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, TLangId langId);
|
|
|
|
protected:
|
|
TAutoEnumVal<T>* Table; // pointer to array of symbol entries
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// 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 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);
|
|
//protected:
|
|
TAppDescriptor& AppDesc;
|
|
TServedObject* AppObject;
|
|
private:
|
|
int ObjCount;
|
|
friend class TServedObject;
|
|
};
|
|
|
|
class _ICLASS TDispatch;
|
|
|
|
class TDispatchCreator : public TAutoCreator {
|
|
public:
|
|
TDispatchCreator() {}
|
|
TUnknown* CreateObject(TObjectDescriptor objDesc, IUnknown* outer = 0);
|
|
IDispatch* CreateDispatch(TObjectDescriptor objDesc, IUnknown* outer = 0);
|
|
protected:
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TServedObject - OLE object exposed for automated access of internal object
|
|
//____________________________________________________________________________
|
|
|
|
DECLARE_COMBASES2(TServedCOM, IDispatch, ITypeInfo)
|
|
|
|
class _ICLASS TServedObject : public TServedCOM {
|
|
HRESULT QueryObject(const GUID far& iid, void far* far* pif);
|
|
public:
|
|
TServedObject(TObjectDescriptor& obj, TServedObjectCreator& creator,
|
|
IUnknown* outer=0);
|
|
~TServedObject();
|
|
TServedObject* GetAppObject() {return Creator.AppObject;}
|
|
TServedObjectCreator& GetCreator() {return Creator;}
|
|
void* Object; // pointer to C++ object instance, 0 if deleted
|
|
const void far* RootObject; // pointer to object of most derived class
|
|
TAutoClass* Class; // class of which object is an instance
|
|
TServedObjectCreator& Creator;
|
|
operator IDispatch*();
|
|
TLangId ReqLang; // language requested by caller
|
|
TObjectDescriptor::TDestruct Destruct; // what to do with C++ object
|
|
private:
|
|
TServedObject* Next;
|
|
TServedObject* far* Prev;
|
|
// need to access local LANGID for typeinfo, either as member or as global
|
|
|
|
// IDispatch implementation
|
|
HRESULT _IFUNC GetTypeInfoCount(unsigned int far* pctinfo);
|
|
HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
|
|
ITypeInfo* far* pptinfo);
|
|
HRESULT _IFUNC GetIDsOfNames(const IID far& riid, OLECHAR far* far* rgszNames,
|
|
uint cNames, LCID lcid,
|
|
DISPID far* rgdispid);
|
|
HRESULT _IFUNC Invoke(DISPID dispidMember, const IID far& riid, LCID lcid,
|
|
unsigned short wFlags,
|
|
DISPPARAMS far* pdispparams,
|
|
VARIANT far* pvarResult,
|
|
EXCEPINFO far* pexcepinfo,
|
|
unsigned int far* puArgErr);
|
|
|
|
// ITypeInfo implementation
|
|
HRESULT _IFUNC GetTypeAttr(TYPEATTR far* far* pptypeattr);
|
|
HRESULT _IFUNC GetTypeComp(ITypeComp* far* pptcomp);
|
|
HRESULT _IFUNC GetFuncDesc(unsigned int index, FUNCDESC far* far* ppfuncdesc);
|
|
HRESULT _IFUNC GetVarDesc(unsigned int index, VARDESC far* far* ppvardesc);
|
|
HRESULT _IFUNC GetNames(MEMBERID memid, BSTR far* rgbstrNames,
|
|
unsigned int cMaxNames,
|
|
unsigned int far* pcNames);
|
|
HRESULT _IFUNC GetRefTypeOfImplType(unsigned int index, HREFTYPE far* phreftype);
|
|
HRESULT _IFUNC GetImplTypeFlags(unsigned int index, int far* pimpltypeflags);
|
|
HRESULT _IFUNC GetIDsOfNames(OLECHAR far* far* rgszNames,
|
|
unsigned int cNames,
|
|
MEMBERID far* rgmemid);
|
|
HRESULT _IFUNC Invoke(void far* pvInstance, MEMBERID memid,
|
|
unsigned short wFlags,
|
|
DISPPARAMS far *pdispparams,
|
|
VARIANT far *pvarResult,
|
|
EXCEPINFO far *pexcepinfo,
|
|
unsigned int far *puArgErr);
|
|
HRESULT _IFUNC GetDocumentation(MEMBERID memid,
|
|
BSTR far* pbstrName,
|
|
BSTR far* pbstrDocString,
|
|
ulong far* pdwHelpContext,
|
|
BSTR far* pbstrHelpFile);
|
|
HRESULT _IFUNC GetDllEntry(MEMBERID memid, INVOKEKIND invkind,
|
|
BSTR far* pbstrDllName,
|
|
BSTR far* pbstrName,
|
|
unsigned short far* pwOrdinal);
|
|
HRESULT _IFUNC GetRefTypeInfo(HREFTYPE hreftype,
|
|
ITypeInfo* far* pptinfo);
|
|
HRESULT _IFUNC AddressOfMember(MEMBERID memid, INVOKEKIND invkind,
|
|
void far* far* ppv);
|
|
HRESULT _IFUNC CreateInstance(IUnknown* punkOuter, const IID far& riid,
|
|
void far* far* ppvObj);
|
|
HRESULT _IFUNC GetMops(MEMBERID memid, BSTR far* pbstrMops);
|
|
HRESULT _IFUNC GetContainingTypeLib(ITypeLib* far* pptlib,
|
|
uint far* pindex);
|
|
void _IFUNC ReleaseTypeAttr(TYPEATTR far* ptypeattr);
|
|
void _IFUNC ReleaseFuncDesc(FUNCDESC far* pfuncdesc);
|
|
void _IFUNC ReleaseVarDesc(VARDESC far* pvardesc);
|
|
friend class TAppDescriptor; // access to Next,Prev
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TDispatch - lightweight IDispatch implementation for automation controllers
|
|
//____________________________________________________________________________
|
|
|
|
DECLARE_COMBASES1(TDispatchCOM, IDispatch)
|
|
|
|
class _ICLASS TDispatch : public TDispatchCOM {
|
|
public:
|
|
TDispatch(TObjectDescriptor& obj, IUnknown* outer = 0);
|
|
void* Object; // pointer to C++ object instance, 0 if deleted
|
|
TAutoClass* Class; // class of which object is an instance
|
|
void InvalidateObject() {Object = 0;}
|
|
operator IDispatch*();
|
|
private:
|
|
// IDispatch implementation
|
|
HRESULT _IFUNC GetTypeInfoCount(unsigned int far* pctinfo);
|
|
HRESULT _IFUNC GetTypeInfo(unsigned int itinfo, LCID lcid,
|
|
ITypeInfo* far* pptinfo);
|
|
HRESULT _IFUNC GetIDsOfNames(const IID far& riid, OLECHAR far* far* rgszNames,
|
|
unsigned int cNames, LCID lcid,
|
|
DISPID far* rgdispid);
|
|
HRESULT _IFUNC Invoke(DISPID dispidMember, const IID far& riid, LCID lcid,
|
|
unsigned short wFlags,
|
|
DISPPARAMS far* pdispparams,
|
|
VARIANT far* pvarResult,
|
|
EXCEPINFO far* pexcepinfo,
|
|
unsigned int far* puArgErr);
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// 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 far* far*)&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 far* far*)&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) {P=p;}
|
|
void operator=(T& r) {P=&r;}
|
|
TAutoObjectDelete() : TAutoObject<T>() {}
|
|
TAutoObjectDelete(T* p) : TAutoObject<T>(p) {}
|
|
TAutoObjectDelete(T& r) : TAutoObject<T>(r) {}
|
|
operator TObjectDescriptor()
|
|
{return TObjectDescriptor(P,T::ClassInfo, TObjectDescriptor::Delete);}
|
|
};
|
|
|
|
template<class T> // for returning objects by value
|
|
class TAutoObjectByVal : public TAutoObjectDelete<T> {
|
|
public:
|
|
void operator=(T o) {P=new T(o);}
|
|
TAutoObjectByVal() : TAutoObjectDelete<T>() {}
|
|
TAutoObjectByVal(T o) : TAutoObjectDelete<T>(new T(o)) {}
|
|
};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// TAutoIterator - automation collection iterator
|
|
//____________________________________________________________________________
|
|
|
|
|
|
class TAutoIterator : public IEnumVARIANT {
|
|
public:
|
|
// IEnumVARIANT implementation
|
|
HRESULT _IFUNC QueryInterface(const GUID far& iid, void far*far* pif);
|
|
unsigned long _IFUNC AddRef();
|
|
unsigned long _IFUNC Release();
|
|
HRESULT _IFUNC Next(unsigned long count, VARIANT far* retvals,
|
|
unsigned long far* retcount);
|
|
HRESULT _IFUNC Skip(unsigned long count);
|
|
HRESULT _IFUNC Reset();
|
|
HRESULT _IFUNC Clone(IEnumVARIANT* far* 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;
|
|
TLangId Lang;
|
|
TAutoIterator(TAutoCreator& creator, IUnknown* owner, TLangId lang); // called from derived
|
|
TAutoIterator(TAutoIterator& copy); // copy constructor for base 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
|
|
};
|
|
|
|
class TAutoProxyArgs {
|
|
public:
|
|
TAutoProxyArgs(int cnt) : Count(cnt) {}
|
|
~TAutoProxyArgs();
|
|
TAutoVal& operator[](int index);
|
|
operator TAutoVal&() {return *(TAutoVal*)(this+1);}
|
|
operator VARIANT far*() {return (VARIANT far*)(this+1);}
|
|
operator unsigned int() {return Count;}
|
|
private:
|
|
int Count;
|
|
};
|
|
|
|
template <int N>
|
|
struct TAutoArgs : public TAutoProxyArgs {
|
|
TAutoVal Args[N+1];
|
|
TAutoArgs() : TAutoProxyArgs(N) {}
|
|
};
|
|
|
|
class TAutoProxy {
|
|
public:
|
|
~TAutoProxy();
|
|
void Bind(IUnknown* obj);
|
|
void Bind(IUnknown& obj);
|
|
void Bind(const GUID& guid);
|
|
void Bind(const char far* progid);
|
|
void Bind(TAutoVal& val);
|
|
void Bind(IDispatch* obj);
|
|
void Bind(IDispatch& obj);
|
|
void Unbind();
|
|
void MustBeBound();
|
|
bool IsBound() {return ToBool(That != 0);}
|
|
void SetLang(TLangId lang) {Lang = lang;}
|
|
operator IDispatch*();
|
|
operator IDispatch&();
|
|
long Lookup(const long id) {return id;}
|
|
long Lookup(const char far* name);
|
|
void Lookup(const char far* names, long* ids, unsigned count);
|
|
protected:
|
|
TAutoProxy(TLangId lang) : That(0), Lang(lang) {}
|
|
TAutoVal& Invoke(uint16 attr, TAutoProxyArgs& args, long* ids, unsigned named=0);
|
|
IDispatch* That;
|
|
TLangId Lang;
|
|
};
|
|
|
|
struct TAutoDispId {
|
|
TAutoDispId(TAutoProxy* prx, const char* name) : Id(prx->Lookup(name)) {}
|
|
TAutoDispId(TAutoProxy*, long id) : Id(id) {}
|
|
long Id;
|
|
operator long*() {return &Id;}
|
|
operator unsigned() {return 0;}
|
|
};
|
|
|
|
template <int N> struct TAutoDispIds {
|
|
TAutoDispIds(TAutoProxy* prx, const char* names) {prx->Lookup(names, Ids);}
|
|
long Ids[N+1];
|
|
operator long*() {return Ids;}
|
|
operator unsigned() {return N;}
|
|
};
|
|
|
|
class 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)
|
|
{
|
|
return *((TAutoVal*)(this+1)+(index ? Count+1-index : 0));
|
|
}
|
|
|
|
inline TAutoProxy::operator IDispatch&() // this function not used internally
|
|
{
|
|
if (!That) // test only needed if inline to prevent function call overhead
|
|
MustBeBound();
|
|
return *That;
|
|
}
|
|
|
|
inline TAutoProxy::operator IDispatch*()
|
|
{
|
|
if (That)
|
|
That->AddRef();
|
|
return That;
|
|
}
|
|
|
|
inline void TAutoProxy::Unbind()
|
|
{
|
|
if (That)
|
|
That->Release();
|
|
That = 0;
|
|
}
|
|
|
|
inline TAutoProxy::~TAutoProxy()
|
|
{
|
|
Unbind();
|
|
}
|
|
|
|
inline void TAutoEnumerator<short>::Value(short& v) { v = Current; }
|
|
inline void TAutoEnumerator<long>::Value(long& v) { v = Current; }
|
|
inline void TAutoEnumerator<bool>::Value(bool& v) { v = Current; }
|
|
inline void TAutoEnumerator<TAutoString>::Value(TAutoString& v)
|
|
{ v = Current; }
|
|
|
|
inline TAutoEnumerator<short>::operator short() { return (short)Current; }
|
|
inline TAutoEnumerator<long>::operator long() { return (long)Current; }
|
|
inline TAutoEnumerator<bool>::operator bool() { return (bool)Current; }
|
|
inline TAutoEnumerator<TAutoString>::operator TAutoString()
|
|
{ return (TAutoString)Current; }
|
|
//____________________________________________________________________________
|
|
//
|
|
// Inline implementations for automation server - part 1
|
|
//____________________________________________________________________________
|
|
|
|
// TAutoClass inlines
|
|
|
|
inline TAutoSymbol* TAutoClass::GetTable() {return Table;}
|
|
inline TAutoSymbol* TAutoClass::GetClassSymbol() {return ClassSymbol;}
|
|
inline TAutoCommandBuildDtr TAutoClass::GetDestructor() {return ClassSymbol->BuildDtr;}
|
|
inline const typeinfo& TAutoClass::GetTypeInfo() {return TypeInfo;}
|
|
inline const char* TAutoClass::GetName(TLangId id) {return ClassSymbol->Name.Translate(id);}
|
|
inline const char* TAutoClass::GetDoc (TLangId id) {return ClassSymbol->Doc.Translate(id);}
|
|
inline unsigned long TAutoClass::GetHelpId() {return ClassSymbol->HelpId;}
|
|
inline unsigned short TAutoClass::GetTypeFlags()
|
|
{return ClassSymbol->TypeFlags & tfAutoClassMask;}
|
|
inline int TAutoClass::GetImplTypeFlags() {return ClassSymbol->TypeFlags>>12;}
|
|
inline unsigned short TAutoClass::GetCoClassFlags()
|
|
{return ClassSymbol->TypeFlags & tfCoClassXfer;}
|
|
inline TAggregator TAutoClass::GetAggregator() {return Aggregator;}
|
|
inline IUnknown& TAutoClass::Aggregate(ObjectPtr obj, TUnknown& inner)
|
|
{return obj && Aggregator ? Aggregator(obj, inner) : (IUnknown&)inner;}
|
|
//____________________________________________________________________________
|
|
|
|
// TAutoSymbol inlines
|
|
|
|
inline void TAutoSymbol::SetFlag(uint16 mask) {Attr |= mask;}
|
|
inline void TAutoSymbol::ClearFlag(uint16 mask) {Attr &= uint16(~mask);}
|
|
inline bool TAutoSymbol::TestFlag(uint16 mask) {return (Attr&mask)? true:false;}
|
|
inline uint16 TAutoSymbol::GetFlags() {return (uint16)Attr;}
|
|
inline bool TAutoSymbol::IsEnum() {return (Type->GetType() & atEnum)? true:false;}
|
|
inline bool TAutoSymbol::IsByRef() {return (Type->GetType() & atByRef)? true:false;}
|
|
inline bool TAutoSymbol::IsArray() {return (Type->GetType() & atSafeArray)? true:false;}
|
|
inline bool TAutoSymbol::IsIterator() {return ToBool((Attr&asIterator)==asIterator);}
|
|
inline bool TAutoSymbol::IsTerminator() {return ToBool((Attr & asNotTerminator)== 0);}
|
|
inline uint16 TAutoSymbol::GetDataType() {return uint16(Type->GetType() & atTypeMask);}
|
|
inline TAutoClass* TAutoSymbol::GetClass(){return (Type->GetType()&atAutoClass)?
|
|
(TAutoClass*)Type : 0; }
|
|
inline TAutoEnum* TAutoSymbol::GetEnum() {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;}
|
|
//____________________________________________________________________________
|
|
|
|
// TAutoVal inlines
|
|
|
|
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 far*() {return (int far*)operator short far*();}
|
|
#else
|
|
inline TAutoVal::operator int() {return operator long(); }
|
|
inline TAutoVal::operator unsigned int() {return (unsigned long)(long)*this;}
|
|
inline TAutoVal::operator int far*() {return (int far*)operator long far*();}
|
|
#endif
|
|
|
|
inline TAutoVal::operator TAutoBool() {return TAutoBool(operator TBool());}
|
|
inline TAutoVal::operator TAutoBoolRef(){return TAutoBoolRef(operator TBool far*());}
|
|
inline TAutoVal::operator signed char(){return operator unsigned char();}
|
|
inline TAutoVal::operator char() {return operator unsigned char();}
|
|
inline TAutoVal::operator char far*() {return (char far*)operator unsigned char far*();}
|
|
inline TAutoVal::operator signed char far*(){return (signed char far*)operator unsigned char far*();}
|
|
|
|
inline void TAutoVal::operator =(IDispatch* ifc) {vt=atObject; pdispVal=ifc;}
|
|
inline void TAutoVal::operator =(IUnknown* ifc) {vt=atUnknown; punkVal=ifc;}
|
|
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 =(TBool v) {vt=atBool; boolVal = short(v ? -1 : 0);}
|
|
inline void TAutoVal::operator =(TAutoBool v){vt=atBool; boolVal = short((bool)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 =(unsigned char far* p){vt=atByte+atByRef; pbVal=p;}
|
|
inline void TAutoVal::operator =(signed char far* p){vt=atByte+atByRef; pbVal=(unsigned char far*) p;}
|
|
inline void TAutoVal::operator =(char far* p) {vt=atByte+atByRef; pbVal=(unsigned char far*) p;}
|
|
inline void TAutoVal::operator =(short far* p) {vt=atShort+atByRef; piVal=p;}
|
|
inline void TAutoVal::operator =(long far* p) {vt=atLong+atByRef; plVal=p;}
|
|
inline void TAutoVal::operator =(TBool far* p) {vt=atBool+atByRef; pbool=(VARIANT_BOOL far*)p;}
|
|
inline void TAutoVal::operator =(TAutoBoolRef p){vt=atBool+atByRef; pbool=(VARIANT_BOOL far*)(bool far*)p;}
|
|
inline void TAutoVal::operator =(float far* p) {vt=atFloat+atByRef; pfltVal=p;}
|
|
inline void TAutoVal::operator =(double far* p){vt=atDouble+atByRef;pdblVal=p;}
|
|
inline void TAutoVal::operator =(TAutoDate far* p){vt=atDatetime+atByRef;pdate=(double far*)p;}
|
|
inline void TAutoVal::operator =(TAutoCurrency far* p){vt=atCurrency+atByRef;pcyVal=p;}
|
|
|
|
inline void TAutoVal::operator =(unsigned short v){vt=atLong; lVal = (long)v;}
|
|
inline void TAutoVal::operator =(unsigned short far* p)
|
|
{vt=atShort+atByRef; piVal = (short far*)p;}
|
|
inline void TAutoVal::operator =(unsigned long v) {vt=atLong; lVal = (long)v;}
|
|
inline void TAutoVal::operator =(unsigned long far* p)
|
|
{vt=atLong+atByRef; plVal = (long far*)p;}
|
|
#if (MAXINT==MAXSHORT)
|
|
inline void TAutoVal::operator =(int v) {vt=atShort; iVal=v;}
|
|
inline void TAutoVal::operator =(int far* p) {vt=atShort+atByRef; piVal=(short far*)p;}
|
|
inline void TAutoVal::operator =(unsigned int v) {operator =((unsigned short)v);}
|
|
inline void TAutoVal::operator =(unsigned int far* p) {operator =((unsigned short far*)p);}
|
|
#else
|
|
inline void TAutoVal::operator =(int v) {vt=atLong; lVal=v;}
|
|
inline void TAutoVal::operator =(int far* p) {vt=atLong+atByRef; plVal = (long far*)p;}
|
|
inline void TAutoVal::operator =(unsigned int v) {operator =((unsigned long)v);}
|
|
inline void TAutoVal::operator =(unsigned int far* p) {operator =((unsigned long far*)p);}
|
|
#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() {return vt;}
|
|
|
|
inline void TAutoVal::Clear()
|
|
{
|
|
if ((vt & ~atByRef) == atLoanedBSTR) {
|
|
s.Holder->ReleaseBstr((vt & atByRef) ? *pbstrVal : bstrVal);
|
|
vt = uint16(atString | (vt & atByRef));
|
|
}
|
|
::VariantClear((VARIANT far*)this);
|
|
}
|
|
|
|
inline void TAutoVal::Restore()
|
|
{
|
|
if ((vt & ~atByRef) == atLoanedBSTR) {
|
|
s.Holder->RevokeBstr((vt & atByRef) ? *pbstrVal : bstrVal);
|
|
vt = uint16(atString | (vt & atByRef));
|
|
} else if (vt == 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);
|
|
}
|
|
|
|
inline bool TAutoVal::IsRef() {return ToBool(vt & atByRef);}
|
|
|
|
inline TAutoVal far* TAutoVal::DereferenceVariant()
|
|
{return vt==atVariant+atByRef ? (TAutoVal far*)pvarVal : this;}
|
|
|
|
inline 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 far* TAutoVal::GetArray()
|
|
{
|
|
if (vt == atSafeArray)
|
|
return parray;
|
|
if (vt == (atSafeArray|atByRef))
|
|
return *pparray;
|
|
return 0;
|
|
}
|
|
|
|
inline void far* TAutoVal::SetByRef(AutoDataType datatype)
|
|
{
|
|
if (vt == atVariant)
|
|
return this;
|
|
vt = 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 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 const char* 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 char far* str = txtVal.StrVal(); // 0 if not string type
|
|
if (str) {
|
|
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, 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
|
|
//
|
|
#pragma warn -inl
|
|
inline bool
|
|
TAutoEnumT<const char*>::Convert(TAutoVal& numVal, TLangId langId)
|
|
{
|
|
const char far* 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()
|
|
{
|
|
::SendObituary(this, typeid(TAutoBase));
|
|
}
|
|
|
|
inline void TAutoDetach::Notify(int offset, const typeinfo& typeInfo)
|
|
{
|
|
::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;
|
|
}
|
|
|
|
#endif // OCF_AUTODEFS_H
|
|
|
|
|