home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows
- // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
- //
- // Implementation of class TModule. TModule defines the
- // basic behavior for OWL libraries and applications.
- //----------------------------------------------------------------------------
- #pragma hdrignore SECTION
- #include <owl/owlpch.h>
- #include <owl/module.h>
- #include <owl/appdict.h>
-
- extern uint _OWLDATA GetWindowPtrMsgId; // in applicat.cpp
-
-
- #if !defined(SECTION) || SECTION == 1
-
- //----------------------------------------------------------------------------
-
- //
- // implementation of Constructors for a TModule object
- //
-
- //
- // Construct a TModule that is an alias for a DLL. TModule will load & free
- // the DLL if shouldLoad is true. If shouldLoad is false, then the HInstance
- // must be set some time later using InitModule()
- //
- TModule::TModule(const char far* name, bool shouldLoad)
- {
- if (shouldLoad) {
- HInstance = ::LoadLibrary(name);
- if (HInstance <= HINSTANCE(32))
- THROW( TXInvalidModule() );
- }
- else {
- HInstance = 0;
- }
-
- ShouldFree = shouldLoad;
- Name = strnewdup(name);
- lpCmdLine = 0;
- }
-
- //
- // Construct a TModule that is an alias for an already loaded DLL or program
- // with an HInstance available. Name is optional & can be 0. No cmdLine is
- // setup
- //
- TModule::TModule(const char far* name, HINSTANCE hInstance)
- {
- PRECONDITION(hInstance > HINSTANCE(32));
- HInstance = hInstance;
- ShouldFree = false;
- Name = strnewdup(name);
- lpCmdLine = 0;
- }
-
- //
- // Construct a TModule for an Owl Program via TApplication. InitModule is
- // called from here to initialize HInstance & the CmdLine
- //
- TModule::TModule(const char far* name, HINSTANCE hInstance,
- const char far* cmdLine)
- {
- HInstance = 0;
- ShouldFree = false;
- Name = strnewdup(name);
- lpCmdLine = 0;
- if (hInstance)
- InitModule(hInstance, cmdLine);
- }
-
- //
- // Destruct a TModule, freeing the instance if appropriate, and deleting
- // new'd strings
- //
- TModule::~TModule()
- {
- if (ShouldFree)
- ::FreeLibrary(HInstance);
- delete [] Name;
- delete [] lpCmdLine;
- }
-
- void
- TModule::SetName(const char far* name)
- {
- delete [] Name;
- Name = strnewdup(name);
- }
-
- //
- // perform initialization of modules cmd line copy, and get proc
- // instance handles for the standard procs.
- //
- void
- TModule::InitModule(HINSTANCE hInstance, const char far* cmdLine)
- {
- SetInstance(hInstance);
-
- #if defined(BI_PLAT_WIN32)
- //
- // Win32 prepends the full application path to the command line arguments
- // skip over this "extra" argument for 16-bit compatibility
- // _argc and _argv do the correct processing, _argv[0] being the pathname
- //
- if (cmdLine)
- while (*cmdLine && *cmdLine++ != ' ')
- ;
- #endif
-
- if (cmdLine)
- lpCmdLine = strnewdup(cmdLine);
-
- // Register a system-wide "GetWindowPtr" message as "GetWindowPtr(_hInstance)"
- // Each running copy of ObjectWindows will get a unique message Id
- //
- if (!GetWindowPtrMsgId) {
- const char msgTemplate[] = "GetWindowPtr(%X)";
- char msgName[sizeof(msgTemplate) + 8];
- wsprintf(msgName, msgTemplate, unsigned(_hInstance));
- GetWindowPtrMsgId = ::RegisterWindowMessage(msgName);
- CHECK(GetWindowPtrMsgId);
- }
- }
-
- //
- // Replaceable exception handler; may be redefined to process OWL exceptions
- // if canResume is false, then the user doesn't have the option of ignoring
- //
- int
- TModule::Error(xmsg& x, unsigned captionResId, unsigned promptResId)
- {
- char cbuf[80];
- char pbuf[80];
-
- if (!captionResId)
- captionResId = IDS_UNHANDLEDXMSG;
- return HandleGlobalException(x,
- LoadString(captionResId, cbuf, sizeof(cbuf)) ? cbuf : 0,
- promptResId ?
- (LoadString(promptResId, pbuf, sizeof(cbuf)) ? pbuf : "OK to Resume?")
- : 0);
- }
-
- //
- // Set the instance handle for a module that does not yet have one. Cannot
- // be called on a module that already has an instance handle.
- //
- void
- TModule::SetInstance(HINSTANCE hInstance)
- {
- PRECONDITION(!ShouldFree && !HInstance);
- HInstance = hInstance;
- }
-
- //
- // LoadString replacements which do not generated debug warning output
- //
- #if defined(BI_PLAT_WIN32)
- typedef WCHAR* TResText;
- typedef WCHAR* TResCount;
- #else
- typedef char far* TResText;
- typedef uint8 far* TResCount;
- #endif
-
- int
- TModule::LoadString(uint id, char far* buf, int bufSize) const
- {
- uint len = 0;
- HRSRC resHdl;
- HGLOBAL glbHdl;
- TResText resData;
-
- if ((resHdl = FindResource(id/16+1, RT_STRING)) != 0
- && (glbHdl = LoadResource(resHdl)) != 0) {
- if ((resData = (TResText)LockResource(glbHdl)) != 0) {
- for (int cnt = id % 16; len = *(TResCount)resData++, cnt--; resData += len)
- ;
- if (len != 0) {
- if (len >= bufSize)
- len = bufSize-1;
- for (cnt = len; cnt--; *buf++ = (char)*resData++)
- ;
- *buf = 0;
- }
- UnlockResource(glbHdl);
- }
- FreeResource(glbHdl);
- if (len)
- return len;
- }
-
- if (::Module != this) // look in OWL module if different
- return ::Module->LoadString(id, buf, bufSize);
-
- if (bufSize)
- *buf = 0; // make empty string just in case caller doesn't check return
- return 0; // indicate string not found
- }
-
- string
- TModule::LoadString(uint id) const
- {
- uint len = 0;
- HRSRC resHdl;
- HGLOBAL glbHdl;
- TResText resData;
- string retString;
-
- if ((resHdl = FindResource(id/16+1, RT_STRING)) != 0
- && (glbHdl = LoadResource(resHdl)) != 0) {
- if ((resData = (TResText)LockResource(glbHdl)) != 0) {
- for (int cnt = id % 16; len = *(TResCount)resData++, cnt--; resData += len)
- ;
- if (len != 0) {
- #if (0) // This is dangerous unless string is changed to handle non-terminated
- // char arrays
- //
- retString.append(resData, 0, len);
- #else
- retString.resize(len);
- int i = 0;
- for (cnt = len; cnt--; retString[i++] = (char)*resData++)
- ;
- #endif
- }
- UnlockResource(glbHdl);
- }
- FreeResource(glbHdl);
- if (len)
- return retString;
- }
-
- if (::Module != this) // look in OWL module if different
- return ::Module->LoadString(id);
-
- return retString; // empty if string not found
- }
-
- //----------------------------------------------------------------------------
-
- #include <owl/applicat.h>
-
- //
- // obsolete error handler--use Error(xmsg&,...) instead
- //
- void
- TModule::Error(int errorCode)
- {
- char errorStr[51];
- TModule* module = GetApplicationObject();
-
- wsprintf(errorStr,
- "Error received: error code = %d\nOK to proceed?",
- errorCode);
-
- if (::MessageBox(0, errorStr, module ? module->GetName() : Name,
- MB_ICONSTOP | MB_YESNO | MB_TASKMODAL) == IDNO)
- #if defined(BI_PLAT_WIN32)
- ::PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
- #else
- ::PostAppMessage(GetCurrentTask(), WM_QUIT, 0, 0);
- #endif
- }
-
- //----------------------------------------------------------------------------
- //
- // Exception class
- //
-
- TModule::TXInvalidModule::TXInvalidModule() : TXOwl(IDS_INVALIDMODULE)
- {
- }
-
- TXOwl*
- TModule::TXInvalidModule::Clone()
- {
- return new TXInvalidModule(*this);
- }
-
- void
- TModule::TXInvalidModule::Throw()
- {
- THROW( *this );
- }
-
- #endif
- #if !defined(SECTION) || SECTION == 2
-
- //----------------------------------------------------------------------------
- // TModule streaming
- //
-
- IMPLEMENT_STREAMABLE(TModule);
-
- void*
- TModule::Streamer::Read(ipstream& is, uint32 /*version*/) const
- {
- TModule* o = GetObject();
- is >> (TResId&)o->Name;
- is >> (TResId&)o->lpCmdLine;
- is >> o->ShouldFree;
- if (o->ShouldFree)
- o->HInstance = ::LoadLibrary(o->Name);
-
- return o;
- }
-
- void
- TModule::Streamer::Write(opstream& os) const
- {
- TModule* o = GetObject();
- os << TResId(o->Name);
- os << TResId(o->lpCmdLine);
- os << o->ShouldFree;
- }
-
- #endif
- #if !defined(SECTION) || SECTION == 3
-
- //----------------------------------------------------------------------------
- //
- // Entry (& exit) functions for Owl in a DLL
- //
-
- #if defined(_BUILDOWLDLL)
-
- //
- // TModule derived class to facilitate streaming pointer to the OWL Library
- // the OWL module must be streamed by reference before any pointers to it
- // the following code simply prevents writing data back over the OWL module
- //
-
- class _OWLCLASS TObjectWindowsLibrary : public TModule {
- public:
- TObjectWindowsLibrary(HINSTANCE hInst) : TModule("ObjectWindowsDLL", hInst){}
- DECLARE_STREAMABLE(_OWLCLASS, TObjectWindowsLibrary, 1);
- };
-
- IMPLEMENT_STREAMABLE1(TObjectWindowsLibrary, TModule);
-
- void*
- TObjectWindowsLibrary::Streamer::Read(ipstream&, uint32) const
- {
- return GetObject();
- }
-
- void
- TObjectWindowsLibrary::Streamer::Write(opstream&) const
- {
- }
-
- //
- // Global pointer to this module
- //
- TModule* Module = 0;
-
- #if defined(BI_PLAT_WIN32)
-
- static int Attaches = 0; // Win32s doesn't have per-instance data-- keep
- // track of number of attached processes
-
- int WINAPI
- DllEntryPoint(HINSTANCE hInstance, uint32 reason, void*)
- {
- switch (reason) {
- case DLL_PROCESS_ATTACH: {
- if (!Attaches) {
- ::Module = new TObjectWindowsLibrary(hInstance);
- }
- Attaches++;
- break;
- }
- case DLL_PROCESS_DETACH: {
- Attaches--;
- if (!Attaches)
- delete ::Module;
- break;
- }
- }
- return true;
- }
-
- #else // !defined(BI_PLAT_WIN32)
-
- //
- // Entry point for the Owl DLL itself
- //
- int FAR PASCAL
- LibMain(HINSTANCE hInstance,
- uint16 /*wDataSeg*/,
- uint16 /*cbHeapSize*/,
- char far* /*lpCmdLine*/)
- {
- //
- // Allocate the TModule object for the Owl DLL. The RTL makes sure that
- // the memory allocated is GMEM_SHARE.
- //
- ::Module = new TObjectWindowsLibrary(hInstance);
-
- return Module->Status == 0;
- }
-
- int
- FAR PASCAL
- WEP(int /*bSystemExit*/)
- {
- delete ::Module;
- return 1;
- }
-
- #endif // defined(BI_PLAT_WIN32)
- #endif // defined(_BUILDOWLDLL)
- #endif // SECTION == 3
-
- #if !defined(SECTION) || SECTION == 4
- //
- // Inserter for formated output of instance handle
- //
- ostream& _OWLFUNC
- operator <<(ostream& os, const TModule& m)
- {
- return os << hex << uint(m.HInstance);
- }
- #endif //section 4
-