home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / MFC / SRC / WINHAND.CP_ / WINHAND.CP
Encoding:
Text File  |  1993-02-08  |  5.1 KB  |  188 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992 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 Microsoft
  7. // QuickHelp and/or WinHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11.  
  12. #include "stdafx.h"
  13. #include "winhand_.h"
  14. #include <malloc.h>
  15.  
  16. #ifdef AFX_CORE1_SEG
  17. #pragma code_seg(AFX_CORE1_SEG)
  18. #endif
  19.  
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #define new DEBUG_NEW
  24. #endif
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27.  
  28. #ifndef _PORTABLE
  29.  
  30. #define MIN_MALLOC_OVERHEAD 4           // LocalAlloc or other overhead
  31.  
  32. int cdecl AfxCriticalNewHandler(size_t nSize)       // nSize is already rounded
  33. {
  34.     // called during critical memory allocation
  35.     //  free up part of the app's safety cache
  36.     TRACE0("Warning: Critical memory allocation failed!\n");
  37.     CWinApp* pApp = AfxGetApp();
  38.  
  39.     if (pApp != NULL && pApp->m_pSafetyPoolBuffer != NULL)
  40.     {
  41.         size_t nOldBufferSize = _msize(pApp->m_pSafetyPoolBuffer);
  42.         if (nOldBufferSize <= nSize + MIN_MALLOC_OVERHEAD)
  43.         {
  44.             // give it all up
  45.             TRACE0("Warning: Freeing application's memory safety pool!\n");
  46.             free(pApp->m_pSafetyPoolBuffer);
  47.             pApp->m_pSafetyPoolBuffer = NULL;
  48.         }
  49.         else
  50.         {
  51.             _expand(pApp->m_pSafetyPoolBuffer,
  52.                 nOldBufferSize - (nSize + MIN_MALLOC_OVERHEAD));
  53.             TRACE3("Warning: Shrinking safety pool from %d to %d to "
  54.                 "satisfy request of %d bytes", nOldBufferSize,
  55.                  _msize(pApp->m_pSafetyPoolBuffer), nSize);
  56.         }
  57.         return 1;       // retry it
  58.     }
  59.     TRACE0("ERROR: Critical memory allocation failed!\n");
  60.     AfxThrowMemoryException();      // oops
  61.     return 0;
  62. }
  63. #endif // !_PORTABLE
  64.  
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CHandleMap implementation
  67.  
  68. CHandleMap::CHandleMap(CRuntimeClass* pClass, int nHandles /*= 1*/)
  69.     : m_permanentMap(10), m_temporaryMap(4)
  70.         // small block size for temporary map
  71. {
  72.     ASSERT(pClass != NULL);
  73.     ASSERT(nHandles == 1 || nHandles == 2);
  74.  
  75.     m_temporaryMap.InitHashTable(7);    // small table for temporary map
  76.     m_pClass = pClass;
  77.     m_nHandles = nHandles;
  78. }
  79.  
  80. CObject* CHandleMap::FromHandle(HANDLE h)
  81. {
  82.     ASSERT(m_pClass != NULL);
  83.     ASSERT(m_nHandles == 1 || m_nHandles == 2);
  84.  
  85.     if (h == NULL)
  86.         return NULL;
  87.  
  88.     CObject* pObject;
  89.     if (LookupPermanent(h, pObject))
  90.         return pObject;   // return permanent one
  91.     else if (LookupTemporary(h, pObject))
  92.         return pObject;   // return current temporary one
  93.  
  94.     // This handle wasn't created by us, so we must create a temporary
  95.     // C++ object to wrap it.  We don't want the user to see this memory
  96.     // allocation, so we turn tracing off.
  97.  
  98. #ifdef _DEBUG
  99.     BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  100. #endif
  101.  
  102. #ifndef _PORTABLE
  103.     _PNH pnhOldHandler = _AfxSetNewHandler(AfxCriticalNewHandler);
  104. #endif // !PORTABLE
  105.  
  106.     CObject* pTemp = m_pClass->CreateObject();
  107.     m_temporaryMap.SetAt((MAPTYPE)h, pTemp);
  108.  
  109. #ifndef _PORTABLE
  110.     _AfxSetNewHandler(pnhOldHandler);
  111. #endif // !_PORTABLE
  112.  
  113. #ifdef _DEBUG
  114.     AfxEnableMemoryTracking(bEnable);
  115. #endif
  116.  
  117.     // now set the handle in the object
  118.     HANDLE* ph = (HANDLE*)(pTemp + 1);  // after CObject
  119.     ph[0] = h;
  120.     if (m_nHandles == 2)
  121.         ph[1] = h;
  122.     return pTemp;
  123. }
  124.  
  125. #ifdef _DEBUG   // out-of-line version for memory tracking
  126. void CHandleMap::SetPermanent(HANDLE h, CObject* permOb)
  127. {
  128.     CObject* pObject;
  129.     ASSERT(!LookupPermanent(h, pObject)); // must not be in there
  130.     BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  131.     m_permanentMap[(MAPTYPE)h] = permOb;
  132.     AfxEnableMemoryTracking(bEnable);
  133. }
  134. #endif //_DEBUG
  135.  
  136. void CHandleMap::RemoveHandle(HANDLE h)
  137. {
  138. #ifdef _DEBUG
  139.     // make sure the handle entry is consistent before deleting
  140.     CObject* pTemp;
  141.     if (LookupTemporary(h, pTemp))
  142.     {
  143.         // temporary objects must have correct handle values
  144.         HANDLE* ph = (HANDLE*)(pTemp + 1);  // after CObject
  145.         ASSERT(ph[0] == h);
  146.         if (m_nHandles == 2)
  147.             ASSERT(ph[1] == h);
  148.     }
  149.     if (LookupPermanent(h, pTemp))
  150.     {
  151.         HANDLE* ph = (HANDLE*)(pTemp + 1);  // after CObject
  152.         ASSERT(ph[0] == h);
  153.         // permanent object may have secondary handles that are different
  154.     }
  155. #endif
  156.     // remove from temporary and permanent maps
  157.     m_permanentMap.RemoveKey((MAPTYPE)h);
  158.     m_temporaryMap.RemoveKey((MAPTYPE)h);
  159. }
  160.  
  161. void CHandleMap::DeleteTemp()
  162. {
  163.     POSITION pos = m_temporaryMap.GetStartPosition();
  164.     while (pos != NULL)
  165.     {
  166.         HANDLE h; // just used for asserts
  167.         CObject* pTemp;
  168.         m_temporaryMap.GetNextAssoc(pos, (MAPTYPE&)h, (void*&)pTemp);
  169.  
  170.         // zero out the handles
  171.         ASSERT(m_nHandles == 1 || m_nHandles == 2);
  172.         HANDLE* ph = (HANDLE*)(pTemp + 1);  // after CObject
  173.         ASSERT(ph[0] == h);
  174.         ph[0] = NULL;
  175.         if (m_nHandles == 2)
  176.         {
  177.             ASSERT(ph[1] == h);
  178.             ph[1] = NULL;
  179.         }
  180.         delete pTemp;       // virtual destructor does the right thing
  181.     }
  182.  
  183.     m_temporaryMap.RemoveAll();       // free up dictionary links etc
  184. }
  185.  
  186.  
  187. /////////////////////////////////////////////////////////////////////////////
  188.