home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
objcore.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
6KB
|
227 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 AFX_CORE1_SEG
#pragma code_seg(AFX_CORE1_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Runtime Typing
// special runtime-class structure for CObject (no base class)
#ifdef _AFXDLL
CRuntimeClass* PASCAL CObject::_GetBaseClass()
{ return NULL; }
AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
{ "CObject", sizeof(CObject), 0xffff, NULL, &CObject::_GetBaseClass, NULL };
#else
AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
{ "CObject", sizeof(CObject), 0xffff, NULL, NULL, NULL };
#endif
CRuntimeClass* CObject::GetRuntimeClass() const
{
return RUNTIME_CLASS(CObject);
}
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
ASSERT(this != NULL);
// it better be in valid memory, at least for CObject size
ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
// simple SI case
CRuntimeClass* pClassThis = GetRuntimeClass();
return pClassThis->IsDerivedFrom(pClass);
}
CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
{
if (pObject != NULL && pObject->IsKindOf(pClass))
return pObject;
else
return NULL;
}
#ifdef _DEBUG
CObject* AFX_CDECL AfxStaticDownCast(CRuntimeClass* pClass, CObject* pObject)
{
ASSERT(pObject == NULL || pObject->IsKindOf(pClass));
return pObject;
}
#endif
/////////////////////////////////////////////////////////////////////////////
// Diagnostic Support
#ifdef _DEBUG
void AFXAPI AfxAssertValidObject(const CObject* pOb,
LPCSTR lpszFileName, int nLine)
{
if (pOb == NULL)
{
TRACE0("ASSERT_VALID fails with NULL pointer.\n");
if (AfxAssertFailedLine(lpszFileName, nLine))
AfxDebugBreak();
return; // quick escape
}
if (!AfxIsValidAddress(pOb, sizeof(CObject)))
{
TRACE0("ASSERT_VALID fails with illegal pointer.\n");
if (AfxAssertFailedLine(lpszFileName, nLine))
AfxDebugBreak();
return; // quick escape
}
// check to make sure the VTable pointer is valid
ASSERT(sizeof(CObject) == sizeof(void*));
if (!AfxIsValidAddress(*(void**)pOb, sizeof(void*), FALSE))
{
TRACE0("ASSERT_VALID fails with illegal vtable pointer.\n");
if (AfxAssertFailedLine(lpszFileName, nLine))
AfxDebugBreak();
return; // quick escape
}
if (!AfxIsValidAddress(pOb, pOb->GetRuntimeClass()->m_nObjectSize, FALSE))
{
TRACE0("ASSERT_VALID fails with illegal pointer.\n");
if (AfxAssertFailedLine(lpszFileName, nLine))
AfxDebugBreak();
return; // quick escape
}
pOb->AssertValid();
}
void CObject::AssertValid() const
{
ASSERT(this != NULL);
}
void CObject::Dump(CDumpContext& dc) const
{
dc << "a " << GetRuntimeClass()->m_lpszClassName <<
" at " << (void*)this << "\n";
UNUSED(dc); // unused in release build
}
#endif //_DEBUG
////////////////////////////////////////////////////////////////////////////
// Allocation/Creation
CObject* CRuntimeClass::CreateObject()
{
if (m_pfnCreateObject == NULL)
{
TRACE(_T("Error: Trying to create object which is not ")
_T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),
m_lpszClassName);
return NULL;
}
CObject* pObject = NULL;
TRY
{
pObject = (*m_pfnCreateObject)();
}
END_TRY
return pObject;
}
////////////////////////////////////////////////////////////////////////////
// Class loader & class serialization
BOOL CObject::IsSerializable() const
{
return (GetRuntimeClass()->m_wSchema != 0xffff);
}
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
AFX_CLASSINIT_COMPAT::AFX_CLASSINIT_COMPAT(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
{
ASSERT(this != NULL);
ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));
ASSERT(pBaseClass != NULL);
ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));
// simple SI case
const CRuntimeClass* pClassThis = this;
while (pClassThis != NULL)
{
if (pClassThis == pBaseClass)
return TRUE;
#ifdef _AFXDLL
pClassThis = (*pClassThis->m_pfnGetBaseClass)();
#else
pClassThis = pClassThis->m_pBaseClass;
#endif
}
return FALSE; // walked to the top, no match
}
////////////////////////////////////////////////////////////////////////////
// CRuntimeClass special diagnostics
#ifdef _DEBUG
void AFXAPI AfxDoForAllClasses(void (AFX_CDECL *pfn)(const CRuntimeClass*, void*),
void* pContext)
{
// just walk through the simple list of registered classes
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
for (CRuntimeClass* pClass = pModuleState->m_classList; pClass != NULL;
pClass = pClass->m_pNextClass)
{
(*pfn)(pClass, pContext);
}
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
#ifdef _AFXDLL
// walk through the list of dynlink library registered classes
AfxLockGlobals(CRIT_DYNLINKLIST);
for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
pDLL = pDLL->m_pNextDLL)
{
for (pClass = pDLL->m_classList; pClass != NULL;
pClass = pClass->m_pNextClass)
{
(*pfn)(pClass, pContext);
}
}
AfxUnlockGlobals(CRIT_DYNLINKLIST);
#endif
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////