home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
dllmodul.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
6KB
|
248 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// global data
// The following symbol used to force inclusion of this module for _USRDLL
#ifdef _X86_
extern "C" { int _afxForceUSRDLL; }
#else
extern "C" { int __afxForceUSRDLL; }
#endif
#ifdef _AFXDLL
static AFX_EXTENSION_MODULE controlDLL;
// force initialization early
#pragma warning(disable: 4074)
#pragma init_seg(lib)
/////////////////////////////////////////////////////////////////////////////
// static-linked version of AfxWndProc for use by this module
LRESULT CALLBACK AfxWndProcDllStatic(HWND, UINT, WPARAM, LPARAM);
class _AFX_DLL_MODULE_STATE : public AFX_MODULE_STATE
{
public:
_AFX_DLL_MODULE_STATE() : AFX_MODULE_STATE(TRUE, AfxWndProcDllStatic, _MFC_VER)
{ }
};
static _AFX_DLL_MODULE_STATE afxModuleState;
#undef AfxWndProc
LRESULT CALLBACK
AfxWndProcDllStatic(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(&afxModuleState);
return AfxWndProc(hWnd, nMsg, wParam, lParam);
}
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState()
{
AFX_MODULE_STATE* pModuleState = &afxModuleState;
return pModuleState;
}
#endif
/////////////////////////////////////////////////////////////////////////////
// export DllMain for the DLL
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
BOOL bResult = FALSE;
#ifdef _AFXDLL
// wire up resources from core DLL
AfxCoreInitModule();
#endif
_AFX_THREAD_STATE* pState = AfxGetThreadState();
AFX_MODULE_STATE* pPrevModState = pState->m_pPrevModuleState;
// Initialize DLL's instance(/module) not the app's
if (!AfxWinInit(hInstance, NULL, _T(""), 0))
{
AfxWinTerm();
goto Cleanup; // Init Failed
}
// initialize the single instance DLL
CWinApp* pApp; pApp = AfxGetApp();
if (pApp != NULL && !pApp->InitInstance())
{
pApp->ExitInstance();
AfxWinTerm();
goto Cleanup; // Init Failed
}
pState->m_pPrevModuleState = pPrevModState;
#ifdef _AFXDLL
// wire up this DLL into the resource chain
VERIFY(AfxInitExtensionModule(controlDLL, hInstance));
CDynLinkLibrary* pDLL; pDLL = new CDynLinkLibrary(controlDLL);
ASSERT(pDLL != NULL);
#else
AfxInitLocalData(hInstance);
#endif
bResult = TRUE;
Cleanup:
pState->m_pPrevModuleState = pPrevModState;
#ifdef _AFXDLL
// restore previously-saved module state
VERIFY(AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState) ==
&afxModuleState);
DEBUG_ONLY(AfxGetThreadState()->m_pPrevModuleState = NULL);
#endif
return bResult;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
#ifdef _AFXDLL
// set module state for cleanup
ASSERT(AfxGetThreadState()->m_pPrevModuleState == NULL);
AfxGetThreadState()->m_pPrevModuleState =
AfxSetModuleState(&afxModuleState);
#endif
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
pApp->ExitInstance();
#ifdef _DEBUG
// check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
#endif
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
// terminate the library before destructors are called
AfxWinTerm();
#ifdef _AFXDLL
AfxTermExtensionModule(controlDLL, TRUE);
#else
AfxTermLocalData(hInstance, TRUE);
#endif
}
else if (dwReason == DLL_THREAD_DETACH)
{
AFX_MANAGE_STATE(&afxModuleState);
#ifdef _DEBUG
// check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
#endif
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
AfxTermThread(hInstance);
}
return TRUE;
}
#ifdef _AFXDLL
/////////////////////////////////////////////////////////////////////////////
// initialize app state such that it points to this module's core state
extern "C" BOOL WINAPI RawDllMain(HINSTANCE, DWORD dwReason, LPVOID);
extern "C" BOOL (WINAPI* _pRawDllMain)(HINSTANCE, DWORD, LPVOID) = &RawDllMain;
extern "C"
BOOL WINAPI RawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// make sure we have enough memory to attempt to start (8kb)
void* pMinHeap = LocalAlloc(NONZEROLPTR, 0x2000);
if (pMinHeap == NULL)
return FALSE; // fail if memory alloc fails
LocalFree(pMinHeap);
#ifndef _AFXDLL
if (!AfxCriticalInit())
return FALSE;
#endif
// set module state before initialization
_AFX_THREAD_STATE* pState = AfxGetThreadState();
pState->m_pPrevModuleState = AfxSetModuleState(&afxModuleState);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
// restore module state after cleanup
_AFX_THREAD_STATE* pState = AfxGetThreadState();
VERIFY(AfxSetModuleState(pState->m_pPrevModuleState) ==
&afxModuleState);
DEBUG_ONLY(pState->m_pPrevModuleState = NULL);
#ifndef _AFXDLL
AfxCriticalTerm();
#endif
}
return TRUE;
}
#endif //_AFXDLL
/////////////////////////////////////////////////////////////////////////////
// Special case for static library startup/termination
#ifndef _AFXDLL
// force initialization early
#pragma warning(disable: 4074)
#pragma init_seg(lib)
void AFX_CDECL AfxTermDllState()
{
// terminate local data and critical sections
AfxTermLocalData(NULL, TRUE);
AfxCriticalTerm();
// release the reference to thread local storage data
AfxTlsRelease();
}
char _afxTermDllState = (char)(AfxTlsAddRef(), atexit(&AfxTermDllState));
#endif // !_AFXDLL
/////////////////////////////////////////////////////////////////////////////