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 >
C/C++ Source or Header  |  1998-06-16  |  6KB  |  227 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE1_SEG
  14. #pragma code_seg(AFX_CORE1_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // Runtime Typing
  24.  
  25. // special runtime-class structure for CObject (no base class)
  26. #ifdef _AFXDLL
  27. CRuntimeClass* PASCAL CObject::_GetBaseClass()
  28.     { return NULL; }
  29. AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
  30.     { "CObject", sizeof(CObject), 0xffff, NULL, &CObject::_GetBaseClass, NULL };
  31. #else
  32. AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
  33.     { "CObject", sizeof(CObject), 0xffff, NULL, NULL, NULL };
  34. #endif
  35.  
  36. CRuntimeClass* CObject::GetRuntimeClass() const
  37. {
  38.     return RUNTIME_CLASS(CObject);
  39. }
  40.  
  41. BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
  42. {
  43.     ASSERT(this != NULL);
  44.     // it better be in valid memory, at least for CObject size
  45.     ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
  46.  
  47.     // simple SI case
  48.     CRuntimeClass* pClassThis = GetRuntimeClass();
  49.     return pClassThis->IsDerivedFrom(pClass);
  50. }
  51.  
  52. CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
  53. {
  54.     if (pObject != NULL && pObject->IsKindOf(pClass))
  55.         return pObject;
  56.     else
  57.         return NULL;
  58. }
  59.  
  60. #ifdef _DEBUG
  61. CObject* AFX_CDECL AfxStaticDownCast(CRuntimeClass* pClass, CObject* pObject)
  62. {
  63.     ASSERT(pObject == NULL || pObject->IsKindOf(pClass));
  64.     return pObject;
  65. }
  66. #endif
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. // Diagnostic Support
  70.  
  71. #ifdef _DEBUG
  72. void AFXAPI AfxAssertValidObject(const CObject* pOb,
  73.     LPCSTR lpszFileName, int nLine)
  74. {
  75.     if (pOb == NULL)
  76.     {
  77.         TRACE0("ASSERT_VALID fails with NULL pointer.\n");
  78.         if (AfxAssertFailedLine(lpszFileName, nLine))
  79.             AfxDebugBreak();
  80.         return;     // quick escape
  81.     }
  82.     if (!AfxIsValidAddress(pOb, sizeof(CObject)))
  83.     {
  84.         TRACE0("ASSERT_VALID fails with illegal pointer.\n");
  85.         if (AfxAssertFailedLine(lpszFileName, nLine))
  86.             AfxDebugBreak();
  87.         return;     // quick escape
  88.     }
  89.  
  90.     // check to make sure the VTable pointer is valid
  91.     ASSERT(sizeof(CObject) == sizeof(void*));
  92.     if (!AfxIsValidAddress(*(void**)pOb, sizeof(void*), FALSE))
  93.     {
  94.         TRACE0("ASSERT_VALID fails with illegal vtable pointer.\n");
  95.         if (AfxAssertFailedLine(lpszFileName, nLine))
  96.             AfxDebugBreak();
  97.         return;     // quick escape
  98.     }
  99.  
  100.     if (!AfxIsValidAddress(pOb, pOb->GetRuntimeClass()->m_nObjectSize, FALSE))
  101.     {
  102.         TRACE0("ASSERT_VALID fails with illegal pointer.\n");
  103.         if (AfxAssertFailedLine(lpszFileName, nLine))
  104.             AfxDebugBreak();
  105.         return;     // quick escape
  106.     }
  107.     pOb->AssertValid();
  108. }
  109.  
  110. void CObject::AssertValid() const
  111. {
  112.     ASSERT(this != NULL);
  113. }
  114.  
  115. void CObject::Dump(CDumpContext& dc) const
  116. {
  117.     dc << "a " << GetRuntimeClass()->m_lpszClassName <<
  118.         " at " << (void*)this << "\n";
  119.  
  120.     UNUSED(dc); // unused in release build
  121. }
  122. #endif //_DEBUG
  123.  
  124. ////////////////////////////////////////////////////////////////////////////
  125. // Allocation/Creation
  126.  
  127. CObject* CRuntimeClass::CreateObject()
  128. {
  129.     if (m_pfnCreateObject == NULL)
  130.     {
  131.         TRACE(_T("Error: Trying to create object which is not ")
  132.               _T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),
  133.             m_lpszClassName);
  134.         return NULL;
  135.     }
  136.  
  137.     CObject* pObject = NULL;
  138.     TRY
  139.     {
  140.         pObject = (*m_pfnCreateObject)();
  141.     }
  142.     END_TRY
  143.  
  144.     return pObject;
  145. }
  146.  
  147. ////////////////////////////////////////////////////////////////////////////
  148. // Class loader & class serialization
  149.  
  150. BOOL CObject::IsSerializable() const
  151. {
  152.     return (GetRuntimeClass()->m_wSchema != 0xffff);
  153. }
  154.  
  155. void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
  156. {
  157.     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  158.     AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  159.     pModuleState->m_classList.AddHead(pNewClass);
  160.     AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  161. }
  162.  
  163. AFX_CLASSINIT_COMPAT::AFX_CLASSINIT_COMPAT(CRuntimeClass* pNewClass)
  164. {
  165.     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  166.     AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  167.     pModuleState->m_classList.AddHead(pNewClass);
  168.     AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  169. }
  170.  
  171. BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
  172. {
  173.     ASSERT(this != NULL);
  174.     ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));
  175.     ASSERT(pBaseClass != NULL);
  176.     ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));
  177.  
  178.     // simple SI case
  179.     const CRuntimeClass* pClassThis = this;
  180.     while (pClassThis != NULL)
  181.     {
  182.         if (pClassThis == pBaseClass)
  183.             return TRUE;
  184. #ifdef _AFXDLL
  185.         pClassThis = (*pClassThis->m_pfnGetBaseClass)();
  186. #else
  187.         pClassThis = pClassThis->m_pBaseClass;
  188. #endif
  189.     }
  190.     return FALSE;       // walked to the top, no match
  191. }
  192.  
  193. ////////////////////////////////////////////////////////////////////////////
  194. // CRuntimeClass special diagnostics
  195.  
  196. #ifdef _DEBUG
  197. void AFXAPI AfxDoForAllClasses(void (AFX_CDECL *pfn)(const CRuntimeClass*, void*),
  198.     void* pContext)
  199. {
  200.     // just walk through the simple list of registered classes
  201.     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  202.     AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  203.     for (CRuntimeClass* pClass = pModuleState->m_classList; pClass != NULL;
  204.         pClass = pClass->m_pNextClass)
  205.     {
  206.         (*pfn)(pClass, pContext);
  207.     }
  208.     AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  209. #ifdef _AFXDLL
  210.     // walk through the list of dynlink library registered classes
  211.     AfxLockGlobals(CRIT_DYNLINKLIST);
  212.     for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  213.         pDLL = pDLL->m_pNextDLL)
  214.     {
  215.         for (pClass = pDLL->m_classList; pClass != NULL;
  216.             pClass = pClass->m_pNextClass)
  217.         {
  218.             (*pfn)(pClass, pContext);
  219.         }
  220.     }
  221.     AfxUnlockGlobals(CRIT_DYNLINKLIST);
  222. #endif
  223. }
  224. #endif //_DEBUG
  225.  
  226. /////////////////////////////////////////////////////////////////////////////
  227.