//---------------------------------------------------------------------------- // 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 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 void TOleFactoryNoAuto::AutomateApp(T* /*app*/, uint32){} template TUnknown* TOleFactoryNoAuto::AutomateObject(T*, const void*,const typeinfo&){return 0;} template void TOleFactoryNoAuto::UnregisterAutomation(T* /*app*/){} //____________________________________________________________________________ // // Automated application default automation callout implementation template 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 TUnknown* TOleFactoryAuto::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 void TOleFactoryAuto::UnregisterAutomation(T* app) { ::Registrar->ReleaseAutoApp(TAutoObject(app)); } // // Default callout to aggregate an automation helper to an automated app // template void TOleFactoryAuto::AutomateApp(T* app, uint32 options) { ::Registrar->CreateAutoApp(TAutoObjectDelete(app), options); } //____________________________________________________________________________ // // Application creation/destruction callouts shared for doc/view and non-d/v // template struct TOleFactoryAppBase { static T* CreateApp(uint32 options); static void DestroyApp(T* app); }; template T* TOleFactoryAppBase::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 void TOleFactoryAppBase::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 struct TOleFactoryNoDocView : TOleFactoryAppBase { static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link); }; template TUnknown* TOleFactoryNoDocView::CreateObject(T* app, uint32 options, TRegLink* link) { return app->CreateOleObject(options, link); } //____________________________________________________________________________ // // Docview application callout implementation - supplies CreateObject function template struct TOleFactoryDocView : TOleFactoryAppBase { static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link); }; template TUnknown* TOleFactoryDocView::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(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(view); // get address of derived most void* docObj = dynamic_cast(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 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 IUnknown* TOleFactoryBase::Create(IUnknown* outer, uint32 options, uint32 id) { TRegLink* link = reinterpret_cast(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 TOleFactory : public TOleFactoryBase > >{}; // Factory for OWL Doc/View, non-automated OLE components // template class TOleDocViewFactory : public TOleFactoryBase > > {}; // Factory for OWL non-Doc/View, automated OLE components // template class TOleAutoFactory : public TOleFactoryBase > > {}; // Factory for OWL Doc/View, automated OLE components // template class TOleDocViewAutoFactory : public TOleFactoryBase > > {}; //____________________________________________________________________________ // // Factory for OWL automated OLE components, no linking/embedding support // // template 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 T* TAutoFactory::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 void TAutoFactory::DestroyApp(T* app) { delete app; } // // Main Create callback function called to create app // template IUnknown* TAutoFactory::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(app), options, outer); ifc = *obj; // does an AddRef, reference count owned by container } if (options & amRun) { app->Run(); } return ifc; } #endif // OWL_OLEFACTO_H