- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
316 lines
10 KiB
C++
316 lines
10 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows
|
|
// (C) Copyright 1994 by Borland International, All Rights Reserved
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#if !defined(OWL_OLEFACTO_H)
|
|
#define OWL_OLEFACTO_H
|
|
|
|
// Templatized class implementation of OLE component creation code for
|
|
// TComponentFactory callback for ObjectWindows applications
|
|
// All templates assume an AppDictionary global and a Registrar global
|
|
// User can provide alternate implementation for any or all of the functions
|
|
// The user's derived TApplication class is passed as the template parameter
|
|
//____________________________________________________________________________
|
|
//
|
|
// Non-automated application automation callout stub implementation
|
|
|
|
template <class T> struct TOleFactoryNoAuto {
|
|
static void AutomateApp(T* app, uint32 options);
|
|
static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
|
|
static void UnregisterAutomation(T* app);
|
|
};
|
|
|
|
template<class T> void
|
|
TOleFactoryNoAuto<T>::AutomateApp(T* /*app*/, uint32){}
|
|
|
|
template<class T> TUnknown*
|
|
TOleFactoryNoAuto<T>::AutomateObject(T*, const void*,const typeinfo&){return 0;}
|
|
|
|
template<class T> void
|
|
TOleFactoryNoAuto<T>::UnregisterAutomation(T* /*app*/){}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Automated application default automation callout implementation
|
|
|
|
template <class T> struct TOleFactoryAuto {
|
|
static void AutomateApp(T* app, uint32 options);
|
|
static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
|
|
static void UnregisterAutomation(T* app);
|
|
};
|
|
|
|
//
|
|
// Default callout to aggregate an automation helper to an automated object
|
|
//
|
|
template <class T> TUnknown*
|
|
TOleFactoryAuto<T>::AutomateObject(T* app,const void* obj,const typeinfo& info)
|
|
{
|
|
return ::Registrar->CreateAutoObject(obj, info, app, typeid(*app));
|
|
}
|
|
|
|
//
|
|
// Default callout to unregister automation active object
|
|
//
|
|
template <class T> void
|
|
TOleFactoryAuto<T>::UnregisterAutomation(T* app)
|
|
{
|
|
::Registrar->ReleaseAutoApp(TAutoObject<T>(app));
|
|
}
|
|
|
|
//
|
|
// Default callout to aggregate an automation helper to an automated app
|
|
//
|
|
template <class T> void
|
|
TOleFactoryAuto<T>::AutomateApp(T* app, uint32 options)
|
|
{
|
|
::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app), options);
|
|
}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Application creation/destruction callouts shared for doc/view and non-d/v
|
|
//
|
|
template<class T, class Auto> struct TOleFactoryAppBase {
|
|
static T* CreateApp(uint32 options);
|
|
static void DestroyApp(T* app);
|
|
};
|
|
|
|
template<class T, class Auto> T*
|
|
TOleFactoryAppBase<T, Auto>::CreateApp(uint32 options)
|
|
{
|
|
T* app = new T;
|
|
if ((options & amEmbedding) || !(options & amExeMode))
|
|
app->nCmdShow = SW_HIDE;
|
|
app->OcInit(*::Registrar, options);
|
|
Auto::AutomateApp(app, options);
|
|
app->Start();
|
|
return app;
|
|
}
|
|
|
|
template<class T, class Auto>
|
|
void TOleFactoryAppBase<T, Auto>::DestroyApp(T* app)
|
|
{
|
|
Auto::UnregisterAutomation(app);
|
|
delete app;
|
|
}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Non-docview application callout implementation, no CreateObject implemented
|
|
// User must either provide an implementation of CreateOleObject for app class
|
|
// or else reimplement this template function for the particular class
|
|
|
|
template<class T, class Auto> struct TOleFactoryNoDocView
|
|
: TOleFactoryAppBase<T, Auto> {
|
|
static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
|
|
};
|
|
|
|
template <class T, class Auto> TUnknown*
|
|
TOleFactoryNoDocView<T, Auto>::CreateObject(T* app, uint32 options,
|
|
TRegLink* link)
|
|
{
|
|
return app->CreateOleObject(options, link);
|
|
}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Docview application callout implementation - supplies CreateObject function
|
|
|
|
template <class T, class Auto> struct TOleFactoryDocView
|
|
: TOleFactoryAppBase<T, Auto> {
|
|
static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
|
|
};
|
|
|
|
template <class T, class Auto> TUnknown*
|
|
TOleFactoryDocView<T, Auto>::CreateObject(T* app, uint32 options, TRegLink* link)
|
|
{
|
|
TUnknown* obj = 0;
|
|
if (!link) // if not coming up embedded, we don't know what to make here
|
|
return 0;
|
|
TDocManager* docMan = app->GetDocManager();
|
|
if (!docMan)
|
|
return 0;
|
|
TDocTemplate* tpl = static_cast<TDocTemplate*>(link);
|
|
TDocument* doc = docMan->CreateDoc(tpl, 0, 0, dtNewDoc | dtNoAutoView);
|
|
TView* view = tpl->ConstructView(*doc);
|
|
TOleWindow* ow = TYPESAFE_DOWNCAST(view, TOleWindow);
|
|
if (ow) {
|
|
obj = ow->CreateOcView(tpl, (options & amEmbedding) != 0, 0);
|
|
TUnknown* autoObj;
|
|
void* viewObj = dynamic_cast<void*>(view); // get address of derived most
|
|
void* docObj = dynamic_cast<void*>(doc);
|
|
if ((autoObj = Auto::AutomateObject(app, viewObj, typeid(*view))) != 0 ||
|
|
(autoObj = Auto::AutomateObject(app, docObj, typeid(*doc))) != 0) {
|
|
obj->SetOuter(&autoObj->Aggregate(*obj));
|
|
obj->AdjustRefCount(-1); // remove extra ref count
|
|
obj = autoObj;
|
|
obj->AdjustRefCount(+1); // add it back to the new outer sub-object
|
|
}
|
|
}
|
|
doc->InitView(view);
|
|
return (options & amEmbedding) ? obj : 0;
|
|
}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Standard factory for OWL components, callouts supplied via template args
|
|
//
|
|
template <class T, class Obj> class TOleFactoryBase {
|
|
public:
|
|
operator TComponentFactory() {return Create;}
|
|
|
|
static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
|
|
};
|
|
|
|
//
|
|
// Main Create callback function called to create app and/or object
|
|
//
|
|
template <class T, class Obj> IUnknown*
|
|
TOleFactoryBase<T, Obj>::Create(IUnknown* outer, uint32 options, uint32 id)
|
|
{
|
|
TRegLink* link = reinterpret_cast<TRegLink*>(id);
|
|
|
|
// Look for the app object for this process, creating one if necessary
|
|
//
|
|
TApplication* existingApp = ::AppDictionary.GetApplication();
|
|
T* app;
|
|
if (!existingApp) {
|
|
if (options & amShutdown) // app already destructed
|
|
return 0;
|
|
app = Obj::CreateApp(options);
|
|
if (!link && !(options & amEmbedding)) {
|
|
Obj::CreateObject(app, options, link);
|
|
}
|
|
} else {
|
|
app = TYPESAFE_DOWNCAST(existingApp, T);
|
|
if (options & amShutdown) {
|
|
Obj::DestroyApp(app);
|
|
return 0; // any interface present when passed in has now been released
|
|
}
|
|
}
|
|
TUnknown* obj = app->OcApp; // app's COM interface, used if not doc object
|
|
|
|
// If a component ID was passed, make that component, otherwise return app
|
|
//
|
|
if (link) {
|
|
TUnknown* doc = Obj::CreateObject(app, options, link);
|
|
if (doc)
|
|
obj = doc;
|
|
else if (!(options & amEmbedding)) // run DLL in ExeMode from doc factory
|
|
app->OcApp->SetOption(amServedApp, true);
|
|
else
|
|
return 0; // doc factory failed
|
|
}
|
|
IUnknown* ifc = obj ? obj->SetOuter(outer) : 0; // aggregate to passed outer
|
|
|
|
// Run message look if ExeMode, either EXE server or DLL server force to run
|
|
// EXE servers come through here twice, no Run if 2nd pass from factory call
|
|
//
|
|
if (options & amRun)
|
|
app->Run();
|
|
|
|
return ifc;
|
|
}
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Factory for OWL non-Doc/View, non-automated OLE components
|
|
//
|
|
template <class T> class TOleFactory
|
|
: public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryNoAuto<T> > >{};
|
|
|
|
// Factory for OWL Doc/View, non-automated OLE components
|
|
//
|
|
template <class T> class TOleDocViewFactory
|
|
: public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryNoAuto<T> > > {};
|
|
|
|
// Factory for OWL non-Doc/View, automated OLE components
|
|
//
|
|
template <class T> class TOleAutoFactory
|
|
: public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryAuto<T> > > {};
|
|
|
|
// Factory for OWL Doc/View, automated OLE components
|
|
//
|
|
template <class T> class TOleDocViewAutoFactory
|
|
: public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryAuto<T> > > {};
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Factory for OWL automated OLE components, no linking/embedding support
|
|
//
|
|
//
|
|
template <class T> class TAutoFactory {
|
|
public:
|
|
operator TComponentFactory() {return Create;}
|
|
|
|
// Callouts to allow replacement of individual creation steps
|
|
//
|
|
static T* CreateApp(uint32 options);
|
|
static void DestroyApp(T* app);
|
|
|
|
// Main Create callback function called to create app and/or object
|
|
//
|
|
static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
|
|
};
|
|
|
|
//
|
|
// Called when the app is not found and needs to be created
|
|
//
|
|
template <class T> T*
|
|
TAutoFactory<T>::CreateApp(uint32 options)
|
|
{
|
|
T* app = new T;
|
|
if ((options & amEmbedding) || !(options & amExeMode))
|
|
app->nCmdShow = SW_HIDE;
|
|
app->Start();
|
|
return app;
|
|
}
|
|
|
|
//
|
|
// Called to destroy the application previously created
|
|
//
|
|
template <class T> void
|
|
TAutoFactory<T>::DestroyApp(T* app)
|
|
{
|
|
delete app;
|
|
}
|
|
|
|
//
|
|
// Main Create callback function called to create app
|
|
//
|
|
template <class T> IUnknown*
|
|
TAutoFactory<T>::Create(IUnknown* outer, uint32 options, uint32 /*id*/)
|
|
{
|
|
IUnknown* ifc = 0;
|
|
TApplication* existingApp = ::AppDictionary.GetApplication();
|
|
T* app;
|
|
if (!existingApp) {
|
|
if (options & amShutdown) // app already destructed
|
|
return 0;
|
|
app = CreateApp(options);
|
|
}
|
|
else {
|
|
app = TYPESAFE_DOWNCAST(existingApp, T);
|
|
if (options & amShutdown) {
|
|
DestroyApp(app);
|
|
return (options & amServedApp) ? 0 : outer;
|
|
}
|
|
}
|
|
|
|
if (options & amServedApp) {
|
|
TUnknown* obj = ::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app),
|
|
options, outer);
|
|
ifc = *obj; // does an AddRef, reference count owned by container
|
|
}
|
|
|
|
if (options & amRun) {
|
|
app->Run();
|
|
}
|
|
return ifc;
|
|
}
|
|
|
|
|
|
#endif // OWL_OLEFACTO_H
|
|
|