home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / MODULE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  9.1 KB  |  384 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\module.cpp
  4. //   Implementation of class TModule.  TModule defines the
  5. //   basic behavior for OWL libraries and applications.
  6. //----------------------------------------------------------------------------
  7. #pragma hdrignore SECTION
  8. #include <owl\owlpch.h>
  9. #include <owl\module.h>
  10.  
  11. extern UINT _OWLDATA GetWindowPtrMsgId;  // in owl.cpp
  12.  
  13.  
  14. #if !defined(SECTION) || SECTION == 1
  15.  
  16. //----------------------------------------------------------------------------
  17.  
  18. //
  19. // implementation of Constructors for a TModule object
  20. //
  21.  
  22. //
  23. // Construct a TModule that is an alias for a DLL. TModule will load & free
  24. // the DLL if shouldLoad is TRUE. If shouldLoad is FALSE, then the HInstance
  25. // must be set some time later using InitModule()
  26. //
  27. TModule::TModule(const char far* name, BOOL shouldLoad)
  28. {
  29.   if (shouldLoad) {
  30.     HInstance = ::LoadLibrary(name);
  31.     if (HInstance <= HINSTANCE(32))
  32.       THROW( TXInvalidModule() );
  33.  
  34.   } else {
  35.     HInstance = 0;
  36.   }
  37.  
  38.   ShouldFree = shouldLoad;
  39.   Name = strnewdup(name);
  40.   lpCmdLine = 0;
  41. }
  42.  
  43. //
  44. // Construct a TModule that is an alias for an already loaded DLL or program
  45. // with an HInstance available. Name is optional & can be 0. No cmdLine is
  46. // setup
  47. //
  48. TModule::TModule(const char far* name, HINSTANCE hInstance)
  49. {
  50.   PRECONDITION(hInstance > HINSTANCE(32));
  51.   HInstance = hInstance;
  52.   ShouldFree = FALSE;
  53.   Name = strnewdup(name);
  54.   lpCmdLine = 0;
  55. }
  56.  
  57. //
  58. // Construct a TModule for an Owl Program via TApplication. InitModule is
  59. // called from here to initialize HInstance & the CmdLine
  60. //
  61. TModule::TModule(const char far* name, HINSTANCE hInstance,
  62.                  const char far* cmdLine)
  63. {
  64.   HInstance = 0;
  65.   ShouldFree = FALSE;
  66.   Name = strnewdup(name);
  67.   lpCmdLine = 0;
  68.   if (hInstance)
  69.     InitModule(hInstance, cmdLine);
  70. }
  71.  
  72. //
  73. // Destruct a TModule, freeing the instance if appropriate, and deleting
  74. // new'd strings
  75. //
  76. TModule::~TModule()
  77. {
  78.   if (ShouldFree)
  79.     ::FreeLibrary(HInstance);
  80.   delete Name;
  81.   delete lpCmdLine;
  82. }
  83.  
  84. void
  85. TModule::SetName(const char far* name)
  86. {
  87.   delete Name;
  88.   Name = strnewdup(name);
  89. }
  90.  
  91. //
  92. // perform initialization of modules cmd line copy, and get proc
  93. // instance handles for the standard procs.
  94. //
  95. void
  96. TModule::InitModule(HINSTANCE hInstance, const char far* cmdLine)
  97. {
  98.   SetInstance(hInstance);
  99.  
  100.   #if defined(__WIN32__)
  101.     //
  102.     // Win32 prepends the full application path to the command line arguments
  103.     // skip over this "extra" argument for 16-bit compatibility
  104.     // _argc and _argv do the correct processing, _argv[0] being the pathname
  105.     //
  106.     if (cmdLine)
  107.       while (*cmdLine && *cmdLine++ != ' ')
  108.         ;
  109.   #endif
  110.  
  111.   if (cmdLine)
  112.     lpCmdLine = strnewdup(cmdLine);
  113.  
  114.   //
  115.   // register a system-wide "GetWindowPtr" message as "OWLxxxx:GetWindowPtr"
  116.   //
  117.   if (!GetWindowPtrMsgId) {
  118.     const char msgName[] = "OWL%X:GetWindowPtr";
  119.     char buff[sizeof(msgName) + 6];
  120.     wsprintf(buff, msgName, OWLVersion);
  121.     GetWindowPtrMsgId = ::RegisterWindowMessage(buff);
  122.   }
  123. }
  124.  
  125. //
  126. // Replaceable exception handler; may be redefined to process OWL exceptions
  127. // if canResume is FALSE, then the user doesn't have the option of ignoring
  128. //
  129. int
  130. TModule::Error(xmsg& x, unsigned captionResId, unsigned promptResId)
  131. {
  132.   char cbuf[80];
  133.   char pbuf[80];
  134.  
  135.   if (!captionResId)
  136.     captionResId = IDS_UNHANDLEDXMSG;
  137.   return HandleGlobalException(x,
  138.     LoadString(captionResId, cbuf, sizeof(cbuf)) ? cbuf : 0,
  139.     promptResId ?
  140.       (LoadString(promptResId, pbuf, sizeof(cbuf)) ? pbuf : "OK to Resume?")
  141.       : 0);
  142. }
  143.  
  144. //
  145. // Set the instance handle for a module that does not yet have one. Cannot
  146. // be called on a module that already has an instance handle.
  147. //
  148. void
  149. TModule::SetInstance(HINSTANCE hInstance)
  150. {
  151.   PRECONDITION(!ShouldFree && !HInstance);
  152.   HInstance = hInstance;
  153. }
  154.  
  155. //
  156. // LoadString replacement which does not generated debug warning output
  157. //
  158. #if defined(__WIN32__)
  159. typedef WCHAR* resText;
  160. #else
  161. typedef char far* resText;
  162. #endif
  163.  
  164. int
  165. TModule::LoadString(UINT id, char far* buf, int bufSize) const
  166. {
  167.   int len = 0;
  168.   HRSRC     resHdl;
  169.   HGLOBAL   glbHdl;
  170.   resText   resData;
  171.   
  172.   if ((resHdl = FindResource(id/16+1, RT_STRING)) != 0
  173.    && (glbHdl = LoadResource(resHdl)) != 0) {
  174.     if ((resData = (resText)LockResource(glbHdl)) != 0) {
  175.       for (int cnt = id % 16; len = *resData++, cnt--; resData += len) ;
  176.       if (len != 0) {
  177.         if (len >= bufSize)
  178.           len = bufSize-1;
  179.         for (cnt = len; len--; *buf++ = (char)*resData++) ;
  180.         *(buf) = 0;
  181.       }
  182.       UnlockResource(glbHdl);
  183.     }
  184.     FreeResource(glbHdl);
  185.     if (len)
  186.       return len;
  187.   }
  188.  
  189.   if (::Module != this)                   // look in OWL module if different
  190.     return ::Module->LoadString(id, buf, bufSize);
  191.  
  192.   if (bufSize)
  193.     *buf = 0;  // make empty string just in case caller doesn't check return
  194.   return 0;    // indicate string not found
  195. }
  196.  
  197.  
  198. //----------------------------------------------------------------------------
  199.  
  200. #include <owl\applicat.h>
  201.  
  202. //
  203. // obsolete error handler--use Error(xmsg&,...) instead
  204. //
  205. void
  206. TModule::Error(int errorCode)
  207. {
  208.   char       errorStr[51];
  209.   TModule*   module = GetApplicationObject();
  210.  
  211.   wsprintf(errorStr,
  212.            "Error received: error code = %d\nOK to proceed?",
  213.            errorCode);
  214.  
  215.   if (::MessageBox(0, errorStr, module ? module->GetName() : Name,
  216.                    MB_ICONSTOP | MB_YESNO | MB_TASKMODAL) == IDNO)
  217.   #if defined(__WIN32__)
  218.     ::PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
  219.   #else
  220.     ::PostAppMessage(GetCurrentTask(), WM_QUIT, 0, 0);
  221.   #endif
  222. }
  223.  
  224. //----------------------------------------------------------------------------
  225. //
  226. // Exception class
  227. //
  228.  
  229. TModule::TXInvalidModule::TXInvalidModule() : TXOwl(IDS_INVALIDMODULE)
  230. {
  231. }
  232.  
  233. TXOwl*
  234. TModule::TXInvalidModule::Clone()
  235. {
  236.   return new TXInvalidModule(*this);
  237. }
  238.  
  239. void
  240. TModule::TXInvalidModule::Throw()
  241. {
  242.   THROW( *this );
  243. }
  244.  
  245. #endif
  246. #if !defined(SECTION) || SECTION == 2
  247.  
  248. //----------------------------------------------------------------------------
  249. // TModule streaming
  250. //
  251.  
  252. IMPLEMENT_STREAMABLE(TModule);
  253.  
  254. void*
  255. TModule::Streamer::Read(ipstream& is, uint32 /*version*/) const
  256. {
  257.   TModule* o = GetObject();
  258.   is >> (TResId&)o->Name;
  259.   is >> (TResId&)o->lpCmdLine;
  260.   is >> o->ShouldFree;
  261.   if (o->ShouldFree)
  262.     o->HInstance = ::LoadLibrary(o->Name);
  263.  
  264.   return o;
  265. }
  266.  
  267. void
  268. TModule::Streamer::Write(opstream& os) const
  269. {
  270.   TModule* o = GetObject();
  271.   os << TResId(o->Name);
  272.   os << TResId(o->lpCmdLine);
  273.   os << o->ShouldFree;
  274. }
  275.  
  276. #endif
  277. #if !defined(SECTION) || SECTION == 3
  278.  
  279. //----------------------------------------------------------------------------
  280. //
  281. // Entry (& exit) functions for Owl in a DLL
  282. //
  283.  
  284. #if defined(__DLL__)
  285.  
  286. //
  287. // TModule derived class to facilitate streaming pointer to the OWL Library
  288. //    the OWL module must be streamed by reference before any pointers to it
  289. // the following code simply prevents writing data back over the OWL module 
  290. //
  291.  
  292. class _OWLCLASS TObjectWindowsLibrary : public TModule {
  293.  public:
  294.   TObjectWindowsLibrary(HINSTANCE hInst) : TModule("ObjectWindowsDLL", hInst){}
  295.   DECLARE_STREAMABLE(_OWLCLASS, TObjectWindowsLibrary, 1);
  296. };
  297.  
  298. IMPLEMENT_STREAMABLE1(TObjectWindowsLibrary, TModule);
  299.  
  300. void*
  301. TObjectWindowsLibrary::Streamer::Read(ipstream&, uint32) const
  302. {
  303.   return GetObject();
  304. }
  305.  
  306. void
  307. TObjectWindowsLibrary::Streamer::Write(opstream&) const
  308. {
  309. }
  310.  
  311. //
  312. // Global pointer to this module
  313. //
  314. TModule* Module = 0;
  315.  
  316. #if defined(__WIN32__)
  317.  
  318. static int  Attaches = 0;  // Win32s doesn't have per-instance data-- keep
  319.                            // track of number of attached processes
  320.  
  321. BOOL WINAPI
  322. DllEntryPoint(HINSTANCE hInstance, DWORD reason, LPVOID)
  323. {
  324.   switch (reason) {
  325.     case DLL_PROCESS_ATTACH: {
  326.       if (!Attaches)
  327.         ::Module = new TObjectWindowsLibrary(hInstance);
  328.       Attaches++;
  329.       break;
  330.     }
  331.     case DLL_PROCESS_DETACH: {
  332.       Attaches--;
  333.       if (!Attaches)
  334.         delete ::Module;
  335.       break;
  336.     }
  337.   }
  338.   return TRUE;
  339. }
  340.  
  341. #else  // !defined(__WIN32__)
  342.  
  343. //
  344. // Construct a TModule on the local heap to represent this Owl DLL
  345. // Leave the heap locked so that we can have far pointers to it.
  346. //
  347. int FAR PASCAL
  348. LibMain(HINSTANCE   hInstance,
  349.         WORD      /*wDataSeg*/,
  350.         WORD      /*cbHeapSize*/,
  351.         char far* /*lpCmdLine*/)
  352. {
  353.   //
  354.   // Allocate the module object for the Owl DLL. The RTL makes sure that
  355.   // the memory allocated is GMEM_SHARE.
  356.   //
  357.   ::Module = new TObjectWindowsLibrary(hInstance);
  358.  
  359.   return Module->Status == 0;
  360. }
  361.  
  362. int
  363. FAR PASCAL
  364. WEP(int /*bSystemExit*/)
  365. {
  366.   delete ::Module;
  367.   return 1;
  368. }
  369.  
  370. #endif  // defined(__WIN32__)
  371. #endif  // defined(__DLL__)
  372. #endif  // SECTION == 3
  373.  
  374. #if !defined(SECTION) || SECTION == 4
  375. //
  376. // Inserter for formated output of instance handle
  377. //
  378. ostream& _OWLFUNC
  379. operator <<(ostream& os, const TModule& m)
  380. {
  381.   return os << hex << UINT(m.HInstance);
  382. }
  383. #endif //section 4
  384.