OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
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.