home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C Programming Starter Kit 2.0
/
SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso
/
bc45
/
owlsrc.pak
/
MODULE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-23
|
11KB
|
429 lines
//----------------------------------------------------------------------------
// 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