// //---------------------------------------------------------------------------- // 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 #endif #if !defined(OSL_LOCALE_H) # include // TLocaleString and TRegItem/TRegList #endif #if !defined(OSL_USTRING_H) # include // TString and TUString #endif #if !defined(__TYPEINFO_H) # include #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 struct TTypeConvert { static ObjectPtr Cast(ObjectPtr from) { return reinterpret_cast( dynamic_cast(reinterpret_cast(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(b)) {} operator bool() {return B;} operator TBool() {return static_cast(B);} void operator =(bool b) {B = b;} void operator =(TBool b) {B = static_cast(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 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 TAutoEnumT : public TAutoEnum { public: TAutoEnumT(TAutoEnumVal* table, int symcount, int type); bool Convert(TAutoVal& txtVal, TAutoVal& numVal); bool Convert(TAutoVal& numVal, TLangId langId); protected: TAutoEnumVal* 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 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 TAutoObject::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 void TAutoObject::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 // for returning objects only, no IDispatch constructor class TAutoObjectDelete : public TAutoObject{ public: void operator=(T* p) {P=p;} void operator=(T& r) {P=&r;} TAutoObjectDelete() : TAutoObject() {} TAutoObjectDelete(T* p) : TAutoObject(p) {} TAutoObjectDelete(T& r) : TAutoObject(r) {} operator TObjectDescriptor() {return TObjectDescriptor(P,T::ClassInfo, TObjectDescriptor::Delete);} }; template // for returning objects by value class TAutoObjectByVal : public TAutoObjectDelete { public: void operator=(T o) {P=new T(o);} TAutoObjectByVal() : TAutoObjectDelete() {} TAutoObjectByVal(T o) : TAutoObjectDelete(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 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 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 TAutoEnumerator : public TAutoEnumeratorBase { public: TAutoEnumerator() : TAutoEnumeratorBase() {} TAutoEnumerator(const TAutoEnumerator& 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::Value(short& v) { v = Current; } inline void TAutoEnumerator::Value(long& v) { v = Current; } inline void TAutoEnumerator::Value(bool& v) { v = Current; } inline void TAutoEnumerator::Value(TAutoString& v) { v = Current; } inline TAutoEnumerator::operator short() { return (short)Current; } inline TAutoEnumerator::operator long() { return (long)Current; } inline TAutoEnumerator::operator bool() { return (bool)Current; } inline TAutoEnumerator::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 inline TAutoEnumT::TAutoEnumT(TAutoEnumVal* table, int symcount, int type) : TAutoEnum(symcount, type), Table(table) {} // incoming enumeration string localized lookup // template bool TAutoEnumT::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 bool TAutoEnumT::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::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