blob: 510f1e7436f336434c9f02ddc8c37f06e3115ce3 [file] [log] [blame]
// Windows Template Library - WTL version 8.0
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This file is a part of the Windows Template Library.
// The use and distribution terms for this software are covered by the
// Microsoft Permissive License (Ms-PL) which can be found in the file
// Ms-PL.txt at the root of this distribution.
#ifndef __ATLGDI_H__
#define __ATLGDI_H__
#pragma once
#ifndef __cplusplus
#error ATL requires C++ compilation (use a .cpp suffix)
#endif
#ifndef __ATLAPP_H__
#error atlgdi.h requires atlapp.h to be included first
#endif
// protect template members from windowsx.h macros
#ifdef _INC_WINDOWSX
#undef CopyRgn
#undef CreateBrush
#undef CreatePen
#undef SelectBrush
#undef SelectPen
#undef SelectFont
#undef SelectBitmap
#endif // _INC_WINDOWSX
// required libraries
#if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE)
#pragma comment(lib, "msimg32.lib")
#endif // !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE)
#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
#pragma comment(lib, "opengl32.lib")
#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
///////////////////////////////////////////////////////////////////////////////
// Classes in this file:
//
// CPenT<t_bManaged>
// CBrushT<t_bManaged>
// CLogFont
// CFontT<t_bManaged>
// CBitmapT<t_bManaged>
// CPaletteT<t_bManaged>
// CRgnT<t_bManaged>
// CDCT<t_bManaged>
// CPaintDC
// CClientDC
// CWindowDC
// CMemoryDC
// CEnhMetaFileInfo
// CEnhMetaFileT<t_bManaged>
// CEnhMetaFileDC
//
// Global functions:
// AtlGetBitmapResourceInfo()
// AtlGetBitmapResourceBitsPerPixel()
// AtlIsAlphaBitmapResource()
// AtlIsDib16()
// AtlGetDibColorTableSize()
// AtlGetDibNumColors(),
// AtlGetDibBitmap()
// AtlCopyBitmap()
// AtlCreatePackedDib16()
// AtlSetClipboardDib16()
// AtlGetClipboardDib()
namespace WTL
{
///////////////////////////////////////////////////////////////////////////////
// Bitmap resource helpers to extract bitmap information for a bitmap resource
inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image)
{
HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP);
ATLASSERT(hResource != NULL);
HGLOBAL hGlobal = ::LoadResource(hModule, hResource);
ATLASSERT(hGlobal != NULL);
LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal);
ATLASSERT(pBitmapInfoHeader != NULL);
return pBitmapInfoHeader;
}
inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image)
{
LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image);
ATLASSERT(pBitmapInfoHeader != NULL);
return pBitmapInfoHeader->biBitCount;
}
inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image)
{
return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image);
}
///////////////////////////////////////////////////////////////////////////////
// 32-bit (alpha channel) bitmap resource helper
// Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6.
// If you want your app to work on older version of Windows, load non-alpha images if Common
// Controls version is less than 6.
inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image)
{
return (AtlGetBitmapResourceBitsPerPixel(image) == 32);
}
///////////////////////////////////////////////////////////////////////////////
// CPen
template <bool t_bManaged>
class CPenT
{
public:
// Data members
HPEN m_hPen;
// Constructor/destructor/operators
CPenT(HPEN hPen = NULL) : m_hPen(hPen)
{ }
~CPenT()
{
if(t_bManaged && m_hPen != NULL)
DeleteObject();
}
CPenT<t_bManaged>& operator =(HPEN hPen)
{
Attach(hPen);
return *this;
}
void Attach(HPEN hPen)
{
if(t_bManaged && m_hPen != NULL && m_hPen != hPen)
::DeleteObject(m_hPen);
m_hPen = hPen;
}
HPEN Detach()
{
HPEN hPen = m_hPen;
m_hPen = NULL;
return hPen;
}
operator HPEN() const { return m_hPen; }
bool IsNull() const { return (m_hPen == NULL); }
// Create methods
HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
{
ATLASSERT(m_hPen == NULL);
m_hPen = ::CreatePen(nPenStyle, nWidth, crColor);
return m_hPen;
}
#ifndef _WIN32_WCE
HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL)
{
ATLASSERT(m_hPen == NULL);
m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
return m_hPen;
}
#endif // !_WIN32_WCE
HPEN CreatePenIndirect(LPLOGPEN lpLogPen)
{
ATLASSERT(m_hPen == NULL);
m_hPen = ::CreatePenIndirect(lpLogPen);
return m_hPen;
}
BOOL DeleteObject()
{
ATLASSERT(m_hPen != NULL);
BOOL bRet = ::DeleteObject(m_hPen);
if(bRet)
m_hPen = NULL;
return bRet;
}
// Attributes
int GetLogPen(LOGPEN* pLogPen) const
{
ATLASSERT(m_hPen != NULL);
return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen);
}
bool GetLogPen(LOGPEN& LogPen) const
{
ATLASSERT(m_hPen != NULL);
return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN));
}
#ifndef _WIN32_WCE
int GetExtLogPen(EXTLOGPEN* pLogPen) const
{
ATLASSERT(m_hPen != NULL);
return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen);
}
bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const
{
ATLASSERT(m_hPen != NULL);
return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN));
}
#endif // !_WIN32_WCE
};
typedef CPenT<false> CPenHandle;
typedef CPenT<true> CPen;
///////////////////////////////////////////////////////////////////////////////
// CBrush
template <bool t_bManaged>
class CBrushT
{
public:
// Data members
HBRUSH m_hBrush;
// Constructor/destructor/operators
CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush)
{ }
~CBrushT()
{
if(t_bManaged && m_hBrush != NULL)
DeleteObject();
}
CBrushT<t_bManaged>& operator =(HBRUSH hBrush)
{
Attach(hBrush);
return *this;
}
void Attach(HBRUSH hBrush)
{
if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush)
::DeleteObject(m_hBrush);
m_hBrush = hBrush;
}
HBRUSH Detach()
{
HBRUSH hBrush = m_hBrush;
m_hBrush = NULL;
return hBrush;
}
operator HBRUSH() const { return m_hBrush; }
bool IsNull() const { return (m_hBrush == NULL); }
// Create methods
HBRUSH CreateSolidBrush(COLORREF crColor)
{
ATLASSERT(m_hBrush == NULL);
m_hBrush = ::CreateSolidBrush(crColor);
return m_hBrush;
}
#ifndef _WIN32_WCE
HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor)
{
ATLASSERT(m_hBrush == NULL);
m_hBrush = ::CreateHatchBrush(nIndex, crColor);
return m_hBrush;
}
#endif // !_WIN32_WCE
#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush)
{
ATLASSERT(m_hBrush == NULL);
#ifndef _WIN32_WCE
m_hBrush = ::CreateBrushIndirect(lpLogBrush);
#else // CE specific
m_hBrush = ATL::CreateBrushIndirect(lpLogBrush);
#endif // _WIN32_WCE
return m_hBrush;
}
#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
HBRUSH CreatePatternBrush(HBITMAP hBitmap)
{
ATLASSERT(m_hBrush == NULL);
m_hBrush = ::CreatePatternBrush(hBitmap);
return m_hBrush;
}
HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage)
{
ATLASSERT(hPackedDIB != NULL);
const void* lpPackedDIB = GlobalLock(hPackedDIB);
ATLASSERT(lpPackedDIB != NULL);
m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
GlobalUnlock(hPackedDIB);
return m_hBrush;
}
HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage)
{
ATLASSERT(m_hBrush == NULL);
m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
return m_hBrush;
}
HBRUSH CreateSysColorBrush(int nIndex)
{
ATLASSERT(m_hBrush == NULL);
m_hBrush = ::GetSysColorBrush(nIndex);
return m_hBrush;
}
BOOL DeleteObject()
{
ATLASSERT(m_hBrush != NULL);
BOOL bRet = ::DeleteObject(m_hBrush);
if(bRet)
m_hBrush = NULL;
return bRet;
}
// Attributes
int GetLogBrush(LOGBRUSH* pLogBrush) const
{
ATLASSERT(m_hBrush != NULL);
return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush);
}
bool GetLogBrush(LOGBRUSH& LogBrush) const
{
ATLASSERT(m_hBrush != NULL);
return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH));
}
};
typedef CBrushT<false> CBrushHandle;
typedef CBrushT<true> CBrush;
///////////////////////////////////////////////////////////////////////////////
// CFont
class CLogFont : public LOGFONT
{
public:
CLogFont()
{
memset(this, 0, sizeof(LOGFONT));
}
CLogFont(const LOGFONT& lf)
{
Copy(&lf);
}
CLogFont(HFONT hFont)
{
ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
}
HFONT CreateFontIndirect()
{
return ::CreateFontIndirect(this);
}
void SetBold()
{
lfWeight = FW_BOLD;
}
bool IsBold() const
{
return (lfWeight >= FW_BOLD);
}
void MakeBolder(int iScale = 1)
{
lfWeight += FW_BOLD * iScale;
}
void MakeLarger(int iScale)
{
if(lfHeight > 0)
lfHeight += iScale;
else
lfHeight -= iScale;
}
void SetHeight(LONG nPointSize, HDC hDC = NULL)
{
// For MM_TEXT mapping mode
lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
}
LONG GetHeight(HDC hDC = NULL) const
{
// For MM_TEXT mapping mode
return ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC, LOGPIXELSY));
}
LONG GetDeciPointHeight(HDC hDC = NULL) const
{
#ifndef _WIN32_WCE
POINT ptOrg = { 0, 0 };
::DPtoLP(hDC, &ptOrg, 1);
POINT pt = { 0, 0 };
pt.y = abs(lfHeight) + ptOrg.y;
::LPtoDP(hDC,&pt,1);
return ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
#else // CE specific
// DP and LP are always the same on CE
return ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
}
void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL)
{
#ifndef _WIN32_WCE
POINT pt = { 0, 0 };
pt.y = ::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point
::DPtoLP(hDC, &pt, 1);
POINT ptOrg = { 0, 0 };
::DPtoLP(hDC, &ptOrg, 1);
lfHeight = -abs(pt.y - ptOrg.y);
#else // CE specific
// DP and LP are always the same on CE
lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
}
#ifndef _WIN32_WCE
void SetCaptionFont()
{
NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
Copy(&ncm.lfCaptionFont);
}
void SetMenuFont()
{
NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
Copy(&ncm.lfMenuFont);
}
void SetStatusFont()
{
NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
Copy(&ncm.lfStatusFont);
}
void SetMessageBoxFont()
{
NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() };
ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
Copy(&ncm.lfMessageFont);
}
#endif // !_WIN32_WCE
void Copy(const LOGFONT* pLogFont)
{
ATLASSERT(pLogFont != NULL);
*(LOGFONT*)this = *pLogFont;
}
CLogFont& operator =(const CLogFont& src)
{
Copy(&src);
return *this;
}
CLogFont& operator =(const LOGFONT& src)
{
Copy(&src);
return *this;
}
CLogFont& operator =(HFONT hFont)
{
ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
return *this;
}
bool operator ==(const LOGFONT& logfont) const
{
return(logfont.lfHeight == lfHeight &&
logfont.lfWidth == lfWidth &&
logfont.lfEscapement == lfEscapement &&
logfont.lfOrientation == lfOrientation &&
logfont.lfWeight == lfWeight &&
logfont.lfItalic == lfItalic &&
logfont.lfUnderline == lfUnderline &&
logfont.lfStrikeOut == lfStrikeOut &&
logfont.lfCharSet == lfCharSet &&
logfont.lfOutPrecision == lfOutPrecision &&
logfont.lfClipPrecision == lfClipPrecision &&
logfont.lfQuality == lfQuality &&
logfont.lfPitchAndFamily == lfPitchAndFamily &&
lstrcmp(logfont.lfFaceName, lfFaceName) == 0);
}
};
template <bool t_bManaged>
class CFontT
{
public:
// Data members
HFONT m_hFont;
// Constructor/destructor/operators
CFontT(HFONT hFont = NULL) : m_hFont(hFont)
{ }
~CFontT()
{
if(t_bManaged && m_hFont != NULL)
DeleteObject();
}
CFontT<t_bManaged>& operator =(HFONT hFont)
{
Attach(hFont);
return *this;
}
void Attach(HFONT hFont)
{
if(t_bManaged && m_hFont != NULL && m_hFont != hFont)
::DeleteObject(m_hFont);
m_hFont = hFont;
}
HFONT Detach()
{
HFONT hFont = m_hFont;
m_hFont = NULL;
return hFont;
}
operator HFONT() const { return m_hFont; }
bool IsNull() const { return (m_hFont == NULL); }
// Create methods
HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
{
ATLASSERT(m_hFont == NULL);
m_hFont = ::CreateFontIndirect(lpLogFont);
return m_hFont;
}
#if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex)
{
ATLASSERT(m_hFont == NULL);
m_hFont = ::CreateFontIndirectEx(penumlfex);
return m_hFont;
}
#endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500)
#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename)
{
ATLASSERT(m_hFont == NULL);
#ifndef _WIN32_WCE
m_hFont = ::CreateFont(nHeight, nWidth, nEscapement,
nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
nCharSet, nOutPrecision, nClipPrecision, nQuality,
nPitchAndFamily, lpszFacename);
#else // CE specific
m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement,
nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
nCharSet, nOutPrecision, nClipPrecision, nQuality,
nPitchAndFamily, lpszFacename);
#endif // _WIN32_WCE
return m_hFont;
}
#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800)
HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false)
{
LOGFONT logFont = { 0 };
logFont.lfCharSet = DEFAULT_CHARSET;
logFont.lfHeight = nPointSize;
SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE);
if(bBold)
logFont.lfWeight = FW_BOLD;
if(bItalic)
logFont.lfItalic = (BYTE)TRUE;
return CreatePointFontIndirect(&logFont, hDC);
}
HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL)
{
HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL);
// convert nPointSize to logical units based on hDC
LOGFONT logFont = *lpLogFont;
#ifndef _WIN32_WCE
POINT pt = { 0, 0 };
pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point
::DPtoLP(hDC1, &pt, 1);
POINT ptOrg = { 0, 0 };
::DPtoLP(hDC1, &ptOrg, 1);
logFont.lfHeight = -abs(pt.y - ptOrg.y);
#else // CE specific
// DP and LP are always the same on CE
logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
if(hDC == NULL)
::ReleaseDC(NULL, hDC1);
return CreateFontIndirect(&logFont);
}
BOOL DeleteObject()
{
ATLASSERT(m_hFont != NULL);
BOOL bRet = ::DeleteObject(m_hFont);
if(bRet)
m_hFont = NULL;
return bRet;
}
// Attributes
int GetLogFont(LOGFONT* pLogFont) const
{
ATLASSERT(m_hFont != NULL);
return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
}
bool GetLogFont(LOGFONT& LogFont) const
{
ATLASSERT(m_hFont != NULL);
return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
}
};
typedef CFontT<false> CFontHandle;
typedef CFontT<true> CFont;
///////////////////////////////////////////////////////////////////////////////
// CBitmap
template <bool t_bManaged>
class CBitmapT
{
public:
// Data members
HBITMAP m_hBitmap;
// Constructor/destructor/operators
CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap)
{ }
~CBitmapT()
{
if(t_bManaged && m_hBitmap != NULL)
DeleteObject();
}
CBitmapT<t_bManaged>& operator =(HBITMAP hBitmap)
{
Attach(hBitmap);
return *this;
}
void Attach(HBITMAP hBitmap)
{
if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap)
::DeleteObject(m_hBitmap);
m_hBitmap = hBitmap;
}
HBITMAP Detach()
{
HBITMAP hBitmap = m_hBitmap;
m_hBitmap = NULL;
return hBitmap;
}
operator HBITMAP() const { return m_hBitmap; }
bool IsNull() const { return (m_hBitmap == NULL); }
// Create and load methods
HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
return m_hBitmap;
}
HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
return m_hBitmap;
}
#ifndef _WIN32_WCE
HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
return m_hBitmap;
}
#endif // !_WIN32_WCE
HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
return m_hBitmap;
}
#ifndef _WIN32_WCE
HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateBitmapIndirect(lpBitmap);
return m_hBitmap;
}
#endif // !_WIN32_WCE
HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
return m_hBitmap;
}
#ifndef _WIN32_WCE
HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight);
return m_hBitmap;
}
#endif // !_WIN32_WCE
BOOL DeleteObject()
{
ATLASSERT(m_hBitmap != NULL);
BOOL bRet = ::DeleteObject(m_hBitmap);
if(bRet)
m_hBitmap = NULL;
return bRet;
}
// Attributes
int GetBitmap(BITMAP* pBitMap) const
{
ATLASSERT(m_hBitmap != NULL);
return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
}
bool GetBitmap(BITMAP& bm) const
{
ATLASSERT(m_hBitmap != NULL);
return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
}
bool GetSize(SIZE& size) const
{
ATLASSERT(m_hBitmap != NULL);
BITMAP bm = { 0 };
if(!GetBitmap(&bm))
return false;
size.cx = bm.bmWidth;
size.cy = bm.bmHeight;
return true;
}
#ifndef _WIN32_WCE
DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const
{
ATLASSERT(m_hBitmap != NULL);
return ::GetBitmapBits(m_hBitmap, dwCount, lpBits);
}
#endif // !_WIN32_WCE
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
DWORD SetBitmapBits(DWORD dwCount, const void* lpBits)
{
ATLASSERT(m_hBitmap != NULL);
return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
#ifndef _WIN32_WCE
BOOL GetBitmapDimension(LPSIZE lpSize) const
{
ATLASSERT(m_hBitmap != NULL);
return ::GetBitmapDimensionEx(m_hBitmap, lpSize);
}
BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL)
{
ATLASSERT(m_hBitmap != NULL);
return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize);
}
// DIB support
HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
return m_hBitmap;
}
#endif // !_WIN32_WCE
HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
{
ATLASSERT(m_hBitmap == NULL);
m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
return m_hBitmap;
}
#ifndef _WIN32_WCE
int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
{
ATLASSERT(m_hBitmap != NULL);
return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
}
int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
{
ATLASSERT(m_hBitmap != NULL);
return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
}
#endif // !_WIN32_WCE
};
typedef CBitmapT<false> CBitmapHandle;
typedef CBitmapT<true> CBitmap;
///////////////////////////////////////////////////////////////////////////////
// CPalette
template <bool t_bManaged>
class CPaletteT
{
public:
// Data members
HPALETTE m_hPalette;
// Constructor/destructor/operators
CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette)
{ }
~CPaletteT()
{
if(t_bManaged && m_hPalette != NULL)
DeleteObject();
}
CPaletteT<t_bManaged>& operator =(HPALETTE hPalette)
{
Attach(hPalette);
return *this;
}
void Attach(HPALETTE hPalette)
{
if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette)
::DeleteObject(m_hPalette);
m_hPalette = hPalette;
}
HPALETTE Detach()
{
HPALETTE hPalette = m_hPalette;
m_hPalette = NULL;
return hPalette;
}
operator HPALETTE() const { return m_hPalette; }
bool IsNull() const { return (m_hPalette == NULL); }
// Create methods
HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette)
{
ATLASSERT(m_hPalette == NULL);
m_hPalette = ::CreatePalette(lpLogPalette);
return m_hPalette;
}
#ifndef _WIN32_WCE
HPALETTE CreateHalftonePalette(HDC hDC)
{
ATLASSERT(m_hPalette == NULL);
ATLASSERT(hDC != NULL);
m_hPalette = ::CreateHalftonePalette(hDC);
return m_hPalette;
}
#endif // !_WIN32_WCE
BOOL DeleteObject()
{
ATLASSERT(m_hPalette != NULL);
BOOL bRet = ::DeleteObject(m_hPalette);
if(bRet)
m_hPalette = NULL;
return bRet;
}
// Attributes
int GetEntryCount() const
{
ATLASSERT(m_hPalette != NULL);
WORD nEntries = 0;
::GetObject(m_hPalette, sizeof(WORD), &nEntries);
return (int)nEntries;
}
UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
{
ATLASSERT(m_hPalette != NULL);
return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
}
UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
{
ATLASSERT(m_hPalette != NULL);
return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
}
// Operations
#ifndef _WIN32_WCE
void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
{
ATLASSERT(m_hPalette != NULL);
::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors);
}
BOOL ResizePalette(UINT nNumEntries)
{
ATLASSERT(m_hPalette != NULL);
return ::ResizePalette(m_hPalette, nNumEntries);
}
#endif // !_WIN32_WCE
UINT GetNearestPaletteIndex(COLORREF crColor) const
{
ATLASSERT(m_hPalette != NULL);
return ::GetNearestPaletteIndex(m_hPalette, crColor);
}
};
typedef CPaletteT<false> CPaletteHandle;
typedef CPaletteT<true> CPalette;
///////////////////////////////////////////////////////////////////////////////
// CRgn
template <bool t_bManaged>
class CRgnT
{
public:
// Data members
HRGN m_hRgn;
// Constructor/destructor/operators
CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn)
{ }
~CRgnT()
{
if(t_bManaged && m_hRgn != NULL)
DeleteObject();
}
CRgnT<t_bManaged>& operator =(HRGN hRgn)
{
Attach(hRgn);
return *this;
}
void Attach(HRGN hRgn)
{
if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn)
::DeleteObject(m_hRgn);
m_hRgn = hRgn;
}
HRGN Detach()
{
HRGN hRgn = m_hRgn;
m_hRgn = NULL;
return hRgn;
}
operator HRGN() const { return m_hRgn; }
bool IsNull() const { return (m_hRgn == NULL); }
// Create methods
HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
return m_hRgn;
}
HRGN CreateRectRgnIndirect(LPCRECT lpRect)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreateRectRgnIndirect(lpRect);
return m_hRgn;
}
#ifndef _WIN32_WCE
HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
return m_hRgn;
}
HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
return m_hRgn;
}
HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
return m_hRgn;
}
HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
return m_hRgn;
}
HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
return m_hRgn;
}
HRGN CreateFromPath(HDC hDC)
{
ATLASSERT(m_hRgn == NULL);
ATLASSERT(hDC != NULL);
m_hRgn = ::PathToRegion(hDC);
return m_hRgn;
}
HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
{
ATLASSERT(m_hRgn == NULL);
m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
return m_hRgn;
}
#endif // !_WIN32_WCE
BOOL DeleteObject()
{
ATLASSERT(m_hRgn != NULL);
BOOL bRet = ::DeleteObject(m_hRgn);
if(bRet)
m_hRgn = NULL;
return bRet;
}
// Operations
void SetRectRgn(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hRgn != NULL);
::SetRectRgn(m_hRgn, x1, y1, x2, y2);
}
void SetRectRgn(LPCRECT lpRect)
{
ATLASSERT(m_hRgn != NULL);
::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
}
int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
{
ATLASSERT(m_hRgn != NULL);
return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
}
int CombineRgn(HRGN hRgnSrc, int nCombineMode)
{
ATLASSERT(m_hRgn != NULL);
return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
}
int CopyRgn(HRGN hRgnSrc)
{
ATLASSERT(m_hRgn != NULL);
return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
}
BOOL EqualRgn(HRGN hRgn) const
{
ATLASSERT(m_hRgn != NULL);
return ::EqualRgn(m_hRgn, hRgn);
}
int OffsetRgn(int x, int y)
{
ATLASSERT(m_hRgn != NULL);
return ::OffsetRgn(m_hRgn, x, y);
}
int OffsetRgn(POINT point)
{
ATLASSERT(m_hRgn != NULL);
return ::OffsetRgn(m_hRgn, point.x, point.y);
}
int GetRgnBox(LPRECT lpRect) const
{
ATLASSERT(m_hRgn != NULL);
return ::GetRgnBox(m_hRgn, lpRect);
}
BOOL PtInRegion(int x, int y) const
{
ATLASSERT(m_hRgn != NULL);
return ::PtInRegion(m_hRgn, x, y);
}
BOOL PtInRegion(POINT point) const
{
ATLASSERT(m_hRgn != NULL);
return ::PtInRegion(m_hRgn, point.x, point.y);
}
BOOL RectInRegion(LPCRECT lpRect) const
{
ATLASSERT(m_hRgn != NULL);
return ::RectInRegion(m_hRgn, lpRect);
}
int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
{
ATLASSERT(m_hRgn != NULL);
return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
}
};
typedef CRgnT<false> CRgnHandle;
typedef CRgnT<true> CRgn;
///////////////////////////////////////////////////////////////////////////////
// CDC - The device context class
template <bool t_bManaged>
class CDCT
{
public:
// Data members
HDC m_hDC;
// Constructor/destructor/operators
CDCT(HDC hDC = NULL) : m_hDC(hDC)
{
}
~CDCT()
{
if(t_bManaged && m_hDC != NULL)
::DeleteDC(Detach());
}
CDCT<t_bManaged>& operator =(HDC hDC)
{
Attach(hDC);
return *this;
}
void Attach(HDC hDC)
{
if(t_bManaged && m_hDC != NULL && m_hDC != hDC)
::DeleteDC(m_hDC);
m_hDC = hDC;
}
HDC Detach()
{
HDC hDC = m_hDC;
m_hDC = NULL;
return hDC;
}
operator HDC() const { return m_hDC; }
bool IsNull() const { return (m_hDC == NULL); }
// Operations
#ifndef _WIN32_WCE
HWND WindowFromDC() const
{
ATLASSERT(m_hDC != NULL);
return ::WindowFromDC(m_hDC);
}
#endif // !_WIN32_WCE
CPenHandle GetCurrentPen() const
{
ATLASSERT(m_hDC != NULL);
return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN));
}
CBrushHandle GetCurrentBrush() const
{
ATLASSERT(m_hDC != NULL);
return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH));
}
CPaletteHandle GetCurrentPalette() const
{
ATLASSERT(m_hDC != NULL);
return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL));
}
CFontHandle GetCurrentFont() const
{
ATLASSERT(m_hDC != NULL);
return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT));
}
CBitmapHandle GetCurrentBitmap() const
{
ATLASSERT(m_hDC != NULL);
return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP));
}
HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData)
{
ATLASSERT(m_hDC == NULL);
m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
return m_hDC;
}
HDC CreateCompatibleDC(HDC hDC = NULL)
{
ATLASSERT(m_hDC == NULL);
m_hDC = ::CreateCompatibleDC(hDC);
return m_hDC;
}
BOOL DeleteDC()
{
if(m_hDC == NULL)
return FALSE;
BOOL bRet = ::DeleteDC(m_hDC);
if(bRet)
m_hDC = NULL;
return bRet;
}
// Device-Context Functions
int SaveDC()
{
ATLASSERT(m_hDC != NULL);
return ::SaveDC(m_hDC);
}
BOOL RestoreDC(int nSavedDC)
{
ATLASSERT(m_hDC != NULL);
return ::RestoreDC(m_hDC, nSavedDC);
}
int GetDeviceCaps(int nIndex) const
{
ATLASSERT(m_hDC != NULL);
return ::GetDeviceCaps(m_hDC, nIndex);
}
#ifndef _WIN32_WCE
UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags)
{
ATLASSERT(m_hDC != NULL);
return ::SetBoundsRect(m_hDC, lpRectBounds, flags);
}
UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const
{
ATLASSERT(m_hDC != NULL);
return ::GetBoundsRect(m_hDC, lpRectBounds, flags);
}
BOOL ResetDC(const DEVMODE* lpDevMode)
{
ATLASSERT(m_hDC != NULL);
return ::ResetDC(m_hDC, lpDevMode) != NULL;
}
// Drawing-Tool Functions
BOOL GetBrushOrg(LPPOINT lpPoint) const
{
ATLASSERT(m_hDC != NULL);
return ::GetBrushOrgEx(m_hDC, lpPoint);
}
#endif // !_WIN32_WCE
BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetBrushOrgEx(m_hDC, x, y, lpPoint);
}
BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet);
}
#ifndef _WIN32_WCE
int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData)
{
ATLASSERT(m_hDC != NULL);
#ifdef STRICT
return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData);
#else
return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData);
#endif
}
#endif // !_WIN32_WCE
// Type-safe selection helpers
HPEN SelectPen(HPEN hPen)
{
ATLASSERT(m_hDC != NULL);
#ifndef _WIN32_WCE
ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN);
#else // CE specific
ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN);
#endif // _WIN32_WCE
return (HPEN)::SelectObject(m_hDC, hPen);
}
HBRUSH SelectBrush(HBRUSH hBrush)
{
ATLASSERT(m_hDC != NULL);
ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH);
return (HBRUSH)::SelectObject(m_hDC, hBrush);
}
HFONT SelectFont(HFONT hFont)
{
ATLASSERT(m_hDC != NULL);
ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT);
return (HFONT)::SelectObject(m_hDC, hFont);
}
HBITMAP SelectBitmap(HBITMAP hBitmap)
{
ATLASSERT(m_hDC != NULL);
ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP);
return (HBITMAP)::SelectObject(m_hDC, hBitmap);
}
int SelectRgn(HRGN hRgn) // special return for regions
{
ATLASSERT(m_hDC != NULL);
ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION);
return PtrToInt(::SelectObject(m_hDC, hRgn));
}
// Type-safe selection helpers for stock objects
HPEN SelectStockPen(int nPen)
{
ATLASSERT(m_hDC != NULL);
#if (_WIN32_WINNT >= 0x0500)
ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
#else
ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
#endif // !(_WIN32_WINNT >= 0x0500)
return SelectPen((HPEN)::GetStockObject(nPen));
}
HBRUSH SelectStockBrush(int nBrush)
{
#if (_WIN32_WINNT >= 0x0500)
ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
#else
ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
#endif // !(_WIN32_WINNT >= 0x0500)
return SelectBrush((HBRUSH)::GetStockObject(nBrush));
}
HFONT SelectStockFont(int nFont)
{
#ifndef _WIN32_WCE
ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
#else // CE specific
ATLASSERT(nFont == SYSTEM_FONT);
#endif // _WIN32_WCE
return SelectFont((HFONT)::GetStockObject(nFont));
}
HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground)
{
ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported
return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground);
}
// Color and Color Palette Functions
COLORREF GetNearestColor(COLORREF crColor) const
{
ATLASSERT(m_hDC != NULL);
return ::GetNearestColor(m_hDC, crColor);
}
HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground)
{
ATLASSERT(m_hDC != NULL);
return ::SelectPalette(m_hDC, hPalette, bForceBackground);
}
UINT RealizePalette()
{
ATLASSERT(m_hDC != NULL);
return ::RealizePalette(m_hDC);
}
#ifndef _WIN32_WCE
void UpdateColors()
{
ATLASSERT(m_hDC != NULL);
::UpdateColors(m_hDC);
}
#endif // !_WIN32_WCE
// Drawing-Attribute Functions
COLORREF GetBkColor() const
{
ATLASSERT(m_hDC != NULL);
return ::GetBkColor(m_hDC);
}
int GetBkMode() const
{
ATLASSERT(m_hDC != NULL);
return ::GetBkMode(m_hDC);
}
#ifndef _WIN32_WCE
int GetPolyFillMode() const
{
ATLASSERT(m_hDC != NULL);
return ::GetPolyFillMode(m_hDC);
}
int GetROP2() const
{
ATLASSERT(m_hDC != NULL);
return ::GetROP2(m_hDC);
}
int GetStretchBltMode() const
{
ATLASSERT(m_hDC != NULL);
return ::GetStretchBltMode(m_hDC);
}
#endif // !_WIN32_WCE
COLORREF GetTextColor() const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextColor(m_hDC);
}
COLORREF SetBkColor(COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetBkColor(m_hDC, crColor);
}
int SetBkMode(int nBkMode)
{
ATLASSERT(m_hDC != NULL);
return ::SetBkMode(m_hDC, nBkMode);
}
#ifndef _WIN32_WCE
int SetPolyFillMode(int nPolyFillMode)
{
ATLASSERT(m_hDC != NULL);
return ::SetPolyFillMode(m_hDC, nPolyFillMode);
}
#endif // !_WIN32_WCE
int SetROP2(int nDrawMode)
{
ATLASSERT(m_hDC != NULL);
return ::SetROP2(m_hDC, nDrawMode);
}
#ifndef _WIN32_WCE
int SetStretchBltMode(int nStretchMode)
{
ATLASSERT(m_hDC != NULL);
return ::SetStretchBltMode(m_hDC, nStretchMode);
}
#endif // !_WIN32_WCE
COLORREF SetTextColor(COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetTextColor(m_hDC, crColor);
}
#ifndef _WIN32_WCE
BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const
{
ATLASSERT(m_hDC != NULL);
return ::GetColorAdjustment(m_hDC, lpColorAdjust);
}
BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust)
{
ATLASSERT(m_hDC != NULL);
return ::SetColorAdjustment(m_hDC, lpColorAdjust);
}
// Mapping Functions
int GetMapMode() const
{
ATLASSERT(m_hDC != NULL);
return ::GetMapMode(m_hDC);
}
BOOL GetViewportOrg(LPPOINT lpPoint) const
{
ATLASSERT(m_hDC != NULL);
return ::GetViewportOrgEx(m_hDC, lpPoint);
}
int SetMapMode(int nMapMode)
{
ATLASSERT(m_hDC != NULL);
return ::SetMapMode(m_hDC, nMapMode);
}
#endif // !_WIN32_WCE
// Viewport Origin
BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetViewportOrgEx(m_hDC, x, y, lpPoint);
}
BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return SetViewportOrg(point.x, point.y, lpPointRet);
}
#ifndef _WIN32_WCE
BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint);
}
// Viewport Extent
BOOL GetViewportExt(LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
return ::GetViewportExtEx(m_hDC, lpSize);
}
BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetViewportExtEx(m_hDC, x, y, lpSize);
}
BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return SetViewportExt(size.cx, size.cy, lpSizeRet);
}
BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
}
#endif // !_WIN32_WCE
// Window Origin
#ifndef _WIN32_WCE
BOOL GetWindowOrg(LPPOINT lpPoint) const
{
ATLASSERT(m_hDC != NULL);
return ::GetWindowOrgEx(m_hDC, lpPoint);
}
BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetWindowOrgEx(m_hDC, x, y, lpPoint);
}
BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return SetWindowOrg(point.x, point.y, lpPointRet);
}
BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint);
}
// Window extent
BOOL GetWindowExt(LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
return ::GetWindowExtEx(m_hDC, lpSize);
}
BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::SetWindowExtEx(m_hDC, x, y, lpSize);
}
BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return SetWindowExt(size.cx, size.cy, lpSizeRet);
}
BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize);
}
// Coordinate Functions
BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const
{
ATLASSERT(m_hDC != NULL);
return ::DPtoLP(m_hDC, lpPoints, nCount);
}
BOOL DPtoLP(LPRECT lpRect) const
{
ATLASSERT(m_hDC != NULL);
return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2);
}
BOOL DPtoLP(LPSIZE lpSize) const
{
SIZE sizeWinExt = { 0, 0 };
if(!GetWindowExt(&sizeWinExt))
return FALSE;
SIZE sizeVpExt = { 0, 0 };
if(!GetViewportExt(&sizeVpExt))
return FALSE;
lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx));
lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy));
return TRUE;
}
BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const
{
ATLASSERT(m_hDC != NULL);
return ::LPtoDP(m_hDC, lpPoints, nCount);
}
BOOL LPtoDP(LPRECT lpRect) const
{
ATLASSERT(m_hDC != NULL);
return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2);
}
BOOL LPtoDP(LPSIZE lpSize) const
{
SIZE sizeWinExt = { 0, 0 };
if(!GetWindowExt(&sizeWinExt))
return FALSE;
SIZE sizeVpExt = { 0, 0 };
if(!GetViewportExt(&sizeVpExt))
return FALSE;
lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx));
lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy));
return TRUE;
}
// Special Coordinate Functions (useful for dealing with metafiles and OLE)
#define HIMETRIC_INCH 2540 // HIMETRIC units per inch
void DPtoHIMETRIC(LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
int nMapMode;
if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
{
// when using a constrained map mode, map against physical inch
((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
DPtoLP(lpSize);
((CDCHandle*)this)->SetMapMode(nMapMode);
}
else
{
// map against logical inch for non-constrained mapping modes
int cxPerInch = GetDeviceCaps(LOGPIXELSX);
int cyPerInch = GetDeviceCaps(LOGPIXELSY);
ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch);
lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch);
}
}
void HIMETRICtoDP(LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
int nMapMode;
if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT)
{
// when using a constrained map mode, map against physical inch
((CDCHandle*)this)->SetMapMode(MM_HIMETRIC);
LPtoDP(lpSize);
((CDCHandle*)this)->SetMapMode(nMapMode);
}
else
{
// map against logical inch for non-constrained mapping modes
int cxPerInch = GetDeviceCaps(LOGPIXELSX);
int cyPerInch = GetDeviceCaps(LOGPIXELSY);
ATLASSERT(cxPerInch != 0 && cyPerInch != 0);
lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
}
}
void LPtoHIMETRIC(LPSIZE lpSize) const
{
LPtoDP(lpSize);
DPtoHIMETRIC(lpSize);
}
void HIMETRICtoLP(LPSIZE lpSize) const
{
HIMETRICtoDP(lpSize);
DPtoLP(lpSize);
}
#endif // !_WIN32_WCE
// Region Functions
BOOL FillRgn(HRGN hRgn, HBRUSH hBrush)
{
ATLASSERT(m_hDC != NULL);
return ::FillRgn(m_hDC, hRgn, hBrush);
}
#ifndef _WIN32_WCE
BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight)
{
ATLASSERT(m_hDC != NULL);
return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight);
}
BOOL InvertRgn(HRGN hRgn)
{
ATLASSERT(m_hDC != NULL);
return ::InvertRgn(m_hDC, hRgn);
}
BOOL PaintRgn(HRGN hRgn)
{
ATLASSERT(m_hDC != NULL);
return ::PaintRgn(m_hDC, hRgn);
}
#endif // !_WIN32_WCE
// Clipping Functions
int GetClipBox(LPRECT lpRect) const
{
ATLASSERT(m_hDC != NULL);
return ::GetClipBox(m_hDC, lpRect);
}
int GetClipRgn(CRgn& region) const
{
ATLASSERT(m_hDC != NULL);
if(region.IsNull())
region.CreateRectRgn(0, 0, 0, 0);
int nRet = ::GetClipRgn(m_hDC, region);
if(nRet != 1)
region.DeleteObject();
return nRet;
}
#ifndef _WIN32_WCE
BOOL PtVisible(int x, int y) const
{
ATLASSERT(m_hDC != NULL);
return ::PtVisible(m_hDC, x, y);
}
BOOL PtVisible(POINT point) const
{
ATLASSERT(m_hDC != NULL);
return ::PtVisible(m_hDC, point.x, point.y);
}
#endif // !_WIN32_WCE
BOOL RectVisible(LPCRECT lpRect) const
{
ATLASSERT(m_hDC != NULL);
return ::RectVisible(m_hDC, lpRect);
}
int SelectClipRgn(HRGN hRgn)
{
ATLASSERT(m_hDC != NULL);
return ::SelectClipRgn(m_hDC, (HRGN)hRgn);
}
int ExcludeClipRect(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hDC != NULL);
return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
}
int ExcludeClipRect(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
}
#ifndef _WIN32_WCE
int ExcludeUpdateRgn(HWND hWnd)
{
ATLASSERT(m_hDC != NULL);
return ::ExcludeUpdateRgn(m_hDC, hWnd);
}
#endif // !_WIN32_WCE
int IntersectClipRect(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hDC != NULL);
return ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
}
int IntersectClipRect(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
}
#ifndef _WIN32_WCE
int OffsetClipRgn(int x, int y)
{
ATLASSERT(m_hDC != NULL);
return ::OffsetClipRgn(m_hDC, x, y);
}
int OffsetClipRgn(SIZE size)
{
ATLASSERT(m_hDC != NULL);
return ::OffsetClipRgn(m_hDC, size.cx, size.cy);
}
int SelectClipRgn(HRGN hRgn, int nMode)
{
ATLASSERT(m_hDC != NULL);
return ::ExtSelectClipRgn(m_hDC, hRgn, nMode);
}
#endif // !_WIN32_WCE
// Line-Output Functions
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
BOOL GetCurrentPosition(LPPOINT lpPoint) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCurrentPositionEx(m_hDC, lpPoint);
}
BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::MoveToEx(m_hDC, x, y, lpPoint);
}
BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL)
{
ATLASSERT(m_hDC != NULL);
return MoveTo(point.x, point.y, lpPointRet);
}
BOOL LineTo(int x, int y)
{
ATLASSERT(m_hDC != NULL);
return ::LineTo(m_hDC, x, y);
}
BOOL LineTo(POINT point)
{
ATLASSERT(m_hDC != NULL);
return LineTo(point.x, point.y);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
#ifndef _WIN32_WCE
BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
ATLASSERT(m_hDC != NULL);
return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
}
BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
{
ATLASSERT(m_hDC != NULL);
return ::Arc(m_hDC, lpRect->left, lpRect->top,
lpRect->right, lpRect->bottom, ptStart.x, ptStart.y,
ptEnd.x, ptEnd.y);
}
#endif // !_WIN32_WCE
BOOL Polyline(LPPOINT lpPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::Polyline(m_hDC, lpPoints, nCount);
}
#ifndef _WIN32_WCE
BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle)
{
ATLASSERT(m_hDC != NULL);
return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle);
}
BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
ATLASSERT(m_hDC != NULL);
return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
}
BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
{
ATLASSERT(m_hDC != NULL);
return ArcTo(lpRect->left, lpRect->top, lpRect->right,
lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
}
int GetArcDirection() const
{
ATLASSERT(m_hDC != NULL);
return ::GetArcDirection(m_hDC);
}
int SetArcDirection(int nArcDirection)
{
ATLASSERT(m_hDC != NULL);
return ::SetArcDirection(m_hDC, nArcDirection);
}
BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount);
}
BOOL PolylineTo(const POINT* lpPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolylineTo(m_hDC, lpPoints, nCount);
}
BOOL PolyPolyline(const POINT* lpPoints,
const DWORD* lpPolyPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount);
}
BOOL PolyBezier(const POINT* lpPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolyBezier(m_hDC, lpPoints, nCount);
}
BOOL PolyBezierTo(const POINT* lpPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolyBezierTo(m_hDC, lpPoints, nCount);
}
#endif // !_WIN32_WCE
// Simple Drawing Functions
BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush)
{
ATLASSERT(m_hDC != NULL);
return ::FillRect(m_hDC, lpRect, hBrush);
}
BOOL FillRect(LPCRECT lpRect, int nColorIndex)
{
ATLASSERT(m_hDC != NULL);
#ifndef _WIN32_WCE
return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1));
#else // CE specific
return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex));
#endif // _WIN32_WCE
}
#ifndef _WIN32_WCE
BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush)
{
ATLASSERT(m_hDC != NULL);
return ::FrameRect(m_hDC, lpRect, hBrush);
}
#endif // !_WIN32_WCE
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
BOOL InvertRect(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
return ::InvertRect(m_hDC, lpRect);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
BOOL DrawIcon(int x, int y, HICON hIcon)
{
ATLASSERT(m_hDC != NULL);
#ifndef _WIN32_WCE
return ::DrawIcon(m_hDC, x, y, hIcon);
#else // CE specific
return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
#endif // _WIN32_WCE
}
BOOL DrawIcon(POINT point, HICON hIcon)
{
ATLASSERT(m_hDC != NULL);
#ifndef _WIN32_WCE
return ::DrawIcon(m_hDC, point.x, point.y, hIcon);
#else // CE specific
return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL);
#endif // _WIN32_WCE
}
BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
}
BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
}
#ifndef _WIN32_WCE
BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP);
}
BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON);
}
BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT));
}
BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX);
}
#endif // !_WIN32_WCE
// Ellipse and Polygon Functions
#ifndef _WIN32_WCE
BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
ATLASSERT(m_hDC != NULL);
return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
}
BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
{
ATLASSERT(m_hDC != NULL);
return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
}
#endif // !_WIN32_WCE
void DrawFocusRect(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
::DrawFocusRect(m_hDC, lpRect);
}
BOOL Ellipse(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hDC != NULL);
return ::Ellipse(m_hDC, x1, y1, x2, y2);
}
BOOL Ellipse(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
}
#ifndef _WIN32_WCE
BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
ATLASSERT(m_hDC != NULL);
return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4);
}
BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd)
{
ATLASSERT(m_hDC != NULL);
return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
}
#endif // !_WIN32_WCE
BOOL Polygon(LPPOINT lpPoints, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::Polygon(m_hDC, lpPoints, nCount);
}
#ifndef _WIN32_WCE
BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount)
{
ATLASSERT(m_hDC != NULL);
return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount);
}
#endif // !_WIN32_WCE
BOOL Rectangle(int x1, int y1, int x2, int y2)
{
ATLASSERT(m_hDC != NULL);
return ::Rectangle(m_hDC, x1, y1, x2, y2);
}
BOOL Rectangle(LPCRECT lpRect)
{
ATLASSERT(m_hDC != NULL);
return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
}
BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3)
{
ATLASSERT(m_hDC != NULL);
return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3);
}
BOOL RoundRect(LPCRECT lpRect, POINT point)
{
ATLASSERT(m_hDC != NULL);
return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y);
}
// Bitmap Functions
BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop)
{
ATLASSERT(m_hDC != NULL);
return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop);
}
BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC,
int xSrc, int ySrc, DWORD dwRop)
{
ATLASSERT(m_hDC != NULL);
return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop);
}
BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
{
ATLASSERT(m_hDC != NULL);
return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
}
COLORREF GetPixel(int x, int y) const
{
ATLASSERT(m_hDC != NULL);
return ::GetPixel(m_hDC, x, y);
}
COLORREF GetPixel(POINT point) const
{
ATLASSERT(m_hDC != NULL);
return ::GetPixel(m_hDC, point.x, point.y);
}
COLORREF SetPixel(int x, int y, COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetPixel(m_hDC, x, y, crColor);
}
COLORREF SetPixel(POINT point, COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetPixel(m_hDC, point.x, point.y, crColor);
}
#ifndef _WIN32_WCE
BOOL FloodFill(int x, int y, COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::FloodFill(m_hDC, x, y, crColor);
}
BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType)
{
ATLASSERT(m_hDC != NULL);
return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType);
}
#endif // !_WIN32_WCE
BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop)
{
ATLASSERT(m_hDC != NULL);
return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop);
}
#ifndef _WIN32_WCE
BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask)
{
ATLASSERT(m_hDC != NULL);
return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask);
}
BOOL SetPixelV(int x, int y, COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetPixelV(m_hDC, x, y, crColor);
}
BOOL SetPixelV(POINT point, COLORREF crColor)
{
ATLASSERT(m_hDC != NULL);
return ::SetPixelV(m_hDC, point.x, point.y, crColor);
}
#endif // !_WIN32_WCE
#if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
#ifndef _WIN32_WCE
BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
{
ATLASSERT(m_hDC != NULL);
return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
}
#else // CE specific
BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent)
{
ATLASSERT(m_hDC != NULL);
return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent);
}
#endif // _WIN32_WCE
#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420))
BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode)
{
ATLASSERT(m_hDC != NULL);
return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420)
#if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf)
{
ATLASSERT(m_hDC != NULL);
return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500)
#endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE)
// Extra bitmap functions
// Helper function for painting a disabled toolbar or menu bitmap
// This function can take either an HBITMAP (for SS) or a DC with
// the bitmap already painted (for cmdbar)
BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc,
HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
{
ATLASSERT(m_hDC != NULL || hBitmap != NULL);
ATLASSERT(nWidth > 0 && nHeight > 0);
// Create a generic DC for all BitBlts
CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC);
ATLASSERT(dc.m_hDC != NULL);
if(dc.m_hDC == NULL)
return FALSE;
// Create a DC for the monochrome DIB section
CDC dcBW = ::CreateCompatibleDC(m_hDC);
ATLASSERT(dcBW.m_hDC != NULL);
if(dcBW.m_hDC == NULL)
{
if(hSrcDC == NULL)
dc.DeleteDC();
return FALSE;
}
// Create the monochrome DIB section with a black and white palette
struct RGBBWBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[2];
};
RGBBWBITMAPINFO rgbBWBitmapInfo =
{
{ sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 },
{ { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } }
};
VOID* pbitsBW;
CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
ATLASSERT(bmpBW.m_hBitmap != NULL);
if(bmpBW.m_hBitmap == NULL)
{
if(hSrcDC == NULL)
dc.DeleteDC();
return FALSE;
}
// Attach the monochrome DIB section and the bitmap to the DCs
HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW);
HBITMAP hbmOldDC = NULL;
if(hBitmap != NULL)
hbmOldDC = dc.SelectBitmap(hBitmap);
// Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white
{
CDC dcTemp1 = ::CreateCompatibleDC(m_hDC);
CDC dcTemp2 = ::CreateCompatibleDC(m_hDC);
CBitmap bmpTemp1;
bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight);
CBitmap bmpTemp2;
bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1);
HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2);
// Let's copy our image, it will be altered
dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY);
// All dark gray pixels will become white, the others black
dcTemp1.SetBkColor(RGB(128, 128, 128));
dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
// Do an XOR to set to black these white pixels
dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT);
// BitBlt the bitmap into the monochrome DIB section
// The DIB section will do a true monochrome conversion
// The magenta background being closer to white will become white
dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY);
// Cleanup
dcTemp1.SelectBitmap(hOldBmp1);
dcTemp2.SelectBitmap(hOldBmp2);
}
// Paint the destination rectangle using hBrushBackground
if(hBrushBackground != NULL)
{
RECT rc = { x, y, x + nWidth, y + nHeight };
FillRect(&rc, hBrushBackground);
}
// BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC
// The magic ROP comes from the Charles Petzold's book
HBRUSH hOldBrush = SelectBrush(hBrush3DEffect);
BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
// BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC
SelectBrush(hBrushDisabledImage);
BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A);
SelectBrush(hOldBrush);
dcBW.SelectBitmap(hbmOldBW);
dc.SelectBitmap(hbmOldDC);
if(hSrcDC == NULL)
dc.DeleteDC();
return TRUE;
}
// Text Functions
#ifndef _WIN32_WCE
BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1)
{
ATLASSERT(m_hDC != NULL);
if(nCount == -1)
nCount = lstrlen(lpszString);
return ::TextOut(m_hDC, x, y, lpszString, nCount);
}
#endif // !_WIN32_WCE
BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
{
ATLASSERT(m_hDC != NULL);
if(nCount == -1)
nCount = lstrlen(lpszString);
return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
}
#ifndef _WIN32_WCE
SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0)
{
ATLASSERT(m_hDC != NULL);
if(nCount == -1)
nCount = lstrlen(lpszString);
LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) };
return size;
}
#endif // !_WIN32_WCE
int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
{
ATLASSERT(m_hDC != NULL);
#ifndef _WIN32_WCE
ATLASSERT((uFormat & DT_MODIFYSTRING) == 0);
#endif // !_WIN32_WCE
return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
}
int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
{
ATLASSERT(m_hDC != NULL);
return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
}
#ifndef _WIN32_WCE
int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams);
}
#endif // !_WIN32_WCE
#if (_WIN32_WINNT >= 0x0501)
int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset)
{
ATLASSERT(m_hDC != NULL);
// This function is present only if comctl32.dll version 6 is loaded;
// we use LoadLibrary/GetProcAddress to allow apps compiled with
// _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl
int nRet = 0;
HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
ATLASSERT(hCommCtrlDLL != NULL);
if(hCommCtrlDLL != NULL)
{
typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset);
PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText");
ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6
if(pfnDrawShadowText != NULL)
nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset);
::FreeLibrary(hCommCtrlDLL);
}
return nRet;
}
#endif // (_WIN32_WINNT >= 0x0501)
BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
if(nCount == -1)
nCount = lstrlen(lpszString);
return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize);
}
BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL)
{
ATLASSERT(m_hDC != NULL);
return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize);
}
#ifndef _WIN32_WCE
DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const
{
ATLASSERT(m_hDC != NULL);
if(nCount == -1)
nCount = lstrlen(lpszString);
return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions);
}
BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight)
{
ATLASSERT(m_hDC != NULL);
return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight);
}
#endif // !_WIN32_WCE
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
UINT GetTextAlign() const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextAlign(m_hDC);
}
UINT SetTextAlign(UINT nFlags)
{
ATLASSERT(m_hDC != NULL);
return ::SetTextAlign(m_hDC, nFlags);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
int GetTextFace(LPTSTR lpszFacename, int nCount) const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextFace(m_hDC, nCount, lpszFacename);
}
int GetTextFaceLen() const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextFace(m_hDC, 0, NULL);
}
#ifndef _ATL_NO_COM
#ifdef _OLEAUTO_H_
BOOL GetTextFace(BSTR& bstrFace) const
{
USES_CONVERSION;
ATLASSERT(m_hDC != NULL);
ATLASSERT(bstrFace == NULL);
int nLen = GetTextFaceLen();
if(nLen == 0)
return FALSE;
CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
LPTSTR lpszText = buff.Allocate(nLen);
if(lpszText == NULL)
return FALSE;
if(!GetTextFace(lpszText, nLen))
return FALSE;
bstrFace = ::SysAllocString(T2OLE(lpszText));
return (bstrFace != NULL) ? TRUE : FALSE;
}
#endif
#endif // !_ATL_NO_COM
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
int GetTextFace(_CSTRING_NS::CString& strFace) const
{
ATLASSERT(m_hDC != NULL);
int nLen = GetTextFaceLen();
if(nLen == 0)
return 0;
LPTSTR lpstr = strFace.GetBufferSetLength(nLen);
if(lpstr == NULL)
return 0;
int nRet = GetTextFace(lpstr, nLen);
strFace.ReleaseBuffer();
return nRet;
}
#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextMetrics(m_hDC, lpMetrics);
}
#ifndef _WIN32_WCE
int SetTextJustification(int nBreakExtra, int nBreakCount)
{
ATLASSERT(m_hDC != NULL);
return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount);
}
int GetTextCharacterExtra() const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextCharacterExtra(m_hDC);
}
int SetTextCharacterExtra(int nCharExtra)
{
ATLASSERT(m_hDC != NULL);
return ::SetTextCharacterExtra(m_hDC, nCharExtra);
}
#endif // !_WIN32_WCE
// Advanced Drawing
BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
{
ATLASSERT(m_hDC != NULL);
return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags);
}
BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState)
{
ATLASSERT(m_hDC != NULL);
return ::DrawFrameControl(m_hDC, lpRect, nType, nState);
}
// Scrolling Functions
BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate)
{
ATLASSERT(m_hDC != NULL);
return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate);
}
// Font Functions
#ifndef _WIN32_WCE
BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer);
}
// GetCharWidth32 is not supported under Win9x
BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer);
}
DWORD SetMapperFlags(DWORD dwFlag)
{
ATLASSERT(m_hDC != NULL);
return ::SetMapperFlags(m_hDC, dwFlag);
}
BOOL GetAspectRatioFilter(LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
return ::GetAspectRatioFilterEx(m_hDC, lpSize);
}
BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc);
}
DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const
{
ATLASSERT(m_hDC != NULL);
return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData);
}
int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const
{
ATLASSERT(m_hDC != NULL);
return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair);
}
UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const
{
ATLASSERT(m_hDC != NULL);
return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm);
}
DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const
{
ATLASSERT(m_hDC != NULL);
return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
}
BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF);
}
BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer);
}
#endif // !_WIN32_WCE
// Printer/Device Escape Functions
#ifndef _WIN32_WCE
int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
{
ATLASSERT(m_hDC != NULL);
return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
}
#endif // !_WIN32_WCE
int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData,
int nOutputSize, LPSTR lpszOutputData)
{
ATLASSERT(m_hDC != NULL);
return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData);
}
#ifndef _WIN32_WCE
int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData)
{
ATLASSERT(m_hDC != NULL);
return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData);
}
#endif // !_WIN32_WCE
// Escape helpers
#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version
{
DOCINFO di = { 0 };
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = lpszDocName;
return StartDoc(&di);
}
int StartDoc(LPDOCINFO lpDocInfo)
{
ATLASSERT(m_hDC != NULL);
return ::StartDoc(m_hDC, lpDocInfo);
}
int StartPage()
{
ATLASSERT(m_hDC != NULL);
return ::StartPage(m_hDC);
}
int EndPage()
{
ATLASSERT(m_hDC != NULL);
return ::EndPage(m_hDC);
}
int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int))
{
ATLASSERT(m_hDC != NULL);
return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn);
}
int AbortDoc()
{
ATLASSERT(m_hDC != NULL);
return ::AbortDoc(m_hDC);
}
int EndDoc()
{
ATLASSERT(m_hDC != NULL);
return ::EndDoc(m_hDC);
}
#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc))
// MetaFile Functions
#ifndef _WIN32_WCE
BOOL PlayMetaFile(HMETAFILE hMF)
{
ATLASSERT(m_hDC != NULL);
if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE)
{
// playing metafile in metafile, just use core windows API
return ::PlayMetaFile(m_hDC, hMF);
}
// for special playback, lParam == pDC
return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this);
}
BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds)
{
ATLASSERT(m_hDC != NULL);
return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds);
}
BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only
{
ATLASSERT(m_hDC != NULL);
return ::GdiComment(m_hDC, nDataSize, pCommentData);
}
// Special handling for metafile playback
static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam)
{
CDCHandle* pDC = (CDCHandle*)lParam;
switch (pMetaRec->rdFunction)
{
case META_SETMAPMODE:
pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]);
break;
case META_SETWINDOWEXT:
pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SETWINDOWORG:
pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SETVIEWPORTEXT:
pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SETVIEWPORTORG:
pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SCALEWINDOWEXT:
pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
(int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SCALEVIEWPORTEXT:
pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2],
(int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_OFFSETVIEWPORTORG:
pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]);
break;
case META_SAVEDC:
pDC->SaveDC();
break;
case META_RESTOREDC:
pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]);
break;
case META_SETBKCOLOR:
pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
break;
case META_SETTEXTCOLOR:
pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]);
break;
// need to watch out for SelectObject(HFONT), for custom font mapping
case META_SELECTOBJECT:
{
HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]];
UINT nObjType = ::GetObjectType(hObject);
if(nObjType == 0)
{
// object type is unknown, determine if it is a font
HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT);
HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont);
HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject);
if(hObjOld == hStockFont)
{
// got the stock object back, so must be selecting a font
pDC->SelectFont((HFONT)hObject);
break; // don't play the default record
}
else
{
// didn't get the stock object back, so restore everything
::SelectObject(pDC->m_hDC, hFontOld);
::SelectObject(pDC->m_hDC, hObjOld);
}
// and fall through to PlayMetaFileRecord...
}
else if(nObjType == OBJ_FONT)
{
// play back as CDCHandle::SelectFont(HFONT)
pDC->SelectFont((HFONT)hObject);
break; // don't play the default record
}
}
// fall through...
default:
::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles);
break;
}
return 1;
}
#endif // !_WIN32_WCE
// Path Functions
#ifndef _WIN32_WCE
BOOL AbortPath()
{
ATLASSERT(m_hDC != NULL);
return ::AbortPath(m_hDC);
}
BOOL BeginPath()
{
ATLASSERT(m_hDC != NULL);
return ::BeginPath(m_hDC);
}
BOOL CloseFigure()
{
ATLASSERT(m_hDC != NULL);
return ::CloseFigure(m_hDC);
}
BOOL EndPath()
{
ATLASSERT(m_hDC != NULL);
return ::EndPath(m_hDC);
}
BOOL FillPath()
{
ATLASSERT(m_hDC != NULL);
return ::FillPath(m_hDC);
}
BOOL FlattenPath()
{
ATLASSERT(m_hDC != NULL);
return ::FlattenPath(m_hDC);
}
BOOL StrokeAndFillPath()
{
ATLASSERT(m_hDC != NULL);
return ::StrokeAndFillPath(m_hDC);
}
BOOL StrokePath()
{
ATLASSERT(m_hDC != NULL);
return ::StrokePath(m_hDC);
}
BOOL WidenPath()
{
ATLASSERT(m_hDC != NULL);
return ::WidenPath(m_hDC);
}
BOOL GetMiterLimit(PFLOAT pfMiterLimit) const
{
ATLASSERT(m_hDC != NULL);
return ::GetMiterLimit(m_hDC, pfMiterLimit);
}
BOOL SetMiterLimit(float fMiterLimit)
{
ATLASSERT(m_hDC != NULL);
return ::SetMiterLimit(m_hDC, fMiterLimit, NULL);
}
int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const
{
ATLASSERT(m_hDC != NULL);
return ::GetPath(m_hDC, lpPoints, lpTypes, nCount);
}
BOOL SelectClipPath(int nMode)
{
ATLASSERT(m_hDC != NULL);
return ::SelectClipPath(m_hDC, nMode);
}
#endif // !_WIN32_WCE
// Misc Helper Functions
static CBrushHandle PASCAL GetHalftoneBrush()
{
HBRUSH halftoneBrush = NULL;
WORD grayPattern[8];
for(int i = 0; i < 8; i++)
grayPattern[i] = (WORD)(0x5555 << (i & 1));
HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
if(grayBitmap != NULL)
{
halftoneBrush = ::CreatePatternBrush(grayBitmap);
DeleteObject(grayBitmap);
}
return CBrushHandle(halftoneBrush);
}
void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL)
{
// first, determine the update region and select it
CRgn rgnOutside;
rgnOutside.CreateRectRgnIndirect(lpRect);
RECT rect = *lpRect;
::InflateRect(&rect, -size.cx, -size.cy);
::IntersectRect(&rect, &rect, lpRect);
CRgn rgnInside;
rgnInside.CreateRectRgnIndirect(&rect);
CRgn rgnNew;
rgnNew.CreateRectRgn(0, 0, 0, 0);
rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
HBRUSH hBrushOld = NULL;
CBrush brushHalftone;
if(hBrush == NULL)
brushHalftone = hBrush = CDCHandle::GetHalftoneBrush();
if(hBrushLast == NULL)
hBrushLast = hBrush;
CRgn rgnLast;
CRgn rgnUpdate;
if(lpRectLast != NULL)
{
// find difference between new region and old region
rgnLast.CreateRectRgn(0, 0, 0, 0);
rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom);
rect = *lpRectLast;
::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy);
::IntersectRect(&rect, &rect, lpRectLast);
rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom);
rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR);
// only diff them if brushes are the same
if(hBrush == hBrushLast)
{
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR);
}
}
if(hBrush != hBrushLast && lpRectLast != NULL)
{
// brushes are different -- erase old region first
SelectClipRgn(rgnLast);
GetClipBox(&rect);
hBrushOld = SelectBrush(hBrushLast);
PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
SelectBrush(hBrushOld);
hBrushOld = NULL;
}
// draw into the update/new region
SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate);
GetClipBox(&rect);
hBrushOld = SelectBrush(hBrush);
PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
// cleanup DC
if(hBrushOld != NULL)
SelectBrush(hBrushOld);
SelectClipRgn(NULL);
}
void FillSolidRect(LPCRECT lpRect, COLORREF clr)
{
ATLASSERT(m_hDC != NULL);
COLORREF clrOld = ::SetBkColor(m_hDC, clr);
ATLASSERT(clrOld != CLR_INVALID);
if(clrOld != CLR_INVALID)
{
::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
::SetBkColor(m_hDC, clrOld);
}
}
void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
{
ATLASSERT(m_hDC != NULL);
RECT rect = { x, y, x + cx, y + cy };
FillSolidRect(&rect, clr);
}
void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
{
Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
}
void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
{
FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
}
// DIB support
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
{
ATLASSERT(m_hDC != NULL);
return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop)
{
ATLASSERT(m_hDC != NULL);
return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop);
}
UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const
{
ATLASSERT(m_hDC != NULL);
return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
}
UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors)
{
ATLASSERT(m_hDC != NULL);
return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
// OpenGL support
#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd)
{
ATLASSERT(m_hDC != NULL);
return ::ChoosePixelFormat(m_hDC, ppfd);
}
int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
{
ATLASSERT(m_hDC != NULL);
return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd);
}
int GetPixelFormat() const
{
ATLASSERT(m_hDC != NULL);
return ::GetPixelFormat(m_hDC);
}
BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd)
{
ATLASSERT(m_hDC != NULL);
return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd);
}
BOOL SwapBuffers()
{
ATLASSERT(m_hDC != NULL);
return ::SwapBuffers(m_hDC);
}
HGLRC wglCreateContext()
{
ATLASSERT(m_hDC != NULL);
return ::wglCreateContext(m_hDC);
}
HGLRC wglCreateLayerContext(int iLayerPlane)
{
ATLASSERT(m_hDC != NULL);
return ::wglCreateLayerContext(m_hDC, iLayerPlane);
}
BOOL wglMakeCurrent(HGLRC hglrc)
{
ATLASSERT(m_hDC != NULL);
return ::wglMakeCurrent(m_hDC, hglrc);
}
BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase)
{
ATLASSERT(m_hDC != NULL);
return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase);
}
BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf)
{
ATLASSERT(m_hDC != NULL);
return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf);
}
BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd)
{
ATLASSERT(m_hDC != NULL);
return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd);
}
int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr)
{
ATLASSERT(m_hDC != NULL);
return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
}
int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr)
{
ATLASSERT(m_hDC != NULL);
return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr);
}
BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize)
{
ATLASSERT(m_hDC != NULL);
return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize);
}
BOOL wglSwapLayerBuffers(UINT uPlanes)
{
ATLASSERT(m_hDC != NULL);
return ::wglSwapLayerBuffers(m_hDC, uPlanes);
}
#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE)
// New for Windows 2000 only
#if (_WIN32_WINNT >= 0x0500)
COLORREF GetDCPenColor() const
{
ATLASSERT(m_hDC != NULL);
return ::GetDCPenColor(m_hDC);
}
COLORREF SetDCPenColor(COLORREF clr)
{
ATLASSERT(m_hDC != NULL);
return ::SetDCPenColor(m_hDC, clr);
}
COLORREF GetDCBrushColor() const
{
ATLASSERT(m_hDC != NULL);
return ::GetDCBrushColor(m_hDC);
}
COLORREF SetDCBrushColor(COLORREF clr)
{
ATLASSERT(m_hDC != NULL);
return ::SetDCBrushColor(m_hDC, clr);
}
#ifndef _WIN32_WCE
DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const
{
ATLASSERT(m_hDC != NULL);
return ::GetFontUnicodeRanges(m_hDC, lpgs);
}
#endif // !_WIN32_WCE
DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const
{
ATLASSERT(m_hDC != NULL);
return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags);
}
BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize);
}
BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const
{
ATLASSERT(m_hDC != NULL);
return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize);
}
BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer);
}
BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const
{
ATLASSERT(m_hDC != NULL);
return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc);
}
#endif // (_WIN32_WINNT >= 0x0500)
// New for Windows 2000 and Windows 98
#if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries)
{
ATLASSERT(m_hDC != NULL);
return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries);
}
#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
};
typedef CDCT<false> CDCHandle;
typedef CDCT<true> CDC;
///////////////////////////////////////////////////////////////////////////////
// CDC Helpers
class CPaintDC : public CDC
{
public:
// Data members
HWND m_hWnd;
PAINTSTRUCT m_ps;
// Constructor/destructor
CPaintDC(HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd));
m_hWnd = hWnd;
m_hDC = ::BeginPaint(hWnd, &m_ps);
}
~CPaintDC()
{
ATLASSERT(m_hDC != NULL);
ATLASSERT(::IsWindow(m_hWnd));
::EndPaint(m_hWnd, &m_ps);
Detach();
}
};
class CClientDC : public CDC
{
public:
// Data members
HWND m_hWnd;
// Constructor/destructor
CClientDC(HWND hWnd)
{
ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
m_hWnd = hWnd;
m_hDC = ::GetDC(hWnd);
}
~CClientDC()
{
ATLASSERT(m_hDC != NULL);
::ReleaseDC(m_hWnd, Detach());
}
};
class CWindowDC : public CDC
{
public:
// Data members
HWND m_hWnd;
// Constructor/destructor
CWindowDC(HWND hWnd)
{
ATLASSERT(hWnd == NULL || ::IsWindow(hWnd));
m_hWnd = hWnd;
m_hDC = ::GetWindowDC(hWnd);
}
~CWindowDC()
{
ATLASSERT(m_hDC != NULL);
::ReleaseDC(m_hWnd, Detach());
}
};
class CMemoryDC : public CDC
{
public:
// Data members
HDC m_hDCOriginal;
RECT m_rcPaint;
CBitmap m_bmp;
HBITMAP m_hBmpOld;
// Constructor/destructor
CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL)
{
m_rcPaint = rcPaint;
CreateCompatibleDC(m_hDCOriginal);
ATLASSERT(m_hDC != NULL);
m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top);
ATLASSERT(m_bmp.m_hBitmap != NULL);
m_hBmpOld = SelectBitmap(m_bmp);
SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top);
}
~CMemoryDC()
{
::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY);
SelectBitmap(m_hBmpOld);
}
};
///////////////////////////////////////////////////////////////////////////////
// Enhanced metafile support
#ifndef _WIN32_WCE
class CEnhMetaFileInfo
{
public:
// Data members
HENHMETAFILE m_hEMF;
BYTE* m_pBits;
TCHAR* m_pDesc;
ENHMETAHEADER m_header;
PIXELFORMATDESCRIPTOR m_pfd;
// Constructor/destructor
CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF)
{ }
~CEnhMetaFileInfo()
{
delete [] m_pBits;
delete [] m_pDesc;
}
// Operations
BYTE* GetEnhMetaFileBits()
{
ATLASSERT(m_hEMF != NULL);
UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL);
delete [] m_pBits;
m_pBits = NULL;
ATLTRY(m_pBits = new BYTE[nBytes]);
if (m_pBits != NULL)
::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits);
return m_pBits;
}
LPTSTR GetEnhMetaFileDescription()
{
ATLASSERT(m_hEMF != NULL);
UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL);
delete [] m_pDesc;
m_pDesc = NULL;
ATLTRY(m_pDesc = new TCHAR[nLen]);
if (m_pDesc != NULL)
nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc);
return m_pDesc;
}
ENHMETAHEADER* GetEnhMetaFileHeader()
{
ATLASSERT(m_hEMF != NULL);
memset(&m_header, 0, sizeof(m_header));
m_header.iType = EMR_HEADER;
m_header.nSize = sizeof(ENHMETAHEADER);
UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header);
return (n != 0) ? &m_header : NULL;
}
PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat()
{
ATLASSERT(m_hEMF != NULL);
memset(&m_pfd, 0, sizeof(m_pfd));
UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd);
return (n != 0) ? &m_pfd : NULL;
}
};
template <bool t_bManaged>
class CEnhMetaFileT
{
public:
// Data members
HENHMETAFILE m_hEMF;
// Constructor/destructor
CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF)
{
}
~CEnhMetaFileT()
{
if(t_bManaged && m_hEMF != NULL)
DeleteObject();
}
// Operations
CEnhMetaFileT<t_bManaged>& operator =(HENHMETAFILE hEMF)
{
Attach(hEMF);
return *this;
}
void Attach(HENHMETAFILE hEMF)
{
if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF)
DeleteObject();
m_hEMF = hEMF;
}
HENHMETAFILE Detach()
{
HENHMETAFILE hEMF = m_hEMF;
m_hEMF = NULL;
return hEMF;
}
operator HENHMETAFILE() const { return m_hEMF; }
bool IsNull() const { return (m_hEMF == NULL); }
BOOL DeleteObject()
{
ATLASSERT(m_hEMF != NULL);
BOOL bRet = ::DeleteEnhMetaFile(m_hEMF);
m_hEMF = NULL;
return bRet;
}
UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const
{
ATLASSERT(m_hEMF != NULL);
return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer);
}
UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const
{
ATLASSERT(m_hEMF != NULL);
return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription);
}
UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const
{
ATLASSERT(m_hEMF != NULL);
lpemh->iType = EMR_HEADER;
lpemh->nSize = sizeof(ENHMETAHEADER);
return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh);
}
UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const
{
ATLASSERT(m_hEMF != NULL);
return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe);
}
UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const
{
ATLASSERT(m_hEMF != NULL);
return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd);
}
};
typedef CEnhMetaFileT<false> CEnhMetaFileHandle;
typedef CEnhMetaFileT<true> CEnhMetaFile;
class CEnhMetaFileDC : public CDC
{
public:
// Constructor/destructor
CEnhMetaFileDC()
{
}
CEnhMetaFileDC(HDC hdc, LPCRECT lpRect)
{
Create(hdc, NULL, lpRect, NULL);
ATLASSERT(m_hDC != NULL);
}
CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
{
Create(hdcRef, lpFilename, lpRect, lpDescription);
ATLASSERT(m_hDC != NULL);
}
~CEnhMetaFileDC()
{
HENHMETAFILE hEMF = Close();
if (hEMF != NULL)
::DeleteEnhMetaFile(hEMF);
}
// Operations
void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription)
{
ATLASSERT(m_hDC == NULL);
m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription);
}
HENHMETAFILE Close()
{
HENHMETAFILE hEMF = NULL;
if (m_hDC != NULL)
{
hEMF = ::CloseEnhMetaFile(m_hDC);
m_hDC = NULL;
}
return hEMF;
}
};
#endif // !_WIN32_WCE
///////////////////////////////////////////////////////////////////////////////
// WinCE compatible clipboard CF_DIB format support functions
#ifndef _WTL_NO_DIB16
#define DIBINFO16_BITFIELDS { 31744, 992, 31 }
// DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib
struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[3];
DIBINFO16(SIZE size)
{
BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy,
1, 16, BI_BITFIELDS, 2 * size.cx * size.cy , 0, 0, 3 };
DWORD dw[3] = DIBINFO16_BITFIELDS ;
bmiHeader = bmih;
memcpy(bmiColors, dw, 3 * sizeof(DWORD));
}
};
// AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB
inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih)
{
return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS);
}
inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih)
{
switch (pbmih->biBitCount)
{
case 2:
case 4:
case 8:
return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount;
case 24:
break;
case 16:
case 32:
return pbmih->biCompression == BI_BITFIELDS ? 3 : 0;
default:
ATLASSERT(FALSE); // should never come here
}
return 0;
}
inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih)
{
switch (pbmih->biBitCount)
{
case 2:
case 4:
case 8:
if (pbmih->biClrUsed)
return pbmih->biClrUsed;
else
break;
case 16:
if (pbmih->biCompression == BI_BITFIELDS )
return 1 << 15;
else
break;
case 24:
break;
case 32:
if (pbmih->biCompression == BI_BITFIELDS )
return 1 << 24;
else
break;
default:
ATLASSERT(FALSE);
}
return 1 << pbmih->biBitCount;
}
inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi)
{
HBITMAP hbm = NULL;
CDC dc(NULL);
void * pBits = NULL;
LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD);
if (hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL))
memcpy(pBits, pDibBits, pbmi->bmiHeader.biSizeImage);
return hbm;
}
inline HBITMAP AtlCopyBitmap(HBITMAP hbm , SIZE sizeDst, bool bAsBitmap = false)
{
CDC hdcSrc = CreateCompatibleDC(NULL);
CDC hdcDst = CreateCompatibleDC(NULL);
CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm;
CBitmap bmNew = NULL;
SIZE sizeSrc = { 0 };
bmSrc.GetSize(sizeSrc);
hbmOld = hdcSrc.SelectBitmap(bmSrc);
if (bAsBitmap)
{
bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy);
}
else
{
DIBINFO16 dib16(sizeDst);
LPVOID pBits = NULL;
bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL);
}
ATLASSERT(!bmNew.IsNull());
hbmOld2 = hdcDst.SelectBitmap(bmNew);
BOOL bOK = FALSE;
if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy))
bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY);
else
bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY);
hdcSrc.SelectBitmap(hbmOld);
hdcDst.SelectBitmap(hbmOld2);
if (bOK == FALSE)
bmNew.DeleteObject();
return bmNew.Detach();
}
inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size)
{
DIBSECTION ds = { 0 };
LPBYTE pDib = NULL;
bool bCopied = false;
bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) ||
(ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy ))
{
if ((hbm = AtlCopyBitmap(hbm, size)) != NULL)
{
bCopied = true;
bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds);
}
else
{
bOK = FALSE;
}
}
if((bOK == TRUE) && (AtlIsDib16(&ds.dsBmih) == TRUE) && (ds.dsBm.bmBits != NULL))
{
pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage);
if (pDib != NULL)
{
memcpy(pDib , &ds.dsBmih, sizeof(DIBINFO16));
memcpy(pDib + sizeof(DIBINFO16), ds.dsBm.bmBits, ds.dsBmih.biSizeImage);
}
}
if (bCopied == true)
DeleteObject(hbm);
return (HLOCAL)pDib;
}
inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd));
BOOL bOK = OpenClipboard(hWnd);
if (bOK == TRUE)
{
if ((bOK = EmptyClipboard()) == TRUE)
{
HLOCAL hDib = AtlCreatePackedDib16(hbm, size);
if (hDib != NULL)
{
bOK = SetClipboardData(CF_DIB, hDib) != NULL;
if (bOK == FALSE)
LocalFree(hDib);
}
else
{
bOK = FALSE;
}
}
CloseClipboard();
}
return bOK == TRUE;
}
inline HBITMAP AtlGetClipboardDib(HWND hWnd)
{
ATLASSERT(::IsWindow(hWnd) == TRUE);
HBITMAP hbm = NULL;
if (OpenClipboard(hWnd) == TRUE)
{
LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB);
if (pbmi != NULL)
hbm = AtlGetDibBitmap(pbmi);
CloseClipboard();
}
return hbm;
}
#endif // _WTL_NO_DIB16
}; // namespace WTL
#endif // __ATLGDI_H__