| // 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__ |