OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
gdiobjec.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1992, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of TGdiObject, abstract class for GDI objects that can be
7/// selected into TDCs
8//----------------------------------------------------------------------------
9#include <owl/pch.h>
10
11#include <owl/gdiobjec.h>
12
13#if defined(BI_MULTI_THREAD_RTL)
14#include <owl/thread.h>
15#endif
16
17#include <owl/template.h>
18
19using namespace std;
20
21namespace owl {
22
24
26// General GDI diagnostic group
28// Orphan control tracing group
29
30
31//
32// TGdiObject's internal orphan control object, container and member functions
33//
34
35struct TObjInfo {
36 HANDLE Handle;
38 int RefCount;
39
40 TObjInfo() : Handle(nullptr), Type(TGdiObject::None), RefCount(0)
41 {}
42 TObjInfo(HANDLE handle) : Handle(handle)
43 {}
44 TObjInfo(HANDLE handle, TGdiObject::TType type, int ref)
45 : Handle(handle), Type(type), RefCount(ref)
46 {}
47 ~TObjInfo()
48 {}
49 bool operator ==(const TObjInfo& other) const {
50 return other.Handle == Handle;
51 }
52 bool operator <(const TObjInfo& other) const {
53 return other.Handle < Handle;
54 }
55};
56
58
59static TObjInfoBag* __ObjInfoBag = 0;
60#if defined(BI_MULTI_THREAD_RTL)
62#endif
63
64#if defined(BI_MULTI_THREAD_RTL) //ObjInfoBag().Lock
65#define LOCKOBJECTBAG(s) TMRSWSection::TLock __lock(*__ObjInfoBagLock,s)
66#else
67#define LOCKOBJECTBAG(s)
68#endif
69
70//static TObjInfoBag* ObjInfoBag;
71
72#if defined(__TRACE)
73static const LPCTSTR ObjTypeStr[] = {
74 _T("?"), _T("Pen"), _T("Brush"), _T("Font"), _T("Palette"),
75 _T("Bitmap"), _T("TextBrush"), 0
76};
77#endif
78
79//
80static void createObjInfoBag()
81{
82 static LONG createObjInfo = -1;
83 if(__ObjInfoBag)
84 return;
85
88 __ObjInfoBag = new TObjInfoBag;
89#if defined(BI_MULTI_THREAD_RTL)
90 __ObjInfoBagLock = new TMRSWSection;
91#endif
92 createObjInfo = -1;
93 }
94}
95//
96static void destroyObjInfoBag()
97{
98 static LONG destroyObjInfo = -1;
99 if(__ObjInfoBag==nullptr || __ObjInfoBag->Size()>0)
100 return;
101
104 delete __ObjInfoBag;
105#if defined(BI_MULTI_THREAD_RTL)
106 delete __ObjInfoBagLock;
107#endif
108 __ObjInfoBag = nullptr;
109 destroyObjInfo = -1;
110 }
111}
112
113//
114/// Searches for the given object handle.
115/// \returns If found, the object's type and reference count are returned in the specified TObjInfo
116/// object. RefFind returns 0 if no match is found.
117//
118TObjInfo*
120{
121 if (handle && __ObjInfoBag)
122 {
123 LOCKOBJECTBAG(true);
124 const auto pos = __ObjInfoBag->Find(TObjInfo(handle));
125 if (pos != __ObjInfoBag->NPOS)
126 return &((*__ObjInfoBag)[pos]);
127 }
128 return nullptr;
129}
130
131//
132/// RefAdd adds a reference entry for the object with the given handle and type.
133/// If the table already has a matching entry, no action is taken, otherwise the reference count is
134/// set to 1.
135//
136void
138{
139 createObjInfoBag();
140#if !defined(NO_GDI_SHARE_HANDLES)
141 if (handle) {
142 TObjInfo* member = RefFind(handle);
143 if (member)
144 member->RefCount++;
145 else {
146 LOCKOBJECTBAG(false);
147 __ObjInfoBag->Add(TObjInfo(handle, type, 1));
148 }
149 }
150#else
151 if (handle && !RefFind(handle)){
152 LOCKOBJECTBAG(false);
153 __ObjInfoBag->Add(TObjInfo(handle, type, 1));
154 }
155#endif
156}
157
158//
159/// Removes the reference entry to the object with the given handle.
160/// If the given handle is not found, no action is taken.
161//
162void
164{
165 if(!__ObjInfoBag)
166 return;
167 {
168 LOCKOBJECTBAG(false);
169 __ObjInfoBag->DestroyItem(TObjInfo(handle));
170 }
171 destroyObjInfoBag();
172}
173
174//
175/// Increments by 1 the reference count of the object associated with the given handle.
176//
177void
179{
180 createObjInfoBag();
181 TObjInfo* member = RefFind(handle);
182 if (member)
183 {
184 member->RefCount++;
185 }
186}
187
188
189//
190/// Decrements this object's reference count by 1 and deletes the object when the reference count
191/// reaches zero.
192///
193/// A warning is issued if the deletion was supposed to happen but didn't. Likewise, a warning is
194/// issued if the deletion wasn't supposed to happen but did. The deleted object is also detached
195/// from the ObjInfoBag table.
196///
197/// You can vary the normal deletion strategy by setting wantDelete to true or false.
198//
199void
201{
203 if(!__ObjInfoBag)
204 return;
205 TObjInfo* member = RefFind(handle);
206 if (member) {
207 bool needDelete = --(member->RefCount) == 0;
208#if defined(__TRACE)
209 if (needDelete != wantDelete) {
210 if (needDelete)
211 TRACEX(OwlGDIOrphan, 1, "Orphan" << ObjTypeStr[member->Type] <<
212 static_cast<void*>(member->Handle) << "Deleted");
213
214 else
216 static_cast<void*>(member->Handle) << "Orphan");
217
218 }
219#endif
220 if (needDelete) {
221
222 if (!::DeleteObject(member->Handle))
223 {
225 }
226
227
228 {
229 LOCKOBJECTBAG(false);
230 __ObjInfoBag->DestroyItem(*member);
231 }
232
233 destroyObjInfoBag();
234 }
235 }
236}
237
238//
239/// Returns this object's current reference count or -1 if the object is not found.
240//
241int
243{
244 TObjInfo* member = RefFind(handle);
245 if (member)
246 return member->RefCount;
247 return -1;
248}
249
250
251
252//----------------------------------------------------------------------------
253
254//
255//
256//
257#if defined(__TRACE) || defined(__WARN)
258ostream& operator <<(ostream& os, const TGdiObject& gdiObject)
259{
260 os << "@" << (void*)&gdiObject << " ";
261 os << '(';
262 os << typeid(gdiObject).name() << ',';
263 os << ')';
264 return os;
265}
266#endif
267
268//
269/// This default constructor sets Handle to 0 and ShouldDelete to true. This
270/// constructor is intended for use by derived classes that must set the Handle
271/// member.
272//
274{
275 // Handle must be set and validated by the derived class.
276 TRACEX(OwlGDI, 2, "TGdiObject constructed " << *this);
277}
278
279//
280/// Create a wrapper for a given GDI object.
281//
282/// This constructor is intended for use by derived classes only. The Handle data
283/// member is "borrowed" from an existing handle given by the argument handle The
284/// ShouldDelete data member defaults to false ensuring that the borrowed handle
285/// will not be deleted when the object is destroyed.
286//
288:
290{
291 // Derived class must call RefAdd(Handle, type) if ShouldDelete
292 TRACEX(OwlGDI, 2, "TGdiObject constructed " << *this);
293}
294
295//
296/// Decrement the reference count on this object.
297//
298/// If ShouldDelete is false no action is taken. Otherwise, the reference count for the object's
299/// handle is decremented, and if it reaches zero, the handle is is deleted.
300//
302{
303 if (ShouldDelete)
304 RefDec(Handle, true);
305 TRACEX(OwlGDI, 2, "TGdiObject destructed " << *this);
306}
307
308} // OWL namespace
309
310/* ========================================================================== */
311
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
Root and abstract class for Windows object wrappers.
Definition gdibase.h:79
GdiObject is the root, pseudo-abstract base class for ObjectWindows' GDI (Graphics Device Interface) ...
Definition gdiobjec.h:68
static void RefInc(HANDLE handle)
Increments by 1 the reference count of the object associated with the given handle.
Definition gdiobjec.cpp:178
static TObjInfo * RefFind(HANDLE object)
Searches for the given object handle.
Definition gdiobjec.cpp:119
~TGdiObject()
Decrement the reference count on this object.
Definition gdiobjec.cpp:301
static void RefDec(HANDLE handle, bool wantDelete)
Decrements this object's reference count by 1 and deletes the object when the reference count reaches...
Definition gdiobjec.cpp:200
TType
This enumeration is used to store the object type in the struct TObjInfo.
Definition gdiobjec.h:103
static void RefRemove(HANDLE handle)
Removes the reference entry to the object with the given handle.
Definition gdiobjec.cpp:163
static int RefCount(HANDLE handle)
Returns this object's current reference count or -1 if the object is not found.
Definition gdiobjec.cpp:242
bool ShouldDelete
Should object delete GDI handle in dtor?
Definition gdibase.h:82
static void RefAdd(HANDLE handle, TType type)
RefAdd adds a reference entry for the object with the given handle and type.
Definition gdiobjec.cpp:137
TGdiObject()
This default constructor sets Handle to 0 and ShouldDelete to true.
Definition gdiobjec.cpp:273
HANDLE Handle
GDI handle of this object.
Definition gdibase.h:81
Multiple Read, Single Write section.
Definition thread.h:348
static void Raise(uint resId=IDS_GDIFAILURE, HANDLE handle=0)
Throws the exception.
Definition gdibase.cpp:112
#define _T(x)
Definition cygwin.h:51
#define LOCKOBJECTBAG(s)
Definition gdiobjec.cpp:67
Definition of abstract GDI object class and derived classes.
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
owl::opstream & operator<<(owl::opstream &os, const TColor &c)
Insert the color value into a persistent output stream.
Definition color.h:498
TSortedObjectArray< TObjInfo > TObjInfoBag
Definition gdiobjec.cpp:57
void InUse(const T &arg)
Handy utility to avoid compiler warnings about unused parameters.
Definition defs.h:299
OWL_DIAGINFO
Definition animctrl.cpp:14
#define OWL_INI
Definition defs.h:170
Definition of container classes used and made available by OWL.