home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows - (C) Copyright 1992, 1993 by Borland International
- // source\owl\dc.cpp
- // Implementation of TMemoryDC and TDibDC encapsulation classes
- //----------------------------------------------------------------------------
- #include <owl\owlpch.h>
- #include <owl\dc.h>
-
- DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
-
- const int MemDCCacheSize = 2; // Number of mem DCs allocated in the cache
-
- //
- // Cache of screen-compatible memory HDCs used automatically by TMemoryDC when
- // the default ctor is called. Reduces the amount of HDC creations & allows
- // centralized sharing of these memory HDCs
- //
- class TMemDCCache {
- public:
- struct TEntry {
- HDC Handle;
- BOOL Busy;
- };
-
- TMemDCCache(int numEntries);
- ~TMemDCCache();
- HDC Get();
- void Release(HDC hDC);
-
- private:
- TEntry* Entries;
- int NumEntries;
- };
-
- TMemDCCache::TMemDCCache(int numEntries)
- {
- NumEntries = numEntries;
- Entries = new TEntry[NumEntries];
-
- for (int i = 0; i < NumEntries; i++) {
- Entries[i].Handle = ::CreateCompatibleDC(0);
- Entries[i].Busy = FALSE;
- }
- }
-
- TMemDCCache::~TMemDCCache()
- {
- for (int i = 0; i < NumEntries; i++) {
- WARNX(OwlGDI, Entries[i].Busy, 0, "Unreleased DC " <<
- hex << UINT(Entries[i].Handle) << " in MemDCCache");
- if (Entries[i].Handle)
- ::DeleteDC(Entries[i].Handle);
- }
- delete Entries;
- }
-
- HDC
- TMemDCCache::Get()
- {
- for (int i = 0; i < NumEntries; i++)
- if (!Entries[i].Busy) {
- Entries[i].Busy = TRUE;
- return Entries[i].Handle;
- }
- return 0;
- }
-
- void
- TMemDCCache::Release(HDC hDC)
- {
- for (int i = 0; i < NumEntries; i++)
- if (Entries[i].Handle == hDC) {
- WARNX(OwlGDI, !Entries[i].Busy, 0, "Releasing non-busy DC " <<
- hex << UINT(Entries[i].Handle) << " in MemDCCache");
- Entries[i].Busy = FALSE;
- return;
- }
- }
-
- static TMemDCCache MemDCCache(MemDCCacheSize);
-
- //
- // construct a screen-compatible memory DC. Try to get one from the cache first
- //
- TMemoryDC::TMemoryDC() : TCreatedDC()
- {
- Handle = MemDCCache.Get();
- if (Handle)
- ShouldDelete = FALSE;
-
- else {
- Handle = ::CreateCompatibleDC(0);
- CheckValid();
- }
- OrgBitmap = 0;
- }
-
- TMemoryDC::TMemoryDC(const TDC& dc) : TCreatedDC()
- {
- Handle = ::CreateCompatibleDC(dc);
- CheckValid();
- OrgBitmap = 0;
- }
-
- //
- // Use an existing HDC. Delete it on destruction as requested. Allow bitmap
- // selection
- //
- TMemoryDC::TMemoryDC(HDC handle, TAutoDelete autoDelete)
- : TCreatedDC(handle, autoDelete)
- {
- }
-
- void
- TMemoryDC::SelectObject(const TBitmap& bitmap)
- {
- HBITMAP oldBitmap = (HBITMAP)::SelectObject(HDC(Handle), bitmap);
- if (oldBitmap) {
- OBJ_REF_INC(bitmap);
- if ((BOOL)oldBitmap > 1)
- if (!OrgBitmap)
- OrgBitmap = oldBitmap;
- else
- OBJ_REF_DEC(oldBitmap, FALSE);
- }
- }
-
- void
- TMemoryDC::RestoreBitmap()
- {
- if (OrgBitmap) {
- OBJ_REF_DEC(::SelectObject(HDC(Handle), OrgBitmap), FALSE);
- OrgBitmap = 0;
- }
- }
-
- TMemoryDC::~TMemoryDC()
- {
- RestoreBitmap();
- RestoreObjects();
- MemDCCache.Release(HDC(Handle));
- }
-