// 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" #include #ifdef AFX_INIT_SEG #pragma code_seg(AFX_INIT_SEG) #endif #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #pragma warning(disable: 4074) #pragma init_seg(compiler) ///////////////////////////////////////////////////////////////////////////// // AFX_MODULE_STATE push/pop implementation #ifdef _AFXDLL AFX_MODULE_STATE* AFXAPI AfxSetModuleState(AFX_MODULE_STATE* pNewState) { _AFX_THREAD_STATE* pState = _afxThreadState; AFX_MODULE_STATE* pPrevState = pState->m_pModuleState; pState->m_pModuleState = pNewState; return pPrevState; } AFX_MAINTAIN_STATE::~AFX_MAINTAIN_STATE() { _AFX_THREAD_STATE* pState = _afxThreadState; pState->m_pModuleState = m_pPrevModuleState; } AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(AFX_MODULE_STATE* pNewState) { m_pThreadState = _afxThreadState; m_pPrevModuleState = m_pThreadState->m_pModuleState; m_pThreadState->m_pModuleState = pNewState; } #endif //_AFXDLL ///////////////////////////////////////////////////////////////////////////// // _AFX_THREAD_STATE implementation _AFX_THREAD_STATE::_AFX_THREAD_STATE() { m_nLastHit = -1; m_nLastStatus = -1; } _AFX_THREAD_STATE::~_AFX_THREAD_STATE() { // cleanup thread local tooltip window if (m_pToolTip != NULL) { m_pToolTip->DestroyWindow(); delete m_pToolTip; } // unhook windows hooks if (m_hHookOldMsgFilter != NULL) ::UnhookWindowsHookEx(m_hHookOldMsgFilter); if (m_hHookOldCbtFilter != NULL) ::UnhookWindowsHookEx(m_hHookOldCbtFilter); // free safety pool buffer if (m_pSafetyPoolBuffer != NULL) free(m_pSafetyPoolBuffer); // parking window must have already been cleaned up by now! ASSERT(m_pWndPark == NULL); } _AFX_THREAD_STATE* AFXAPI AfxGetThreadState() { return _afxThreadState.GetData(); } THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState) ///////////////////////////////////////////////////////////////////////////// // AFX_MODULE_STATE implementation #ifdef _AFXDLL AFX_MODULE_STATE::AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion, BOOL bSystem) #else AFX_MODULE_STATE::AFX_MODULE_STATE(BOOL bDLL) #endif { #ifndef _AFX_NO_OLE_SUPPORT m_factoryList.Construct(offsetof(COleObjectFactory, m_pNextFactory)); #endif m_classList.Construct(offsetof(CRuntimeClass, m_pNextClass)); m_fRegisteredClasses = 0; m_bDLL = (BYTE)bDLL; #ifdef _AFXDLL m_pfnAfxWndProc = pfnAfxWndProc; m_dwVersion = dwVersion; m_bSystem = (BYTE)bSystem; #endif // app starts out in "user control" m_bUserCtrl = TRUE; #ifndef _AFX_NO_OCC_SUPPORT m_lockList.Construct(offsetof(COleControlLock, m_pNextLock)); #endif #ifdef _AFXDLL m_libraryList.Construct(offsetof(CDynLinkLibrary, m_pNextDLL)); #endif #ifdef _AFX_OLD_EXCEPTIONS m_pfnTerminate = AfxAbort; #endif } // Note: this constructor is purely for backward compatibility to the ISV drop #ifdef _AFXDLL AFX_MODULE_STATE::AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion) { ::new((void*)this) AFX_MODULE_STATE(bDLL, pfnAfxWndProc, dwVersion, FALSE); } #endif AFX_MODULE_STATE::~AFX_MODULE_STATE() { #ifndef _AFX_NO_DAO_SUPPORT delete m_pDaoState; #endif // clean up type lib cache map, if any if (m_pTypeLibCacheMap != NULL) { m_pTypeLibCacheMap->RemoveAll(&m_typeLibCache); delete m_pTypeLibCacheMap; } } void CTypeLibCacheMap::RemoveAll(void* pExcept) { POSITION pos = GetStartPosition(); void* pTypeLibID; CTypeLibCache* pCache; while (pos != NULL) { GetNextAssoc(pos, pTypeLibID, (void*&)pCache); if (pCache != pExcept) delete pCache; } } AFX_MODULE_THREAD_STATE::AFX_MODULE_THREAD_STATE() { m_frameList.Construct(offsetof(CFrameWnd, m_pNextFrameWnd)); // Note: it is only necessary to initialize non-zero data m_pfnNewHandler = &AfxNewHandler; } AFX_MODULE_THREAD_STATE::~AFX_MODULE_THREAD_STATE() { // cleanup temp/permanent maps (just the maps themselves) delete m_pmapHWND; delete m_pmapHMENU; delete m_pmapHDC; delete m_pmapHGDIOBJ; delete m_pmapHIMAGELIST; #ifndef _AFX_NO_SOCKET_SUPPORT // cleanup socket notification list if (m_plistSocketNotifications != NULL) while (!m_plistSocketNotifications->IsEmpty()) delete m_plistSocketNotifications->RemoveHead(); #ifndef _AFXDLL // cleanup dynamically allocated socket maps delete m_pmapSocketHandle; delete m_pmapDeadSockets; delete m_plistSocketNotifications; #endif #endif //!_AFX_NO_SOCKET_SUPPORT } ///////////////////////////////////////////////////////////////////////////// // AFX_MODULE_STATE for base application LRESULT CALLBACK AfxWndProcBase(HWND, UINT, WPARAM, LPARAM); class _AFX_BASE_MODULE_STATE : public AFX_MODULE_STATE { public: #ifdef _AFXDLL _AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE, AfxWndProcBase, _MFC_VER) #else _AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE) #endif { } }; PROCESS_LOCAL(_AFX_BASE_MODULE_STATE, _afxBaseModuleState) #ifdef _AFXDLL #undef AfxWndProc LRESULT CALLBACK AfxWndProcBase(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { AFX_MANAGE_STATE(_afxBaseModuleState.GetData()); return AfxWndProc(hWnd, nMsg, wParam, lParam); } #endif ///////////////////////////////////////////////////////////////////////////// // helper functions for module state AFX_MODULE_STATE* AFXAPI AfxGetAppModuleState() { return _afxBaseModuleState.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; } AFX_MODULE_THREAD_STATE* AFXAPI AfxGetModuleThreadState() { return AfxGetModuleState()->m_thread.GetData(); } ///////////////////////////////////////////////////////////////////////////// // CTypeLibCache::Unlock // (Note: the rest of CTypeLibCache is implemented in oletyplb.cpp) void CTypeLibCache::Unlock() { ASSERT(m_cRef > 0); if (InterlockedDecrement(&m_cRef) == 0) { if (m_ptinfo != NULL) { m_ptinfo->Release(); m_ptinfo = NULL; } if (m_ptlib != NULL) { m_ptlib->Release(); m_ptlib = NULL; } } }