mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.7 KiB
220 lines
5.7 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 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_DATADEF struct CRuntimeClass CObject::classCObject =
|
|
{ "CObject", sizeof(CObject), 0xffff, NULL, &CObject::_GetBaseClass, NULL };
|
|
#else
|
|
AFX_DATADEF struct CRuntimeClass CObject::classCObject =
|
|
{ "CObject", sizeof(CObject), 0xffff, NULL, NULL, NULL };
|
|
#endif
|
|
static const AFX_CLASSINIT _init_CObject(&CObject::classCObject);
|
|
|
|
CRuntimeClass* CObject::GetRuntimeClass() const
|
|
{
|
|
return &CObject::classCObject;
|
|
}
|
|
|
|
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))
|
|
{
|
|
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);
|
|
}
|
|
|
|
AFX_CLASSINIT::AFX_CLASSINIT(register CRuntimeClass* pNewClass)
|
|
{
|
|
AFX_MODULE_STATE* pState = AfxGetModuleState();
|
|
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
|
|
pState->m_classList.AddHead(pNewClass);
|
|
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
|
|
}
|
|
|
|
BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
|
|
{
|
|
ASSERT(this != NULL);
|
|
ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass)));
|
|
ASSERT(pBaseClass != NULL);
|
|
ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass)));
|
|
|
|
// 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);
|
|
AFX_MODULE_PROCESS_STATE* pState = AfxGetModuleProcessState();
|
|
for (CDynLinkLibrary* pDLL = pState->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
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|