home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / GDIOBJEC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  4.4 KB  |  173 lines

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