home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
OCFINC.PAK
/
AUTODEFS.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
61KB
|
1,482 lines
//
//----------------------------------------------------------------------------
// 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