#ifndef DRAWGDIX_H
#define DRAWGDIX_H
/*******************************************************************
GDI Helper Classes, MFC Version, by G. Bavestrelli, Techint S.p.A.
Any feedback is welcome, you can contact me at:
giovanni.bavestrelli@pomini.it
class CSelStock
class CSelPen
class CSelBrush
class CSelFont
class CSelBitmap
class CSelPalette
class CSelROP2
class CSelBkMode
class CSelBkColor
class CSelTextColor
class CSelTextAlign
class CSelMapMode
class CSaveDC
class CSelStock
CSelStock(CDC * pDC, int index)
void Select(int index)
CGdiObject * Old()
class CSelPen
CSelPen(CDC * pDC, COLORREF col, int sty=PS_SOLID, int wid = 0)
CSelPen(CDC * pDC, CPen * pPen)
void Select(CPen * pPen)
void Select(COLORREF col, int sty=PS_SOLID, int wid = 0)
class CSelBrush
CSelBrush(CDC * pDC, CBrush * pBrush)
CSelBrush(CDC * pDC, COLORREF crColor)
CSelBrush(CDC * pDC, int index, COLORREF crColor) // Hatch brush
CSelBrush(CDC * pDC, CBitmap * pBitmap) // Pattern brush
CSelBrush(CDC * pDC, HGLOBAL hPackedDib, UINT usage) // DIB Pattern brush
void Select(CBrush * pBrush)
void Select(COLORREF col)
void Select(int index, COLORREF col) // Hatch brush
void Select(CBitmap * pBitmap) // Pattern brush
void Select(HGLOBAL hPackedDib, UINT usage) // DIB Pattern brush
class CSelFont
CSelFont(CDC * pDC, int size, LPCTSTR face = NULL, BOOL bold = 0,
BOOL italic = 0, BOOL underlined = 0, BOOL fixed = 0,
BOOL hiquality = 0, int angleindegrees = 0)
CSelFont(CDC * pDC, CFont * pFont)
CSelFont(CDC * pDC, const LOGFONT* lpLogFont)
void Select(int size, LPCTSTR face = NULL, BOOL bold = 0,
BOOL italic = 0, BOOL underlined = 0, BOOL fixed = 0,
BOOL hiquality = 0, int angleindegrees = 0)
void Select(CFont * pFont)
void Select(const LOGFONT* lpLogFont)
class CSelBitmap
CSelBitmap(CDC * pDC, CBitmap * pBitmap)
CSelBitmap(CDC * SelectInDC, CDC * pCompatibleToDC, int w, int h)
void Select(CBitmap * pBitmap)
void Select(CDC * pCompatibleToDC, int w, int h)
class CSelPalette
CSelPalette(CDC * pDC, CPalette * pPalette,
BOOL fForceBackground = FALSE, BOOL fRealize = TRUE)
UINT Select(CPalette * pPalette,
BOOL fForceBackground = FALSE, BOOL fRealize = TRUE)
void ChangeRestoreFlags(BOOL fForceBackground, BOOL fRealize)
class CSelROP2
CSelROP2(CDC * pDC, int drawMode)
void Select(int drawmode)
class CSelBkMode
CSelBkMode(CDC * pDC, int BkMode)
void Select(int bkmode)
class CSelBkColor
CSelBkColor(CDC * pDC, COLORREF BkColor)
void Select(COLORREF color)
class CSelTextColor
CSelTextColor(CDC * pDC, COLORREF TextColor)
void Select(COLORREF color)
class CSelTextAlign
CSelTextAlign(CDC * pDC, UINT TextAlign)
void Select(UINT align)
class CSelMapMode
CSelMapMode(CDC * pDC, int MapMode)
void Select(int mode)
class CSaveDC
CSaveDC(CDC * pDC) // saving the complete state of the DC
every class also have:
<Constructor>(CDC* pDC) // constructor w/o selection
void Restore() // restores original object and destroys new object if neccessary
<retval> Old() // returns original object
*******************************************************************/
//******************************************************************
// Base class, stores CDC *
//******************************************************************
class CSelect
{
protected:
CDC * const m_pDC;
CSelect(CDC * pDC):m_pDC(pDC) { ASSERT(m_pDC);}
virtual ~CSelect() {}
private:
// Disable copying
operator = (const CSelect & d);
CSelect(const CSelect &);
};
//******************************************************************
// Class for Stock Objects
//******************************************************************
class CSelStock : public CSelect
{
CGdiObject * m_pOldObj;
public:
CSelStock(CDC * pDC)
:CSelect(pDC), m_pOldObj(NULL) {}
CSelStock(CDC * pDC, int index)
:CSelect(pDC), m_pOldObj(NULL)
{ Select(index); }
~CSelStock() { Restore(); }
void Select(int index)
{
CGdiObject * pOld = m_pDC->SelectStockObject(index); ASSERT(pOld);
if (!m_pOldObj) m_pOldObj = pOld;
}
void Restore()
{
if (m_pOldObj) VERIFY(m_pDC->SelectObject(m_pOldObj));
m_pOldObj = NULL;
}
CGdiObject * Old() const { return m_pOldObj; }
};
//******************************************************************
// Pens
//******************************************************************
class CSelPen : public CSelect
{
CPen m_NewPen;
CPen * m_pOldPen;
public:
CSelPen(CDC * pDC)
:CSelect(pDC), m_pOldPen(NULL){}
CSelPen(CDC * pDC, COLORREF col, int sty = PS_SOLID, int wid = 0)
:CSelect(pDC), m_pOldPen(NULL)
{ Select(col, sty, wid); }
CSelPen(CDC * pDC, CPen * pPen)
:CSelect(pDC), m_pOldPen(NULL)
{ Select(pPen); }
~CSelPen() { Restore(); }
void Select(CPen * pPen)
{
ASSERT(pPen);
ASSERT(pPen != &m_NewPen);
CPen * pOld = m_pDC->SelectObject(pPen); ASSERT(pOld);
if (!m_pOldPen) m_pOldPen = pOld;
m_NewPen.DeleteObject();
}
void Select(COLORREF col, int sty = PS_SOLID, int wid = 0)
{
if (m_pOldPen) Select(m_pOldPen);
VERIFY(m_NewPen.CreatePen(sty, wid, col));
VERIFY(m_pOldPen = m_pDC->SelectObject(&m_NewPen));
}
void Restore()
{
if (m_pOldPen) VERIFY(m_pDC->SelectObject(m_pOldPen));
m_pOldPen = NULL;
m_NewPen.DeleteObject();
}
CPen * Old() const { return m_pOldPen; }
};
//******************************************************************
// Brushes
//******************************************************************
class CSelBrush : public CSelect
{
CBrush m_NewBrush;
CBrush * m_pOldBrush;
public:
CSelBrush(CDC * pDC)
:CSelect(pDC), m_pOldBrush(NULL) {}
// Solid brush
CSelBrush(CDC * pDC, COLORREF crColor)
:CSelect(pDC), m_pOldBrush(NULL)
{ Select(crColor); }
// Hatch brush
CSelBrush(CDC * pDC, int index, COLORREF crColor)
:CSelect(pDC), m_pOldBrush(NULL)
{ Select(index, crColor); }
// Pattern brush
CSelBrush(CDC * pDC, CBitmap * pBitmap)
:CSelect(pDC), m_pOldBrush(NULL)
{ Select(pBitmap); }
// DIB Pattern brush
CSelBrush(CDC * pDC, HGLOBAL hPackedDib, UINT usage)
:CSelect(pDC), m_pOldBrush(NULL)
{ Select(hPackedDib, usage); }
CSelBrush(CDC * pDC, CBrush * pBrush)
:CSelect(pDC), m_pOldBrush(NULL)
{ Select(pBrush); }
~CSelBrush() { Restore(); }
void Select(CBrush * pBrush)
{
ASSERT(pBrush);
ASSERT(pBrush != &m_NewBrush);
CBrush * pOld = m_pDC->SelectObject(pBrush); ASSERT(pOld);
if (!m_pOldBrush) m_pOldBrush=pOld;
m_NewBrush.DeleteObject();
}
// Solid brush
void Select(COLORREF col)
{
if (m_pOldBrush) Select(m_pOldBrush);
VERIFY(m_NewBrush.CreateSolidBrush(col));
VERIFY(m_pOldBrush = m_pDC->SelectObject(&m_NewBrush));
}
// Hatch brush
void Select(int index, COLORREF col)
{
if (m_pOldBrush) Select(m_pOldBrush);
VERIFY(m_NewBrush.CreateHatchBrush(index, col));
VERIFY(m_pOldBrush = m_pDC->SelectObject(&m_NewBrush));
}
// Pattern brush
void Select(CBitmap * pBitmap)
{
ASSERT(pBitmap);
if (m_pOldBrush) Select(m_pOldBrush);
VERIFY(m_NewBrush.CreatePatternBrush(pBitmap));
VERIFY(m_pOldBrush = m_pDC->SelectObject(&m_NewBrush));
}
// DIB Pattern brush
void Select(HGLOBAL hPackedDib, UINT usage)
{
if (m_pOldBrush) Select(m_pOldBrush);
VERIFY(m_NewBrush.CreateDIBPatternBrush(hPackedDib, usage));
VERIFY(m_pOldBrush=m_pDC->SelectObject(&m_NewBrush));
}
void Restore()
{
if (m_pOldBrush) VERIFY(m_pDC->SelectObject(m_pOldBrush));
m_pOldBrush = NULL;
m_NewBrush.DeleteObject();
}
CBrush * Old() const { return m_pOldBrush; }
};
//******************************************************************
// My own font with different constructor and creation function
//******************************************************************
class CMyFont : public CFont
{
public:
CMyFont(){}
CMyFont(CDC * pDC, int size, LPCTSTR face = NULL, BOOL bold = 0,
BOOL italic = 0, BOOL underlined = 0, BOOL fixed = 0,
BOOL hiquality = 0, int angleindegrees = 0)
{
VERIFY(MyCreateFont(pDC, size, face, bold, italic, underlined,
fixed, hiquality, angleindegrees));
}
BOOL MyCreateFont(CDC * pDC, int size, LPCTSTR face = NULL,
BOOL bold = 0, BOOL italic = 0, BOOL underlined = 0,
BOOL fixed = 0, BOOL hiquality = 0,
int angleindegrees = 0)
{
ASSERT(pDC);
CSize Size(0, MulDiv(size, pDC->GetDeviceCaps(LOGPIXELSY), 72));
pDC->DPtoLP(&Size);
return CreateFont(-abs(Size.cy), 0, 10*angleindegrees, 0,
bold ? FW_BOLD : FW_NORMAL, BYTE(italic),
BYTE(underlined), 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
BYTE(hiquality ? PROOF_QUALITY : DEFAULT_QUALITY),
BYTE(fixed ? FF_MODERN|FIXED_PITCH :
FF_SWISS|VARIABLE_PITCH),
face && *face ? face : NULL);
}
};
//******************************************************************
// Fonts
//******************************************************************
class CSelFont : public CSelect
{
CMyFont m_NewFont;
CFont * m_pOldFont;
public:
CSelFont(CDC * pDC)
: CSelect(pDC), m_pOldFont(NULL) {}
CSelFont(CDC * pDC, int size, LPCTSTR face = NULL, BOOL bold = 0,
BOOL italic = 0, BOOL underlined = 0, BOOL fixed = 0,
BOOL hiquality = 0, int angleindegrees = 0)
: CSelect(pDC), m_pOldFont(NULL)
{
Select(size, face, bold, italic, underlined,
fixed, hiquality, angleindegrees);
}
CSelFont(CDC * pDC, CFont * pFont)
: CSelect(pDC), m_pOldFont(NULL)
{ Select(pFont); }
CSelFont(CDC * pDC, const LOGFONT* lpLogFont)
: CSelect(pDC), m_pOldFont(NULL)
{ Select(lpLogFont); }
~CSelFont() { Restore(); }
void Select(CFont * pFont)
{
ASSERT(pFont);
ASSERT(pFont != &m_NewFont);
CFont * pOld = m_pDC->SelectObject(pFont); ASSERT(pOld);
if (!m_pOldFont) m_pOldFont = pOld;
m_NewFont.DeleteObject();
}
void Select(int size, LPCTSTR face = NULL, BOOL bold = 0,
BOOL italic = 0, BOOL underlined = 0, BOOL fixed = 0,
BOOL hiquality = 0, int angleindegrees = 0)
{
if (m_pOldFont) Select(m_pOldFont);
VERIFY(m_NewFont.MyCreateFont(m_pDC, size, face, bold, italic,
underlined, fixed, hiquality, angleindegrees));
VERIFY(m_pOldFont = m_pDC->SelectObject(&m_NewFont));
}
void Select(const LOGFONT* lpLogFont)
{
if (m_pOldFont) Select(m_pOldFont);
VERIFY(m_NewFont.CreateFontIndirect(lpLogFont));
VERIFY(m_pOldFont = m_pDC->SelectObject(&m_NewFont));
}
void Restore()
{
if (m_pOldFont) VERIFY(m_pDC->SelectObject(m_pOldFont));
m_pOldFont = NULL;
m_NewFont.DeleteObject();
}
CFont * Old() const { return m_pOldFont; }
};
//******************************************************************
// Bitmaps
//******************************************************************
class CSelBitmap : public CSelect
{
CBitmap m_NewBmp;
CBitmap * m_pOldBmp;
public:
CSelBitmap(CDC * pDC)
: CSelect(pDC), m_pOldBmp(NULL) {}
CSelBitmap(CDC * SelectInDC, CDC * pCompatibleToDC, int w, int h)
: CSelect(SelectInDC), m_pOldBmp(NULL)
{ Select(pCompatibleToDC, w, h); }
CSelBitmap(CDC * pDC, CBitmap * pBitmap)
: CSelect(pDC), m_pOldBmp(NULL)
{ Select(pBitmap); }
~CSelBitmap() { Restore(); }
void Select(CBitmap * pBitmap)
{
ASSERT(pBitmap);
ASSERT(pBitmap != &m_NewBmp);
CBitmap * pOld = m_pDC->SelectObject(pBitmap); ASSERT(pOld);
if (!m_pOldBmp) m_pOldBmp = pOld;
m_NewBmp.DeleteObject();
}
void Select(CDC * pCompatibleToDC, int w, int h)
{
ASSERT(pCompatibleToDC);
if (m_pOldBmp) Select(m_pOldBmp);
VERIFY(m_NewBmp.CreateCompatibleBitmap(pCompatibleToDC, w, h));
VERIFY(m_pOldBmp = m_pDC->SelectObject(&m_NewBmp));
}
void Restore()
{
if (m_pOldBmp) VERIFY(m_pDC->SelectObject(m_pOldBmp));
m_pOldBmp = NULL;
m_NewBmp.DeleteObject();
}
CBitmap * Old() const { return m_pOldBmp; }
};
// This class is a bit different
class CSelPalette : public CSelect
{
// You need your own palette, use CPalette
CPalette * m_pOldPalette;
BOOL m_fForceBackground;
BOOL m_fRealizePalette;
public:
CSelPalette(CDC * pDC)
: CSelect(pDC), m_pOldPalette(NULL) {}
CSelPalette(CDC * pDC, CPalette * pPalette,
BOOL fForceBackground = FALSE, BOOL fRealize = TRUE)
: CSelect(pDC), m_pOldPalette(NULL)
{ Select(pPalette, fForceBackground, fRealize); }
~CSelPalette() { Restore(); }
UINT Select(CPalette * pPalette,
BOOL fForceBackground = FALSE, BOOL fRealize = TRUE)
{
ASSERT(pPalette);
ASSERT(m_pDC->GetDeviceCaps(RASTERCAPS)&RC_PALETTE);
CPalette * pOld=m_pDC->SelectPalette(pPalette, fForceBackground);
ASSERT(pOld);
if (!m_pOldPalette) m_pOldPalette=pOld;
m_fForceBackground = fForceBackground;
m_fRealizePalette = fRealize;
return fRealize ? m_pDC->RealizePalette() : 0;
}
void ChangeRestoreFlags(BOOL fForceBackground, BOOL fRealize)
{
m_fForceBackground = fForceBackground;
m_fRealizePalette = fRealize;
}
void Restore()
{
if (!m_pOldPalette)
return;
VERIFY(m_pDC->SelectPalette(m_pOldPalette, m_fForceBackground));
if (m_fRealizePalette)
m_pDC->RealizePalette();
m_pOldPalette = NULL;
}
CPalette * Old() const { return m_pOldPalette; }
};
//******************************************************************
// Set and restore other characteristics of the DC (no GDI objects)
//******************************************************************
class CSelROP2 : public CSelect
{
int m_OldRop;
public:
CSelROP2(CDC * pDC)
: CSelect(pDC), m_OldRop(0)
{ /*VERIFY(m_OldRop=m_pDC->GetROP2());*/ }
CSelROP2(CDC * pDC, int drawMode)
: CSelect(pDC), m_OldRop(0)
{ Select(drawMode); }
~CSelROP2() { Restore(); }
void Select(int drawmode)
{
int old = m_pDC->SetROP2(drawmode); ASSERT(old);
if (!m_OldRop) m_OldRop = old;
}
void Restore()
{
if (m_OldRop) VERIFY(m_pDC->SetROP2(m_OldRop));
m_OldRop = 0;
}
int Old() const { return m_OldRop; }
};
class CSelBkMode : public CSelect
{
int m_OldBkMode;
public:
CSelBkMode(CDC * pDC)
: CSelect(pDC), m_OldBkMode(0)
{ /*VERIFY(m_OldBkMode = m_pDC->GetBkMode());*/ }
CSelBkMode(CDC * pDC, int BkMode)
: CSelect(pDC), m_OldBkMode(0)
{ Select(BkMode); }
~CSelBkMode() { Restore(); }
void Select(int BkMode)
{
int old = m_pDC->SetBkMode(BkMode); ASSERT(old);
if (!m_OldBkMode) m_OldBkMode = old;
}
void Restore()
{
if (m_OldBkMode) VERIFY(m_pDC->SetBkMode(m_OldBkMode));
m_OldBkMode = 0;
}
int Old() const { return m_OldBkMode; }
};
class CSelBkColor : public CSelect
{
COLORREF m_OldBkColor;
public:
CSelBkColor(CDC * pDC)
: CSelect(pDC), m_OldBkColor(CLR_INVALID)
{ m_OldBkColor = m_pDC->GetBkColor(); }
CSelBkColor(CDC * pDC, COLORREF BkColor)
:CSelect(pDC), m_OldBkColor(CLR_INVALID)
{ Select(BkColor); }
~CSelBkColor() { Restore(); }
void Select(COLORREF color)
{
ASSERT(color != CLR_INVALID);
int old = m_pDC->SetBkColor(color); ASSERT(old != CLR_INVALID);
if (m_OldBkColor == CLR_INVALID) m_OldBkColor = old;
}
void Restore()
{
if(m_OldBkColor == CLR_INVALID) return;
VERIFY(m_pDC->SetBkColor(m_OldBkColor) != CLR_INVALID);
m_OldBkColor = CLR_INVALID;
}
COLORREF Old() const { return m_OldBkColor; }
};
class CSelTextColor : public CSelect
{
COLORREF m_OldTextColor;
public:
CSelTextColor(CDC * pDC)
: CSelect(pDC), m_OldTextColor(CLR_INVALID)
{ m_OldTextColor = m_pDC->GetTextColor(); }
CSelTextColor(CDC * pDC, COLORREF TextColor)
:CSelect(pDC), m_OldTextColor(CLR_INVALID)
{ Select(TextColor); }
~CSelTextColor() { Restore(); }
void Select(COLORREF color)
{
ASSERT(color != CLR_INVALID);
int old = m_pDC->SetTextColor(color); ASSERT(old != CLR_INVALID);
if (m_OldTextColor == CLR_INVALID) m_OldTextColor = old;
}
void Restore()
{
if(m_OldTextColor == CLR_INVALID) return;
VERIFY(m_pDC->SetTextColor(m_OldTextColor) != CLR_INVALID);
m_OldTextColor = CLR_INVALID;
}
COLORREF Old() const { return m_OldTextColor; }
};
class CSelTextAlign : public CSelect
{
UINT m_OldTextAlign;
public:
CSelTextAlign(CDC * pDC)
: CSelect(pDC), m_OldTextAlign(GDI_ERROR)
{ m_OldTextAlign = m_pDC->GetTextAlign(); }
CSelTextAlign(CDC * pDC, UINT TextAlign)
: CSelect(pDC), m_OldTextAlign(GDI_ERROR)
{ Select(TextAlign); }
~CSelTextAlign() { Restore(); }
void Select(UINT align)
{
ASSERT(align != GDI_ERROR);
int old = m_pDC->SetTextAlign(align); ASSERT(old != GDI_ERROR);
if (m_OldTextAlign == GDI_ERROR) m_OldTextAlign = old;
}
void Restore()
{
if(m_OldTextAlign == GDI_ERROR) return;
VERIFY(m_pDC->SetTextAlign(m_OldTextAlign) != GDI_ERROR);
m_OldTextAlign = GDI_ERROR;
}
UINT Old() const { return m_OldTextAlign; }
};
class CSelMapMode : public CSelect
{
int m_OldMapMode;
public:
CSelMapMode(CDC * pDC)
: CSelect(pDC), m_OldMapMode(0)
{ /*VERIFY(m_OldMapMode = m_pDC->GetMapMode());*/ }
CSelMapMode(CDC * pDC, int MapMode)
: CSelect(pDC), m_OldMapMode(0)
{ Select(MapMode); }
~CSelMapMode() { Restore(); }
void Select(int MapMode)
{
int old = m_pDC->SetMapMode(MapMode); ASSERT(old);
if (!m_OldMapMode) m_OldMapMode = old;
}
void Restore()
{
if (m_OldMapMode) VERIFY(m_pDC->SetMapMode(m_OldMapMode));
m_OldMapMode = 0;
}
UINT Old() const { return m_OldMapMode; }
};
//******************************************************************
// Class for saving the complete state of the DC
//******************************************************************
class CSaveDC : public CSelect
{
int m_SavedDC;
public:
CSaveDC(CDC * pDC)
: CSelect(pDC)
{ VERIFY(m_SavedDC = m_pDC->SaveDC()); }
~CSaveDC() { Restore(); }
void Restore()
{
if (m_SavedDC) VERIFY(m_pDC->RestoreDC(m_SavedDC));
m_SavedDC = 0;
}
int Old() const { return m_SavedDC; }
};
#endif