home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OWLINC.PAK / OLEFACTO.H < prev    next >
C/C++ Source or Header  |  1995-08-29  |  10KB  |  316 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1994 by Borland International, All Rights Reserved
  4. //
  5. //----------------------------------------------------------------------------
  6. #if !defined(OWL_OLEFACTO_H)
  7. #define OWL_OLEFACTO_H
  8.  
  9. // Templatized class implementation of OLE component creation code for
  10. // TComponentFactory callback for ObjectWindows applications
  11. // All templates assume an AppDictionary global and a Registrar global
  12. // User can provide alternate implementation for any or all of the functions
  13. // The user's derived TApplication class is passed as the template parameter
  14. //____________________________________________________________________________
  15. //
  16. // Non-automated application automation callout stub implementation
  17.  
  18. template <class T> struct TOleFactoryNoAuto {
  19.   static void      AutomateApp(T* app, uint32 options);
  20.   static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
  21.   static void      UnregisterAutomation(T* app);
  22. };
  23.  
  24. template<class T> void
  25. TOleFactoryNoAuto<T>::AutomateApp(T* /*app*/, uint32){}
  26.  
  27. template<class T> TUnknown*
  28. TOleFactoryNoAuto<T>::AutomateObject(T*, const void*,const typeinfo&){return 0;}
  29.  
  30. template<class T> void
  31. TOleFactoryNoAuto<T>::UnregisterAutomation(T* /*app*/){}
  32.  
  33. //____________________________________________________________________________
  34. //
  35. // Automated application default automation callout implementation
  36.  
  37. template <class T> struct TOleFactoryAuto {
  38.   static void      AutomateApp(T* app, uint32 options);
  39.   static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
  40.   static void      UnregisterAutomation(T* app);
  41. };
  42.  
  43. //
  44. // Default callout to aggregate an automation helper to an automated object
  45. //
  46. template <class T> TUnknown*
  47. TOleFactoryAuto<T>::AutomateObject(T* app,const void* obj,const typeinfo& info)
  48. {
  49.   return ::Registrar->CreateAutoObject(obj, info, app, typeid(*app));
  50. }
  51.  
  52. //
  53. // Default callout to unregister automation active object
  54. //
  55. template <class T> void
  56. TOleFactoryAuto<T>::UnregisterAutomation(T* app)
  57. {
  58.   ::Registrar->ReleaseAutoApp(TAutoObject<T>(app));
  59. }
  60.  
  61. //
  62. // Default callout to aggregate an automation helper to an automated app
  63. //
  64. template <class T> void
  65. TOleFactoryAuto<T>::AutomateApp(T* app, uint32 options)
  66. {
  67.   ::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app), options);
  68. }
  69.  
  70. //____________________________________________________________________________
  71. //
  72. // Application creation/destruction callouts shared for doc/view and non-d/v
  73. //
  74. template<class T, class Auto> struct TOleFactoryAppBase {
  75.   static T*        CreateApp(uint32 options);
  76.   static void      DestroyApp(T* app);
  77. };
  78.  
  79. template<class T, class Auto> T*
  80. TOleFactoryAppBase<T, Auto>::CreateApp(uint32 options)
  81. {
  82.   T* app = new T;
  83.   if ((options & amEmbedding) || !(options & amExeMode))
  84.     app->nCmdShow = SW_HIDE;
  85.   app->OcInit(*::Registrar, options);
  86.   Auto::AutomateApp(app, options);
  87.   app->Start();
  88.   return app;
  89. }
  90.  
  91. template<class T, class Auto>
  92. void TOleFactoryAppBase<T, Auto>::DestroyApp(T* app)
  93. {
  94.   Auto::UnregisterAutomation(app);
  95.   delete app;
  96. }
  97.  
  98. //____________________________________________________________________________
  99. //
  100. // Non-docview application callout implementation, no CreateObject implemented
  101. // User must either provide an implementation of CreateOleObject for app class
  102. // or else reimplement this template function for the particular class
  103.  
  104. template<class T, class Auto> struct TOleFactoryNoDocView 
  105.                                    : TOleFactoryAppBase<T, Auto> {
  106.   static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
  107. };
  108.  
  109. template <class T, class Auto> TUnknown*
  110. TOleFactoryNoDocView<T, Auto>::CreateObject(T* app, uint32 options,
  111.                                             TRegLink* link)
  112. {
  113.   return app->CreateOleObject(options, link);
  114. }
  115.  
  116. //____________________________________________________________________________
  117. //
  118. // Docview application callout implementation - supplies CreateObject function
  119.  
  120. template <class T, class Auto> struct TOleFactoryDocView
  121.                                     : TOleFactoryAppBase<T, Auto> {
  122.   static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
  123. };
  124.  
  125. template <class T, class Auto> TUnknown*
  126. TOleFactoryDocView<T, Auto>::CreateObject(T* app, uint32 options, TRegLink* link)
  127. {
  128.   TUnknown* obj = 0;
  129.   if (!link)      // if not coming up embedded, we don't know what to make here
  130.     return 0;
  131.   TDocManager* docMan = app->GetDocManager();
  132.   if (!docMan)
  133.     return 0;
  134.   TDocTemplate* tpl = static_cast<TDocTemplate*>(link);
  135.   TDocument* doc = docMan->CreateDoc(tpl, 0, 0, dtNewDoc | dtNoAutoView);
  136.   TView* view = tpl->ConstructView(*doc);
  137.   TOleWindow* ow = TYPESAFE_DOWNCAST(view, TOleWindow);
  138.   if (ow) {
  139.     obj = ow->CreateOcView(tpl, (options & amEmbedding) != 0, 0);
  140.     TUnknown* autoObj;
  141.     void* viewObj = dynamic_cast<void*>(view); // get address of derived most
  142.     void* docObj = dynamic_cast<void*>(doc);
  143.     if ((autoObj = Auto::AutomateObject(app, viewObj, typeid(*view))) != 0 ||
  144.         (autoObj = Auto::AutomateObject(app, docObj,  typeid(*doc)))  != 0) {
  145.       obj->SetOuter(&autoObj->Aggregate(*obj));
  146.       obj->AdjustRefCount(-1);  // remove extra ref count
  147.       obj = autoObj;
  148.       obj->AdjustRefCount(+1);  // add it back to the new outer sub-object
  149.     }
  150.   }
  151.   doc->InitView(view);
  152.   return (options & amEmbedding) ? obj : 0;
  153. }
  154.  
  155. //____________________________________________________________________________
  156. //
  157. //  Standard factory for OWL components, callouts supplied via template args
  158. //
  159. template <class T, class Obj> class TOleFactoryBase {
  160.   public:
  161.     operator TComponentFactory() {return Create;}
  162.  
  163.     static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
  164. };
  165.  
  166. //
  167. // Main Create callback function called to create app and/or object
  168. //
  169. template <class T, class Obj> IUnknown*
  170. TOleFactoryBase<T, Obj>::Create(IUnknown* outer, uint32 options, uint32 id)
  171. {
  172.   TRegLink* link = reinterpret_cast<TRegLink*>(id);
  173.  
  174.   // Look for the app object for this process, creating one if necessary
  175.   //
  176.   TApplication* existingApp = ::AppDictionary.GetApplication();
  177.   T* app;
  178.   if (!existingApp) {
  179.     if (options & amShutdown)   // app already destructed
  180.       return 0;
  181.     app = Obj::CreateApp(options);
  182.     if (!link && !(options & amEmbedding)) {
  183.       Obj::CreateObject(app, options, link);
  184.     }
  185.   } else {
  186.     app = TYPESAFE_DOWNCAST(existingApp, T);
  187.     if (options & amShutdown) {
  188.       Obj::DestroyApp(app);
  189.       return 0;  // any interface present when passed in has now been released
  190.     }
  191.   }
  192.   TUnknown* obj = app->OcApp;   // app's COM interface, used if not doc object
  193.  
  194.   // If a component ID was passed, make that component, otherwise return app
  195.   //
  196.   if (link) {
  197.     TUnknown* doc = Obj::CreateObject(app, options, link);
  198.     if (doc)
  199.       obj = doc;
  200.     else if (!(options & amEmbedding))  // run DLL in ExeMode from doc factory
  201.       app->OcApp->SetOption(amServedApp, true);
  202.     else
  203.       return 0;  // doc factory failed
  204.   }
  205.   IUnknown* ifc = obj ? obj->SetOuter(outer) : 0; // aggregate to passed outer
  206.  
  207.   // Run message look if ExeMode, either EXE server or DLL server force to run
  208.   // EXE servers come through here twice, no Run if 2nd pass from factory call
  209.   //
  210.   if (options & amRun)
  211.     app->Run();
  212.  
  213.   return ifc;
  214. }
  215.  
  216. //____________________________________________________________________________
  217. //
  218. //  Factory for OWL non-Doc/View, non-automated OLE components
  219. //
  220. template <class T> class TOleFactory
  221. : public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryNoAuto<T> > >{};
  222.  
  223. //  Factory for OWL Doc/View, non-automated OLE components
  224. //
  225. template <class T> class TOleDocViewFactory
  226. : public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryNoAuto<T> > > {};
  227.  
  228. //  Factory for OWL non-Doc/View, automated OLE components
  229. //
  230. template <class T> class TOleAutoFactory
  231. : public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryAuto<T> > > {};
  232.  
  233. //  Factory for OWL Doc/View, automated OLE components
  234. //
  235. template <class T> class TOleDocViewAutoFactory
  236. : public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryAuto<T> > > {};
  237.  
  238. //____________________________________________________________________________
  239. //
  240. //  Factory for OWL automated OLE components, no linking/embedding support
  241. //
  242. //
  243. template <class T> class TAutoFactory {
  244.   public:
  245.     operator TComponentFactory() {return Create;}
  246.  
  247.     // Callouts to allow replacement of individual creation steps
  248.     //
  249.     static T*        CreateApp(uint32 options);
  250.     static void      DestroyApp(T* app);
  251.  
  252.     // Main Create callback function called to create app and/or object
  253.     //
  254.     static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
  255. };
  256.  
  257. //
  258. // Called when the app is not found and needs to be created
  259. //
  260. template <class T> T*
  261. TAutoFactory<T>::CreateApp(uint32 options)
  262. {
  263.   T* app = new T;
  264.   if ((options & amEmbedding) || !(options & amExeMode))
  265.     app->nCmdShow = SW_HIDE;
  266.   app->Start();
  267.   return app;
  268. }
  269.  
  270. //
  271. // Called to destroy the application previously created
  272. //
  273. template <class T> void
  274. TAutoFactory<T>::DestroyApp(T* app)
  275. {
  276.   delete app;
  277. }
  278.  
  279. //
  280. // Main Create callback function called to create app
  281. //
  282. template <class T> IUnknown*
  283. TAutoFactory<T>::Create(IUnknown* outer, uint32 options, uint32 /*id*/)
  284. {
  285.   IUnknown* ifc = 0;
  286.   TApplication* existingApp = ::AppDictionary.GetApplication();
  287.   T* app;
  288.   if (!existingApp) {
  289.     if (options & amShutdown)   // app already destructed
  290.       return 0;
  291.     app = CreateApp(options);
  292.   }
  293.   else {
  294.     app = TYPESAFE_DOWNCAST(existingApp, T);
  295.     if (options & amShutdown) {
  296.       DestroyApp(app);
  297.       return (options & amServedApp) ? 0 : outer;
  298.     }
  299.   }
  300.  
  301.   if (options & amServedApp) {
  302.     TUnknown* obj = ::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app),
  303.                                                options, outer);
  304.     ifc = *obj;  // does an AddRef, reference count owned by container
  305.   }
  306.  
  307.   if (options & amRun) {
  308.     app->Run();
  309.   }
  310.   return ifc;
  311. }
  312.  
  313.  
  314. #endif  // OWL_OLEFACTO_H
  315.  
  316.