home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / GDIOBJEC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  4.2 KB  |  165 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1992, 1993 by Borland International
  3. //   source\owl\gdiobjec.cpp
  4. //   Implementation of TGdiObject, abstract GDI object base class
  5. //----------------------------------------------------------------------------
  6. #include <owl\owlpch.h>
  7. #include <owl\gdiobjec.h>
  8.  
  9. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlGDI, 1, 0);
  10.                                    // General GDI diagnostic group
  11. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlGDIOrphan, 1, 0);
  12.                                    // Orphan control tracing group
  13.  
  14. //
  15. // TGdiObject's internal orphan control object, container and member functions
  16. //
  17. #if !defined(NO_GDI_ORPHAN_CONTROL)
  18.  
  19. #include <classlib\bags.h>
  20.  
  21. struct TObjInfo {
  22.   HANDLE            Handle;
  23.   TGdiObject::TType Type : 8;
  24.   int               RefCount : 8;
  25.  
  26.   TObjInfo() : Handle(0), Type(TGdiObject::None), RefCount(0) {}
  27.   TObjInfo(HANDLE handle) : Handle(handle) {}
  28.   TObjInfo(HANDLE handle, TGdiObject::TType type, int ref)
  29.     : Handle(handle), Type(type), RefCount(ref) {}
  30.   BOOL operator ==(const TObjInfo& other) const {
  31.     return other.Handle == Handle;
  32.   }
  33. };
  34.  
  35. typedef TBagAsVector<TObjInfo> TObjInfoBag;
  36. typedef TBagAsVectorIterator<TObjInfo> TObjInfoBagIter;
  37.  
  38. static TObjInfoBag* ObjInfoBag;
  39.  
  40. #if defined(__TRACE)
  41. const static char* ObjTypeStr[] = {
  42.   "?", "Pen", "Brush", "Font", "Palette", "Bitmap", "TextBrush", 0
  43. };
  44. #endif
  45.  
  46. //
  47. // Find a reference to a given handle in the ObjInfoBag
  48. //
  49. TObjInfo*
  50. TGdiObject::RefFind(HANDLE handle)
  51. {
  52.   if (!ObjInfoBag)                  // Allocate bag on the first access of it
  53.     ObjInfoBag = new TObjInfoBag;
  54.  
  55.   return handle ?
  56.            CONST_CAST(TObjInfo*,ObjInfoBag->Find(TObjInfo(handle))) : 0;
  57. }
  58.  
  59. //
  60. // Add an object reference entry into table, starting ref count at one
  61. //
  62. void
  63. TGdiObject::RefAdd(HANDLE handle, TGdiObject::TType type)
  64. {
  65.   if (handle && !RefFind(handle))
  66.     ObjInfoBag->Add(TObjInfo(handle, type, 1));
  67. }
  68.  
  69. //
  70. // Remove an object reference entry from table
  71. //
  72. void
  73. TGdiObject::RefRemove(HANDLE handle)
  74. {
  75.   ObjInfoBag->Detach(TObjInfo(handle));
  76. }
  77.  
  78. //
  79. // Increment an object reference entry's ref count
  80. //
  81. void
  82. TGdiObject::RefInc(HANDLE handle)
  83. {
  84.   TObjInfo* member = RefFind(handle);
  85.   if (member)
  86.     member->RefCount++;
  87. }
  88.  
  89. //
  90. // Decrement an object reference entry's ref count.  Delete object if
  91. // refcount goes to zero.  Warn if deletion was/wasn't supposed to
  92. // happen and it didn't/did. Detach info if object was deleted.
  93. //
  94. void
  95. #if defined(__TRACE)
  96.   TGdiObject::RefDec(HANDLE handle, BOOL wantDelete)
  97. #else
  98.   TGdiObject::RefDec(HANDLE handle)
  99. #endif
  100. {
  101.   TObjInfo* member = RefFind(handle);
  102.   if (member) {
  103.     BOOL needDelete = --(member->RefCount) == 0;
  104.     #if defined(__TRACE)
  105.       if (needDelete != wantDelete) {
  106.         if (needDelete)
  107.           TRACEX(OwlGDIOrphan, 1, "Orphan" << ObjTypeStr[member->Type] <<
  108.                  (UINT)member->Handle << "Deleted")
  109.         else
  110.           TRACEX(OwlGDIOrphan, 1, ObjTypeStr[member->Type] <<
  111.                  (UINT)member->Handle << "Orphan")
  112.       }
  113.     #endif
  114.     if (needDelete) {
  115.       if (!::DeleteObject(member->Handle))
  116.         THROW( TXGdi(IDS_GDIDELETEFAIL, member->Handle) );
  117.       ObjInfoBag->Detach(*member);
  118.     }
  119.   }
  120. }
  121.  
  122. //
  123. // Return the reference count of a handle, -1 if not found
  124. //
  125. int
  126. TGdiObject::RefCount(HANDLE handle)
  127. {
  128.   TObjInfo* member = RefFind(handle);
  129.   if (member)
  130.     return member->RefCount;
  131.   return -1;
  132. }
  133.  
  134. #endif  // !defined(NO_GDI_ORPHAN_CONTROL)
  135.  
  136.  
  137. //----------------------------------------------------------------------------
  138.  
  139. //
  140. // TGdiObject constructors
  141. //
  142. TGdiObject::TGdiObject()
  143. {
  144.   // Handle must be set by derived class
  145. }
  146.  
  147. TGdiObject::TGdiObject(HANDLE handle, TAutoDelete autoDelete)
  148.   : TGdiBase(handle, autoDelete)
  149. {
  150. //  CheckValid();
  151.   // Derived class must call OBJ_REF_ADD(Handle, type) if ShouldDelete
  152. }
  153.  
  154. TGdiObject::~TGdiObject()
  155. {
  156.   if (ShouldDelete) {
  157.     #if !defined(NO_GDI_ORPHAN_CONTROL)
  158.       OBJ_REF_DEC(Handle, TRUE);
  159.     #else
  160.       if (!::DeleteObject(Handle))
  161.         THROW( TXGdi(IDS_GDIDELETEFAIL, Handle) );
  162.     #endif
  163.   }
  164. }
  165.