int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
#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);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
/////////////////////////////////////////////////////////////////////////////
CWinThread* AFXAPI AfxGetThread()
{
// check for current thread in module thread state
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
CWinThread* pThread = pState->m_pCurrentWinThread;
// if no CWinThread for the module, then use the global app
if (pThread == NULL)
pThread = AfxGetApp();
return pThread;
}
AFX_MODULE_THREAD_STATE* AFXAPI AfxGetModuleThreadState()
{
return AfxGetModuleState()->m_thread.GetData();
}
AFX_MODULE_STATE* AFXAPI AfxGetModuleState()
{
_AFX_THREAD_STATE* pState = _afxThreadState;
AFX_MODULE_STATE* pResult;
if (pState->m_pModuleState != NULL)
{
// thread state's module state serves as override
pResult = pState->m_pModuleState;
}
else
{
// otherwise, use global app state
pResult = _afxBaseModuleState.GetData();
}
ASSERT(pResult != NULL);
return pResult;
}
template<class TYPE>
class CProcessLocal : public CProcessLocalObject
{
// Attributes
public:
AFX_INLINE TYPE* GetData()
{
TYPE* pData = (TYPE*)CProcessLocalObject::GetData(&CreateObject);
ASSERT(pData != NULL);
return pData;
}
AFX_INLINE TYPE* GetDataNA()
{ return (TYPE*)m_pObject; }
AFX_INLINE operator TYPE*()
{ return GetData(); }
AFX_INLINE TYPE* operator->()
{ return GetData(); }
// Implementation
public:
static CNoTrackObject* AFXAPI CreateObject()
{ return new TYPE; }
};
CNoTrackObject* CProcessLocalObject::GetData(
CNoTrackObject* (AFXAPI* pfnCreateObject)())
{
if (m_pObject == NULL)
{
AfxLockGlobals(CRIT_PROCESSLOCAL);
TRY
{
if (m_pObject == NULL)
m_pObject = (*pfnCreateObject)();
}
CATCH_ALL(e)
{
AfxUnlockGlobals(CRIT_PROCESSLOCAL);
THROW_LAST();
}
END_CATCH_ALL
AfxUnlockGlobals(CRIT_PROCESSLOCAL);
}
return m_pObject;
}
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
{ return afxCurrentWinApp; }
BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
// handle critical errors and avoid Windows message boxes
SetErrorMode(SetErrorMode(0) |
SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
// set resource handles
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_hCurrentInstanceHandle = hInstance;
pModuleState->m_hCurrentResourceHandle = hInstance;
// fill in the initial state for the application
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
{
// Windows specific initialization (not done if no CWinApp)
pApp->m_hInstance = hInstance;
pApp->m_hPrevInstance = hPrevInstance;
pApp->m_lpCmdLine = lpCmdLine;
pApp->m_nCmdShow = nCmdShow;
pApp->SetCurrentHandles();
}
// initialize thread specific data (for main thread)
if (!afxContextIsDLL)
AfxInitThread();
return TRUE;
}
LRESULT CALLBACK _AfxMsgFilterHook(int code, WPARAM wParam, LPARAM lParam);
void AFXAPI AfxInitThread()
{
if (!afxContextIsDLL)
{
// set message filter proc
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
ASSERT(pThreadState->m_hHookOldMsgFilter == NULL);
pThreadState->m_hHookOldMsgFilter = ::SetWindowsHookEx(WH_MSGFILTER,
_AfxMsgFilterHook, NULL, ::GetCurrentThreadId());
#ifndef _AFX_NO_CTL3D_SUPPORT
// intialize CTL3D for this thread
_AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState;
if (pCtl3dState->m_pfnAutoSubclass != NULL)
(*pCtl3dState->m_pfnAutoSubclass)(AfxGetInstanceHandle());
// allocate thread local _AFX_CTL3D_THREAD just for automatic termination
_AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread;
pTemp; // avoid unused warning
#endif
}
}
BOOL CWinApp::InitApplication()
{
if (CDocManager::pStaticDocManager != NULL)
{
if (m_pDocManager == NULL)
m_pDocManager = CDocManager::pStaticDocManager;
CDocManager::pStaticDocManager = NULL;
}
if (m_pDocManager != NULL)
m_pDocManager->AddDocTemplate(NULL);
else
CDocManager::bStaticInit = FALSE;
return TRUE;
}
void AFXAPI AfxWinTerm(void)
{
// unregister Window classes
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_REGCLASSLIST);
LPTSTR lpsz = pModuleState->m_szUnregisterList;
while (*lpsz != 0)
{
LPTSTR lpszEnd = _tcschr(lpsz, '\n');
ASSERT(lpszEnd != NULL);
*lpszEnd = 0;
UnregisterClass(lpsz, AfxGetInstanceHandle());
lpsz = lpszEnd + 1;
}
pModuleState->m_szUnregisterList[0] = 0;
AfxUnlockGlobals(CRIT_REGCLASSLIST);
// cleanup OLE if required
CWinThread* pThread = AfxGetApp();
if (pThread != NULL && pThread->m_lpfnOleTermOrFreeLib != NULL)
(*pThread->m_lpfnOleTermOrFreeLib)(TRUE, FALSE);
// cleanup thread local tooltip window
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pToolTip != NULL)
{
if (pThreadState->m_pToolTip->DestroyToolTipCtrl())
pThreadState->m_pToolTip = NULL;
}
if (!afxContextIsDLL)
{
// unhook windows hooks
if (pThreadState->m_hHookOldMsgFilter != NULL)
{
::UnhookWindowsHookEx(pThreadState->m_hHookOldMsgFilter);
pThreadState->m_hHookOldMsgFilter = NULL;
}
if (pThreadState->m_hHookOldCbtFilter != NULL)
{
::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);
pThreadState->m_hHookOldCbtFilter = NULL;
}
}
}