AcExtensionModule.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2015 Autodesk, Inc. All rights reserved.
  4. //
  5. // Use of this software is subject to the terms of the Autodesk license
  6. // agreement provided at the time of installation or download, or which
  7. // otherwise accompanies this software in either electronic or hard copy form.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // DESCRIPTION
  12. //
  13. // This file provides two useful classes for developers of MFC extensions
  14. // to AutoCAD (ARX applications in particular). There is no source file
  15. // correponding to this file; the classes should be implemented in the DLL
  16. // that includes this file (a task simplified by using the provided macros).
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. #ifndef _AcExtensionModule_h
  20. #define _AcExtensionModule_h
  21. #if _MSC_VER >= 1000
  22. #pragma once
  23. #endif // _MSC_VER >= 1000
  24. #include "acdocman.h"
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CAcExtensionModule - MFC Extension Module and Resource Manager
  27. //
  28. // This class serves two purposes - it provides a placeholder for an
  29. // AFX_EXTENSION_MODULE structure (normally used to initialize or terminate
  30. // an MFC extension DLL) and tracks two resource providers for the DLL.
  31. // The resource providers are the module's resources (normally the DLL
  32. // itself, but may be set to some other module) and the default resources
  33. // (normally the host application, actually the provider currently active
  34. // when AttachInstance() is called). CAcExtensionModule tracks these to
  35. // simplify switching MFC's resource lookup between the default and the
  36. // module's.
  37. // A DLL should create exactly one instance of this class and provide the
  38. // implementation for the class (use the macros included in this file and
  39. // refer to the given example).
  40. class CAcExtensionModule {
  41. public:
  42. CAcExtensionModule ();
  43. ~CAcExtensionModule ();
  44. protected:
  45. BOOL m_bAttached;
  46. HINSTANCE m_hDefaultResource;
  47. HINSTANCE m_hModuleResource;
  48. #ifndef _ADESK_MAC_
  49. AFX_EXTENSION_MODULE m_module;
  50. #endif
  51. public:
  52. BOOL Attached ();
  53. HINSTANCE DefaultResourceInstance ();
  54. HINSTANCE ModuleResourceInstance ();
  55. // Attaches the Extension DLL to MFC and updates the member
  56. // resource handles. Pass hInst as the module's resources.
  57. // Returns TRUE on success and FALSE otherwise.
  58. // On success a corresponding call to DetachInstance() is
  59. // required before the DLL terminates.
  60. BOOL AttachInstance (HINSTANCE hInst);
  61. // Detaches the Extension DLL from MFC.
  62. void DetachInstance ();
  63. };
  64. inline CAcExtensionModule::CAcExtensionModule () :
  65. m_bAttached(FALSE),
  66. m_hDefaultResource(NULL),
  67. m_hModuleResource(NULL)
  68. {
  69. #ifndef _ADESK_MAC_
  70. m_module.bInitialized = FALSE;
  71. m_module.hModule = NULL;
  72. m_module.hResource = NULL;
  73. m_module.pFirstSharedClass = NULL;
  74. m_module.pFirstSharedFactory = NULL;
  75. #endif
  76. }
  77. inline CAcExtensionModule::~CAcExtensionModule ()
  78. {
  79. }
  80. inline BOOL CAcExtensionModule::Attached ()
  81. {
  82. return m_bAttached;
  83. }
  84. inline BOOL CAcExtensionModule::AttachInstance (HINSTANCE hInst)
  85. {
  86. if (m_bAttached)
  87. return FALSE;
  88. #ifndef _ADESK_MAC_
  89. m_bAttached = AfxInitExtensionModule(m_module, hInst);
  90. #else
  91. m_bAttached = true;
  92. #endif
  93. if (m_bAttached) {
  94. m_hDefaultResource = AfxGetResourceHandle();
  95. m_hModuleResource = hInst;
  96. #ifndef _ADESK_MAC_
  97. new CDynLinkLibrary(m_module);
  98. #endif
  99. }
  100. return m_bAttached;
  101. }
  102. inline HINSTANCE CAcExtensionModule::DefaultResourceInstance ()
  103. {
  104. return m_hDefaultResource;
  105. }
  106. inline void CAcExtensionModule::DetachInstance ()
  107. {
  108. if (m_bAttached) {
  109. #ifndef _ADESK_MAC_
  110. AfxTermExtensionModule(m_module);
  111. #endif
  112. m_bAttached = FALSE;
  113. }
  114. }
  115. inline HINSTANCE CAcExtensionModule::ModuleResourceInstance ()
  116. {
  117. return m_hModuleResource;
  118. }
  119. /////////////////////////////////////////////////////////////////////////////
  120. // CAcModuleResourceOverride - Switch between default and module's resources
  121. //
  122. // Use an instance of this class to switch between resource providers. When
  123. // the object is constructed a new resource provider will get switched in.
  124. // Upon destruction the original resource provider will be restored. For
  125. // example:
  126. //
  127. // void MyFunc ()
  128. // {
  129. // CAcModuleResourceOverride myResources;
  130. // .
  131. // .
  132. // }
  133. //
  134. // Upon entry to this function the module's resources will be selected. When
  135. // the function returns the default resources will be restored.
  136. // A resource override can be used in any of three ways:
  137. //
  138. // o Use the default constructor (no arguments) to switch to the module's
  139. // resources. The default resources will be restored by the destructor.
  140. // The module/default resources are those maintained by the DLL's
  141. // CAcExtensionModule.
  142. //
  143. // o Pass NULL (or 0) to the constructor. The DLL's resources will be
  144. // selected and the resources that were in effect will be restored when
  145. // the override object is destroyed.
  146. //
  147. // o Pass a non-NULL handle to the constructor. The associated module's
  148. // resources will be and the resources that were in effect will be
  149. // restored when the override object is destroyed.
  150. class CAcModuleResourceOverride {
  151. public:
  152. CAcModuleResourceOverride ();
  153. CAcModuleResourceOverride (HINSTANCE hInst);
  154. ~CAcModuleResourceOverride ();
  155. private:
  156. static CAcExtensionModule& m_extensionModule;
  157. };
  158. inline CAcModuleResourceOverride::CAcModuleResourceOverride ()
  159. {
  160. acDocManager->pushResourceHandle(m_extensionModule.ModuleResourceInstance());
  161. }
  162. inline CAcModuleResourceOverride::CAcModuleResourceOverride (HINSTANCE hInst)
  163. {
  164. acDocManager->pushResourceHandle(hInst ? hInst :
  165. m_extensionModule.ModuleResourceInstance());
  166. }
  167. inline CAcModuleResourceOverride::~CAcModuleResourceOverride ()
  168. {
  169. acDocManager->popResourceHandle();
  170. }
  171. /////////////////////////////////////////////////////////////////////////////
  172. // Extension Module Decalaration and Implementation Macros
  173. //
  174. // Instatiate an extension module once in a single source file in your DLL
  175. // project. If you want to access the extension module object from other
  176. // source files in your project then use the declaration macro as well
  177. // (usually in an include file). For example, an ARX application's main DLL
  178. // source file might contain:
  179. //
  180. // AC_IMPLEMENT_EXTENSION_MODULE(myDLL)
  181. //
  182. // extern "C" int APIENTRY
  183. // DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  184. // {
  185. // // Remove this if you use lpReserved
  186. // UNREFERENCED_PARAMETER(lpReserved);
  187. //
  188. // if (dwReason == DLL_PROCESS_ATTACH)
  189. // {
  190. // theArxDLL.AttachInstance(hInstance);
  191. // }
  192. // else if (dwReason == DLL_PROCESS_DETACH)
  193. // {
  194. // theArxDLL.DetachInstance();
  195. // }
  196. // return 1; // ok
  197. // }
  198. //
  199. //
  200. // To publicize the extension module in this example to other source files
  201. // add the following to the module's main include file:
  202. //
  203. // AC_DECLARE_EXTENSION_MODULE(myDLL)
  204. #define AC_DECLARE_EXTENSION_MODULE(exm) \
  205. extern CAcExtensionModule exm;
  206. #define AC_IMPLEMENT_EXTENSION_MODULE(exm) \
  207. CAcExtensionModule exm; \
  208. CAcExtensionModule& CAcModuleResourceOverride::m_extensionModule = exm;
  209. /////////////////////////////////////////////////////////////////////////////
  210. //{{AFX_INSERT_LOCATION}}
  211. // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
  212. #endif