6aa9bd0f77
Now with some actual consensus on what the updater will do!
3945 lines
121 KiB
C++
3945 lines
121 KiB
C++
// Win32++ Version 7.2
|
|
// Released: 5th AUgust 2011
|
|
//
|
|
// David Nash
|
|
// email: dnash@bigpond.net.au
|
|
// url: https://sourceforge.net/projects/win32-framework
|
|
//
|
|
//
|
|
// Copyright (c) 2005-2011 David Nash
|
|
//
|
|
// Permission is hereby granted, free of charge, to
|
|
// any person obtaining a copy of this software and
|
|
// associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify,
|
|
// merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom
|
|
// the Software is furnished to do so, subject to the
|
|
// following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice
|
|
// shall be included in all copies or substantial portions
|
|
// of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
// gdi.h
|
|
// Declaration of the CDC class, and CBitmapInfoPtr class
|
|
|
|
// The CDC class provides a device context, along with the various associated
|
|
// objects such as Bitmaps, Brushes, Bitmaps, Fonts and Pens. This class
|
|
// handles the creation, selection, de-selection and deletion of these objects
|
|
// automatically. It also automatically deletes or releases the device context
|
|
// itself as appropriate. Any failure to create the new GDI object throws an
|
|
// exception.
|
|
//
|
|
// The CDC class is sufficient for most GDI programming needs. Sometimes
|
|
// however we need to have the GDI object seperated from the device context.
|
|
// Wrapper classes for GDI objects are provided for this purpose. The classes
|
|
// are CBitmap, CBrush, CFont, CPalette, CPen and CRgn. These classes
|
|
// automatically delete the GDI resouce assigned to them when their destructor
|
|
// is called. These wrapper class objects can be attached to the CDC as
|
|
// shown below.
|
|
//
|
|
// Coding Exampe without CDC ...
|
|
// void DrawLine()
|
|
// {
|
|
// HDC hdcClient = ::GetDC(m_hWnd);
|
|
// HDC hdcMem = ::CreateCompatibleDC(hdcClient);
|
|
// HBITMAP hBitmap = ::CreateCompatibleBitmap(hdcClient, cx, cy);
|
|
// HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hBitmap);
|
|
// HPEN hPen = ::CreatePen(PS_SOLID, 1, RGB(255,0,0);
|
|
// HPEN hOldPen = (HPEN)::SelectObject(hdcMem, hPen);
|
|
// ::MoveToEx(hdcMem, 0, 0, NULL);
|
|
// ::LineTo(hdcMem, 50, 50);
|
|
// ::BitBlt(hdcClient, 0, 0, cx, cy, hdcMem, 0, 0);
|
|
// ::SelectObject(hdcMem, hOldPen);
|
|
// ::DeleteObject(hPen);
|
|
// ::SelectObject(hdcMem, hOldBitmap);
|
|
// ::DeleteObject(hBitmap);
|
|
// ::DeleteDC(hdcMem);
|
|
// ::ReleaseDC(m_hWnd, hdcClient);
|
|
// }
|
|
//
|
|
// Coding Example with CDC classes ...
|
|
// void DrawLine()
|
|
// {
|
|
// CClientDC dcClient(this)
|
|
// CMemDC dcMem(&dcClient);
|
|
// CBitmap* pOldBitmap = dcMem.CreateCompatibleBitmap(&dcClient, cx, cy);
|
|
// CPen* pOldPen = CMemDC.CreatePen(PS_SOLID, 1, RGB(255,0,0);
|
|
// CMemDC.MoveTo(0, 0);
|
|
// CMemDC.LineTo(50, 50);
|
|
// dcClient.BitBlt(0, 0, cx, cy, &CMemDC, 0, 0);
|
|
// }
|
|
//
|
|
// Coding Example with CDC classes and CPen ...
|
|
// void DrawLine()
|
|
// {
|
|
// CClientDC dcClient(this)
|
|
// CMemDC CMemDC(&dcClient);
|
|
// CBitmap* pOldBitmap = dcMem.CreateCompatibleBitmap(&dcClient, cx, cy);
|
|
// CPen MyPen(PS_SOLID, 1, RGB(255,0,0));
|
|
// CPen* pOldPen = CMemDC.SelectObject(&MyPen);
|
|
// CMemDC.MoveTo(0, 0);
|
|
// CMemDC.LineTo(50, 50);
|
|
// dcClient.BitBlt(0, 0, cx, cy, &CMemDC, 0, 0);
|
|
// }
|
|
|
|
// Notes:
|
|
// * When the CDC object drops out of scope, it's destructor is called, releasing
|
|
// or deleting the device context as appropriate.
|
|
// * When the destructor for CBitmap, CBrush, CPalette, CPen and CRgn are called,
|
|
// the destructor is called deleting their GDI object.
|
|
// * When the CDC object' destructor is called, any GDI objects created by one of
|
|
// the CDC member functions (CDC::CreatePen for example) will be deleted.
|
|
// * Bitmaps can only be selected into one device context at a time.
|
|
// * Palettes use SelectPalatte to select them into device the context.
|
|
// * Regions use SelectClipRgn to select them into the device context.
|
|
// * The FromHandle function can be used to convert a GDI handle (HDC, HPEN,
|
|
// HBITMAP etc) to a pointer of the appropriate GDI class (CDC, CPen CBitmap etc).
|
|
// The FromHandle function creates a temporary object unless the HANDLE is already
|
|
// assigned to a GDI class. Temporary objects don't delete their GDI object when
|
|
// their destructor is called.
|
|
// * All the GDI classes are reference counted. This allows functions to safely
|
|
// pass these objects by value, as well as by pointer or by reference.
|
|
|
|
// The CBitmapInfoPtr class is a convienient wrapper for the BITMAPINFO structure.
|
|
// The size of the BITMAPINFO structure is dependant on the type of HBITMAP, and its
|
|
// space needs to be allocated dynamically. CBitmapInfoPtr automatically allocates
|
|
// and deallocates the memory for the structure. A CBitmapInfoPtr object can be
|
|
// used anywhere in place of a LPBITMAPINFO. LPBITMAPINFO is used in functions like
|
|
// GetDIBits and SetDIBits.
|
|
//
|
|
// Coding example ...
|
|
// CDC MemDC = CreateCompatibleDC(NULL);
|
|
// CBitmapInfoPtr pbmi(hBitmap);
|
|
// MemDC.GetDIBits(hBitmap, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
|
|
|
|
#ifndef _WIN32XX_GDI_H_
|
|
#define _WIN32XX_GDI_H_
|
|
|
|
#include "wincore.h"
|
|
|
|
// Disable macros from Windowsx.h
|
|
#undef CopyRgn
|
|
|
|
namespace Win32xx
|
|
{
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Declarations for some global functions in the Win32xx namespace
|
|
//
|
|
#ifndef _WIN32_WCE
|
|
void GrayScaleBitmap(CBitmap* pbmSource);
|
|
void TintBitmap(CBitmap* pbmSource, int cRed, int cGreen, int cBlue);
|
|
HIMAGELIST CreateDisabledImageList(HIMAGELIST himlNormal);
|
|
#endif
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CGDIObject class
|
|
//
|
|
class CGDIObject
|
|
{
|
|
friend CBitmap* FromHandle(HBITMAP hBitmap);
|
|
friend CBrush* FromHandle(HBRUSH hBrush);
|
|
friend CDC* FromHandle(HDC hDC);
|
|
friend CFont* FromHandle(HFONT hFont);
|
|
friend CPalette* FromHandle(HPALETTE hPalette);
|
|
friend CPen* FromHandle(HPEN hPen);
|
|
friend CRgn* FromHandle(HRGN hRgn);
|
|
|
|
public:
|
|
struct DataMembers // A structure that contains the data members for CGDIObject
|
|
{
|
|
HGDIOBJ hGDIObject;
|
|
long Count;
|
|
BOOL bRemoveObject;
|
|
};
|
|
CGDIObject();
|
|
CGDIObject(const CGDIObject& rhs);
|
|
virtual ~CGDIObject();
|
|
CGDIObject& operator = ( const CGDIObject& rhs );
|
|
void operator = (HGDIOBJ hObject);
|
|
|
|
void Attach(HGDIOBJ hObject);
|
|
HGDIOBJ Detach();
|
|
HGDIOBJ GetHandle() const;
|
|
int GetObject(int nCount, LPVOID pObject) const;
|
|
|
|
protected:
|
|
DataMembers* m_pData;
|
|
|
|
private:
|
|
void AddToMap();
|
|
BOOL RemoveFromMap();
|
|
void Release();
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CBitmap class
|
|
//
|
|
class CBitmap : public CGDIObject
|
|
{
|
|
public:
|
|
CBitmap();
|
|
CBitmap(HBITMAP hBitmap);
|
|
CBitmap(LPCTSTR lpstr);
|
|
CBitmap(int nID);
|
|
operator HBITMAP() const;
|
|
~CBitmap();
|
|
|
|
// Create and load methods
|
|
BOOL LoadBitmap(LPCTSTR lpszName);
|
|
BOOL LoadBitmap(int nID);
|
|
BOOL LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad);
|
|
BOOL LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad);
|
|
BOOL LoadOEMBitmap(UINT nIDBitmap);
|
|
HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, LPCVOID lpBits);
|
|
HBITMAP CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight);
|
|
HBITMAP CreateDIBSection(CDC* pDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, LPVOID* ppvBits, HANDLE hSection, DWORD dwOffset);
|
|
|
|
#ifndef _WIN32_WCE
|
|
HBITMAP CreateDIBitmap(CDC* pDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, LPCVOID lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse);
|
|
HBITMAP CreateMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0);
|
|
HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap);
|
|
int GetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const;
|
|
int SetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse);
|
|
CSize GetBitmapDimensionEx() const;
|
|
CSize SetBitmapDimensionEx(int nWidth, int nHeight);
|
|
#endif // !_WIN32_WCE
|
|
|
|
// Attributes
|
|
BITMAP GetBitmapData() const;
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CBrush class
|
|
//
|
|
class CBrush : public CGDIObject
|
|
{
|
|
public:
|
|
CBrush();
|
|
CBrush(HBRUSH hBrush);
|
|
CBrush(COLORREF crColor);
|
|
operator HBRUSH() const;
|
|
~CBrush();
|
|
|
|
HBRUSH CreateSolidBrush(COLORREF crColor);
|
|
HBRUSH CreatePatternBrush(CBitmap* pBitmap);
|
|
LOGBRUSH GetLogBrush() const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor);
|
|
HBRUSH CreateBrushIndirect(LPLOGBRUSH lpLogBrush);
|
|
HBRUSH CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec);
|
|
HBRUSH CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT nUsage);
|
|
#endif // !defined(_WIN32_WCE)
|
|
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CFont class
|
|
//
|
|
class CFont : public CGDIObject
|
|
{
|
|
public:
|
|
CFont();
|
|
CFont(HFONT hFont);
|
|
CFont(const LOGFONT* lpLogFont);
|
|
operator HFONT() const;
|
|
~CFont();
|
|
|
|
// Create methods
|
|
HFONT CreateFontIndirect(const LOGFONT* lpLogFont);
|
|
HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL, BOOL bBold = FALSE, BOOL bItalic = FALSE);
|
|
HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC = NULL);
|
|
|
|
#ifndef _WIN32_WCE
|
|
HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
|
|
int nOrientation, int nWeight, DWORD dwItalic, DWORD dwUnderline,
|
|
DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision,
|
|
DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily,
|
|
LPCTSTR lpszFacename);
|
|
#endif // #ifndef _WIN32_WCE
|
|
|
|
// Attributes
|
|
LOGFONT GetLogFont() const;
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CPalette class
|
|
//
|
|
class CPalette : public CGDIObject
|
|
{
|
|
public:
|
|
CPalette();
|
|
CPalette(HPALETTE hPalette);
|
|
operator HPALETTE() const;
|
|
~CPalette();
|
|
|
|
// Create methods
|
|
HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette);
|
|
|
|
#ifndef _WIN32_WCE
|
|
HPALETTE CreateHalftonePalette(CDC* pDC);
|
|
#endif // !_WIN32_WCE
|
|
|
|
// Attributes
|
|
int GetEntryCount() const;
|
|
UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const;
|
|
UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors);
|
|
|
|
// Operations
|
|
#ifndef _WIN32_WCE
|
|
BOOL ResizePalette(UINT nNumEntries);
|
|
void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors);
|
|
#endif // !_WIN32_WCE
|
|
|
|
UINT GetNearestPaletteIndex (COLORREF crColor) const;
|
|
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CPen class
|
|
//
|
|
class CPen : public CGDIObject
|
|
{
|
|
public:
|
|
CPen();
|
|
CPen(HPEN hPen);
|
|
CPen(int nPenStyle, int nWidth, COLORREF crColor);
|
|
#ifndef _WIN32_WCE
|
|
CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL);
|
|
#endif // !_WIN32_WCE
|
|
operator HPEN() const;
|
|
~CPen();
|
|
|
|
HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor);
|
|
HPEN CreatePenIndirect(LPLOGPEN lpLogPen);
|
|
LOGPEN GetLogPen() const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
HPEN ExtCreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL);
|
|
EXTLOGPEN GetExtLogPen() const;
|
|
#endif // !_WIN32_WCE
|
|
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CRgn class
|
|
//
|
|
class CRgn : public CGDIObject
|
|
{
|
|
public:
|
|
CRgn();
|
|
CRgn(HRGN hRgn);
|
|
operator HRGN() const;
|
|
~CRgn ();
|
|
|
|
// Create methods
|
|
HRGN CreateRectRgn(int x1, int y1, int x2, int y2);
|
|
HRGN CreateRectRgnIndirect(const RECT& rc);
|
|
HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData);
|
|
|
|
#ifndef _WIN32_WCE
|
|
HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2);
|
|
HRGN CreateEllipticRgnIndirect(const RECT& rc);
|
|
HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode);
|
|
HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode);
|
|
HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);
|
|
HRGN CreateFromPath(HDC hDC);
|
|
#endif // !_WIN32_WCE
|
|
|
|
// Operations
|
|
void SetRectRgn(int x1, int y1, int x2, int y2);
|
|
void SetRectRgn(const RECT& rc);
|
|
int CombineRgn(CRgn* pRgnSrc1, CRgn* pRgnSrc2, int nCombineMode);
|
|
int CombineRgn(CRgn* pRgnSrc, int nCombineMode);
|
|
int CopyRgn(CRgn* pRgnSrc);
|
|
BOOL EqualRgn(CRgn* pRgn) const;
|
|
int OffsetRgn(int x, int y);
|
|
int OffsetRgn(POINT& pt);
|
|
int GetRgnBox(RECT& rc) const;
|
|
BOOL PtInRegion(int x, int y) const;
|
|
BOOL PtInRegion(POINT& pt) const;
|
|
BOOL RectInRegion(const RECT& rc) const;
|
|
int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const;
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CDC class
|
|
//
|
|
class CDC
|
|
{
|
|
friend class CWinApp;
|
|
friend class CWnd;
|
|
friend CDC* FromHandle(HDC hDC);
|
|
|
|
public:
|
|
struct DataMembers // A structure that contains the data members for CDC
|
|
{
|
|
std::vector<GDIPtr> m_vGDIObjects; // Smart pointers to internally created Bitmaps, Brushes, Fonts, Bitmaps and Regions
|
|
HDC hDC; // The HDC belonging to this CDC
|
|
long Count; // Reference count
|
|
BOOL bRemoveHDC; // Delete/Release the HDC on destruction
|
|
HWND hWnd; // The HWND of a Window or Client window DC
|
|
int nSavedDCState; // The save state of the HDC.
|
|
};
|
|
|
|
CDC(); // Constructs a new CDC without assigning a HDC
|
|
CDC(HDC hDC, HWND hWnd = 0); // Assigns a HDC to a new CDC
|
|
CDC(const CDC& rhs); // Constructs a new copy of the CDC
|
|
virtual ~CDC();
|
|
operator HDC() const { return m_pData->hDC; } // Converts a CDC to a HDC
|
|
CDC& operator = (const CDC& rhs); // Assigns a CDC to an existing CDC
|
|
|
|
void Attach(HDC hDC, HWND hWnd = 0);
|
|
void Destroy();
|
|
HDC Detach();
|
|
HDC GetHDC() const { return m_pData->hDC; }
|
|
CPalette* SelectPalette(const CPalette* pPalette, BOOL bForceBkgnd);
|
|
CBitmap* SelectObject(const CBitmap* pBitmap);
|
|
CBrush* SelectObject(const CBrush* pBrush);
|
|
CFont* SelectObject(const CFont* pFont);
|
|
CPalette* SelectObject(const CPalette* pPalette);
|
|
CPen* SelectObject(const CPen* pPen);
|
|
|
|
#ifndef _WIN32_WCE
|
|
void operator = (const HDC hDC);
|
|
#endif
|
|
|
|
// Initialization
|
|
BOOL CreateCompatibleDC(CDC* pDC);
|
|
BOOL CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData);
|
|
int GetDeviceCaps(int nIndex) const;
|
|
#ifndef _WIN32_WCE
|
|
BOOL CreateIC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData);
|
|
#endif
|
|
|
|
// Create and Select Bitmaps
|
|
CBitmap* CreateBitmap(int cx, int cy, UINT Planes, UINT BitsPerPixel, LPCVOID pvColors);
|
|
CBitmap* CreateCompatibleBitmap(CDC* pDC, int cx, int cy);
|
|
CBitmap* CreateDIBSection(CDC* pDC, const BITMAPINFO& bmi, UINT iUsage, LPVOID *ppvBits,
|
|
HANDLE hSection, DWORD dwOffset);
|
|
BITMAP GetBitmapData() const;
|
|
CBitmap* LoadBitmap(UINT nID);
|
|
CBitmap* LoadBitmap(LPCTSTR lpszName);
|
|
CBitmap* LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad);
|
|
CBitmap* LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad);
|
|
CBitmap* LoadOEMBitmap(UINT nIDBitmap); // for OBM_/OCR_/OIC
|
|
|
|
#ifndef _WIN32_WCE
|
|
CBitmap* CreateBitmapIndirect(LPBITMAP pBitmap);
|
|
CBitmap* CreateDIBitmap(CDC* pDC, const BITMAPINFOHEADER& bmih, DWORD fdwInit, LPCVOID lpbInit,
|
|
BITMAPINFO& bmi, UINT fuUsage);
|
|
CBitmap* CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/);
|
|
#endif
|
|
|
|
// Create and Select Brushes
|
|
CBrush* CreatePatternBrush(CBitmap* pBitmap);
|
|
CBrush* CreateSolidBrush(COLORREF rbg);
|
|
LOGBRUSH GetLogBrush() const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
CBrush* CreateBrushIndirect(LPLOGBRUSH pLogBrush);
|
|
CBrush* CreateHatchBrush(int fnStyle, COLORREF rgb);
|
|
CBrush* CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec);
|
|
CBrush* CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT iUsage);
|
|
#endif
|
|
|
|
// Create and Select Fonts
|
|
CFont* CreateFontIndirect(LPLOGFONT plf);
|
|
LOGFONT GetLogFont() const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
CFont* CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight,
|
|
DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet,
|
|
DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality,
|
|
DWORD fdwPitchAndFamily, LPCTSTR lpszFace);
|
|
#endif
|
|
|
|
// Create and Select Pens
|
|
CPen* CreatePen(int nStyle, int nWidth, COLORREF rgb);
|
|
CPen* CreatePenIndirect(LPLOGPEN pLogPen);
|
|
LOGPEN GetLogPen() const;
|
|
|
|
// Create Select Regions
|
|
int CreateRectRgn(int left, int top, int right, int bottom);
|
|
int CreateRectRgnIndirect(const RECT& rc);
|
|
int CreateFromData(const XFORM* Xform, DWORD nCount, const RGNDATA *pRgnData);
|
|
#ifndef _WIN32_WCE
|
|
int CreateEllipticRgn(int left, int top, int right, int bottom);
|
|
int CreateEllipticRgnIndirect(const RECT& rc);
|
|
int CreatePolygonRgn(LPPOINT ppt, int cPoints, int fnPolyFillMode);
|
|
int CreatePolyPolygonRgn(LPPOINT ppt, LPINT pPolyCounts, int nCount, int fnPolyFillMode);
|
|
#endif
|
|
|
|
// Wrappers for WinAPI functions
|
|
|
|
// Point and Line Drawing Functions
|
|
CPoint GetCurrentPosition() const;
|
|
CPoint MoveTo(int x, int y) const;
|
|
CPoint MoveTo(POINT pt) const;
|
|
BOOL LineTo(int x, int y) const;
|
|
BOOL LineTo(POINT pt) const;
|
|
COLORREF GetPixel(int x, int y) const;
|
|
COLORREF GetPixel(POINT pt) const;
|
|
COLORREF SetPixel(int x, int y, COLORREF crColor) const;
|
|
COLORREF SetPixel(POINT pt, COLORREF crColor) const;
|
|
#ifndef _WIN32_WCE
|
|
BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
|
|
BOOL Arc(RECT& rc, POINT ptStart, POINT ptEnd) const;
|
|
BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
|
|
BOOL ArcTo(RECT& rc, POINT ptStart, POINT ptEnd) const;
|
|
BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) const;
|
|
int GetArcDirection() const;
|
|
int SetArcDirection(int nArcDirection) const;
|
|
BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) const;
|
|
BOOL Polyline(LPPOINT lpPoints, int nCount) const;
|
|
BOOL PolyPolyline(const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount) const;
|
|
BOOL PolylineTo(const POINT* lpPoints, int nCount) const;
|
|
BOOL PolyBezier(const POINT* lpPoints, int nCount) const;
|
|
BOOL PolyBezierTo(const POINT* lpPoints, int nCount) const;
|
|
BOOL SetPixelV(int x, int y, COLORREF crColor) const;
|
|
BOOL SetPixelV(POINT pt, COLORREF crColor) const;
|
|
#endif
|
|
|
|
// Shape Drawing Functions
|
|
void DrawFocusRect(const RECT& rc) const;
|
|
BOOL Ellipse(int x1, int y1, int x2, int y2) const;
|
|
BOOL Ellipse(const RECT& rc) const;
|
|
BOOL Polygon(LPPOINT lpPoints, int nCount) const;
|
|
BOOL Rectangle(int x1, int y1, int x2, int y2) const;
|
|
BOOL Rectangle(const RECT& rc) const;
|
|
BOOL RoundRect(int x1, int y1, int x2, int y2, int nWidth, int nHeight) const;
|
|
BOOL RoundRect(const RECT& rc, int nWidth, int nHeight) const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
|
|
BOOL Chord(const RECT& rc, POINT ptStart, POINT ptEnd) const;
|
|
BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
|
|
BOOL Pie(const RECT& rc, POINT ptStart, POINT ptEnd) const;
|
|
BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) const;
|
|
#endif
|
|
|
|
// Fill and Image Drawing functions
|
|
BOOL FillRect(const RECT& rc, CBrush* pBrushr) const;
|
|
BOOL InvertRect(const RECT& rc) const;
|
|
BOOL DrawIconEx(int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, CBrush* pFlickerFreeDraw, UINT diFlags) const;
|
|
BOOL DrawEdge(const RECT& rc, UINT nEdge, UINT nFlags) const;
|
|
BOOL DrawFrameControl(const RECT& rc, UINT nType, UINT nState) const;
|
|
BOOL FillRgn(CRgn* pRgn, CBrush* pBrush) const;
|
|
void GradientFill(COLORREF Color1, COLORREF Color2, const RECT& rc, BOOL bVertical);
|
|
void SolidFill(COLORREF Color, const RECT& rc);
|
|
|
|
#ifndef _WIN32_WCE
|
|
BOOL DrawIcon(int x, int y, HICON hIcon) const;
|
|
BOOL DrawIcon(POINT point, HICON hIcon) const;
|
|
BOOL FrameRect(const RECT& rc, CBrush* pBrush) const;
|
|
BOOL PaintRgn(CRgn* pRgn) const;
|
|
#endif
|
|
|
|
// Bitmap Functions
|
|
void DrawBitmap(int x, int y, int cx, int cy, CBitmap& Bitmap, COLORREF clrMask);
|
|
int StretchDIBits(int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
|
|
int nSrcHeight, CONST VOID *lpBits, BITMAPINFO& bi, UINT iUsage, DWORD dwRop) const;
|
|
BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) const;
|
|
BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) const;
|
|
BOOL StretchBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
int GetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbi, UINT uUsage) const;
|
|
int SetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, LPBITMAPINFO lpbi, UINT fuColorUse) const;
|
|
int GetStretchBltMode() const;
|
|
int SetStretchBltMode(int iStretchMode) const;
|
|
BOOL FloodFill(int x, int y, COLORREF crColor) const;
|
|
BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) const;
|
|
#endif
|
|
|
|
// Brush Functions
|
|
#ifdef GetDCBrushColor
|
|
COLORREF GetDCBrushColor() const;
|
|
COLORREF SetDCBrushColor(COLORREF crColor) const;
|
|
#endif
|
|
|
|
// Clipping Functions
|
|
int ExcludeClipRect(int Left, int Top, int Right, int BottomRect);
|
|
int ExcludeClipRect(const RECT& rc);
|
|
int GetClipBox(RECT& rc);
|
|
int GetClipRgn(HRGN hrgn);
|
|
int IntersectClipRect(int Left, int Top, int Right, int Bottom);
|
|
int IntersectClipRect(const RECT& rc);
|
|
BOOL RectVisible(const RECT& rc);
|
|
int SelectClipRgn(CRgn* pRgn);
|
|
|
|
#ifndef _WIN32_WCE
|
|
int ExtSelectClipRgn(CRgn* pRgn, int fnMode);
|
|
int OffsetClipRgn(int nXOffset, int nYOffset);
|
|
BOOL PtVisible(int X, int Y);
|
|
#endif
|
|
|
|
// Co-ordinate Functions
|
|
#ifndef _WIN32_WCE
|
|
BOOL DPtoLP(LPPOINT lpPoints, int nCount) const;
|
|
BOOL DPtoLP(RECT& rc) const;
|
|
BOOL LPtoDP(LPPOINT lpPoints, int nCount) const;
|
|
BOOL LPtoDP(RECT& rc) const;
|
|
#endif
|
|
|
|
// Layout Functions
|
|
DWORD GetLayout() const;
|
|
DWORD SetLayout(DWORD dwLayout) const;
|
|
|
|
// Mapping functions
|
|
#ifndef _WIN32_WCE
|
|
int GetMapMode() const;
|
|
int SetMapMode(int nMapMode) const;
|
|
BOOL GetViewportOrgEx(LPPOINT lpPoint) const;
|
|
BOOL SetViewportOrgEx(int x, int y, LPPOINT lpPoint = NULL) const;
|
|
BOOL SetViewportOrgEx(POINT point, LPPOINT lpPointRet = NULL) const;
|
|
BOOL OffsetViewportOrgEx(int nWidth, int nHeight, LPPOINT lpPoint = NULL) const;
|
|
BOOL GetViewportExtEx(LPSIZE lpSize) const;
|
|
BOOL SetViewportExtEx(int x, int y, LPSIZE lpSize) const;
|
|
BOOL SetViewportExtEx(SIZE size, LPSIZE lpSizeRet) const;
|
|
BOOL ScaleViewportExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const;
|
|
BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint) const;
|
|
BOOL GetWindowExtEx(LPSIZE lpSize) const;
|
|
BOOL SetWindowExtEx(int x, int y, LPSIZE lpSize) const;
|
|
BOOL SetWindowExtEx(SIZE size, LPSIZE lpSizeRet) const;
|
|
BOOL ScaleWindowExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const;
|
|
BOOL GetWindowOrgEx(LPPOINT lpPoint) const;
|
|
BOOL SetWindowOrgEx(int x, int y, LPPOINT lpPoint) const;
|
|
BOOL SetWindowOrgEx(POINT point, LPPOINT lpPointRet) const;
|
|
BOOL OffsetWindowOrgEx(int nWidth, int nHeight, LPPOINT lpPoint) const;
|
|
#endif
|
|
|
|
// Printer Functions
|
|
int StartDoc(LPDOCINFO lpDocInfo) const;
|
|
int EndDoc() const;
|
|
int StartPage() const;
|
|
int EndPage() const;
|
|
int AbortDoc() const;
|
|
int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) const;
|
|
|
|
// Text Functions
|
|
int DrawText(LPCTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat) const;
|
|
BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lprc, LPCTSTR lpszString, int nCount = -1, LPINT lpDxWidths = NULL) const;
|
|
COLORREF GetBkColor() const;
|
|
int GetBkMode() const;
|
|
UINT GetTextAlign() const;
|
|
int GetTextFace(int nCount, LPTSTR lpszFacename) const;
|
|
COLORREF GetTextColor() const;
|
|
BOOL GetTextMetrics(TEXTMETRIC& Metrics) const;
|
|
COLORREF SetBkColor(COLORREF crColor) const;
|
|
int SetBkMode(int iBkMode) const;
|
|
UINT SetTextAlign(UINT nFlags) const;
|
|
COLORREF SetTextColor(COLORREF crColor) const;
|
|
|
|
#ifndef _WIN32_WCE
|
|
int DrawTextEx(LPTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat, LPDRAWTEXTPARAMS lpDTParams) const;
|
|
CSize GetTabbedTextExtent(LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions) const;
|
|
int GetTextCharacterExtra() const;
|
|
CSize GetTextExtentPoint32(LPCTSTR lpszString, int nCount) const;
|
|
BOOL GrayString(CBrush* pBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) const;
|
|
int SetTextCharacterExtra(int nCharExtra) const;
|
|
int SetTextJustification(int nBreakExtra, int nBreakCount) const;
|
|
CSize TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin) const;
|
|
BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1) const;
|
|
#endif
|
|
|
|
private:
|
|
void AddToMap();
|
|
static CDC* AddTempHDC(HDC hDC, HWND hWnd);
|
|
void Release();
|
|
BOOL RemoveFromMap();
|
|
|
|
DataMembers* m_pData; // pointer to the class's data members
|
|
};
|
|
|
|
class CClientDC : public CDC
|
|
{
|
|
public:
|
|
CClientDC(const CWnd* pWnd)
|
|
{
|
|
if (pWnd) assert(pWnd->IsWindow());
|
|
HWND hWnd = pWnd? pWnd->GetHwnd() : GetDesktopWindow();
|
|
Attach(::GetDC(hWnd), hWnd);
|
|
}
|
|
virtual ~CClientDC() {}
|
|
};
|
|
|
|
class CMemDC : public CDC
|
|
{
|
|
public:
|
|
CMemDC(const CDC* pDC)
|
|
{
|
|
if (pDC) assert(pDC->GetHDC());
|
|
HDC hDC = pDC? pDC->GetHDC() : NULL;
|
|
Attach(::CreateCompatibleDC(hDC));
|
|
}
|
|
virtual ~CMemDC() {}
|
|
};
|
|
|
|
class CPaintDC : public CDC
|
|
{
|
|
public:
|
|
CPaintDC(const CWnd* pWnd)
|
|
{
|
|
assert(pWnd->IsWindow());
|
|
m_hWnd = pWnd->GetHwnd();
|
|
Attach(::BeginPaint(pWnd->GetHwnd(), &m_ps), m_hWnd);
|
|
}
|
|
|
|
virtual ~CPaintDC() { ::EndPaint(m_hWnd, &m_ps); }
|
|
|
|
private:
|
|
HWND m_hWnd;
|
|
PAINTSTRUCT m_ps;
|
|
};
|
|
|
|
class CWindowDC : public CDC
|
|
{
|
|
public:
|
|
CWindowDC(const CWnd* pWnd)
|
|
{
|
|
if (pWnd) assert(pWnd->IsWindow());
|
|
HWND hWnd = pWnd? pWnd->GetHwnd() : GetDesktopWindow();
|
|
Attach(::GetWindowDC(hWnd), hWnd);
|
|
}
|
|
virtual ~CWindowDC() {}
|
|
};
|
|
|
|
#ifndef _WIN32_WCE
|
|
class CMetaFileDC : public CDC
|
|
{
|
|
public:
|
|
CMetaFileDC() : m_hMF(0), m_hEMF(0) {}
|
|
virtual ~CMetaFileDC()
|
|
{
|
|
if (m_hMF)
|
|
{
|
|
::CloseMetaFile(GetHDC());
|
|
::DeleteMetaFile(m_hMF);
|
|
}
|
|
if (m_hEMF)
|
|
{
|
|
::CloseEnhMetaFile(GetHDC());
|
|
::DeleteEnhMetaFile(m_hEMF);
|
|
}
|
|
}
|
|
void Create(LPCTSTR lpszFilename = NULL) { Attach(::CreateMetaFile(lpszFilename)); }
|
|
void CreateEnhanced(CDC* pDCRef, LPCTSTR lpszFileName, LPCRECT lpBounds, LPCTSTR lpszDescription)
|
|
{
|
|
HDC hDC = pDCRef? pDCRef->GetHDC() : NULL;
|
|
::CreateEnhMetaFile(hDC, lpszFileName, lpBounds, lpszDescription);
|
|
assert(GetHDC());
|
|
}
|
|
HMETAFILE Close() { return ::CloseMetaFile(GetHDC()); }
|
|
HENHMETAFILE CloseEnhanced() { return ::CloseEnhMetaFile(GetHDC()); }
|
|
|
|
private:
|
|
HMETAFILE m_hMF;
|
|
HENHMETAFILE m_hEMF;
|
|
};
|
|
#endif
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CBitmapInfoPtr class
|
|
// The CBitmapInfoPtr class is a convienient wrapper for the BITMAPINFO structure.
|
|
class CBitmapInfoPtr
|
|
{
|
|
public:
|
|
CBitmapInfoPtr(CBitmap* pBitmap)
|
|
{
|
|
BITMAP bmSource = pBitmap->GetBitmapData();
|
|
|
|
// Convert the color format to a count of bits.
|
|
WORD cClrBits = (WORD)(bmSource.bmPlanes * bmSource.bmBitsPixel);
|
|
if (cClrBits == 1) cClrBits = 1;
|
|
else if (cClrBits <= 4) cClrBits = 4;
|
|
else if (cClrBits <= 8) cClrBits = 8;
|
|
else if (cClrBits <= 16) cClrBits = 16;
|
|
else if (cClrBits <= 24) cClrBits = 24;
|
|
else cClrBits = 32;
|
|
|
|
// Allocate memory for the BITMAPINFO structure.
|
|
UINT uQuadSize = (cClrBits == 24)? 0 : sizeof(RGBQUAD) * (int)(1 << cClrBits);
|
|
m_bmi.assign(sizeof(BITMAPINFOHEADER) + uQuadSize, 0);
|
|
m_pbmiArray = (LPBITMAPINFO) &m_bmi[0];
|
|
|
|
m_pbmiArray->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
m_pbmiArray->bmiHeader.biHeight = bmSource.bmHeight;
|
|
m_pbmiArray->bmiHeader.biWidth = bmSource.bmWidth;
|
|
m_pbmiArray->bmiHeader.biPlanes = bmSource.bmPlanes;
|
|
m_pbmiArray->bmiHeader.biBitCount = bmSource.bmBitsPixel;
|
|
m_pbmiArray->bmiHeader.biCompression = BI_RGB;
|
|
if (cClrBits < 24)
|
|
m_pbmiArray->bmiHeader.biClrUsed = (1<<cClrBits);
|
|
}
|
|
LPBITMAPINFO get() const { return m_pbmiArray; }
|
|
operator LPBITMAPINFO() const { return m_pbmiArray; }
|
|
LPBITMAPINFO operator->() const { return m_pbmiArray; }
|
|
|
|
private:
|
|
CBitmapInfoPtr(const CBitmapInfoPtr&); // Disable copy construction
|
|
CBitmapInfoPtr& operator = (const CBitmapInfoPtr&); // Disable assignment operator
|
|
LPBITMAPINFO m_pbmiArray;
|
|
std::vector<byte> m_bmi;
|
|
};
|
|
|
|
|
|
CBitmap* FromHandle(HBITMAP hBitmap);
|
|
CBrush* FromHandle(HBRUSH hBrush);
|
|
CFont* FromHandle(HFONT hFont);
|
|
CPalette* FromHandle(HPALETTE hPalette);
|
|
CPen* FromHandle(HPEN hPen);
|
|
CRgn* FromHandle(HRGN hRgn);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
namespace Win32xx
|
|
{
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CGDIObject class
|
|
//
|
|
|
|
inline CGDIObject::CGDIObject()
|
|
// Constructs the CGDIObject
|
|
{
|
|
m_pData = new DataMembers;
|
|
m_pData->hGDIObject = 0;
|
|
m_pData->Count = 1L;
|
|
m_pData->bRemoveObject = TRUE;
|
|
}
|
|
|
|
inline CGDIObject::CGDIObject(const CGDIObject& rhs)
|
|
// Note: A copy of a CGDIObject is a clone of the original.
|
|
// Both objects manipulate the one HGDIOBJ.
|
|
{
|
|
m_pData = rhs.m_pData;
|
|
InterlockedIncrement(&m_pData->Count);
|
|
}
|
|
|
|
inline CGDIObject::~CGDIObject()
|
|
// Deconstructs the CGDIObject
|
|
{
|
|
Release();
|
|
}
|
|
|
|
inline CGDIObject& CGDIObject::operator = ( const CGDIObject& rhs )
|
|
// Note: A copy of a CGDIObject is a clone of the original.
|
|
// Both objects manipulate the one HGDIOBJ.
|
|
{
|
|
if (this != &rhs)
|
|
{
|
|
InterlockedIncrement(&rhs.m_pData->Count);
|
|
Release();
|
|
m_pData = rhs.m_pData;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline void CGDIObject::operator = (HGDIOBJ hObject)
|
|
{
|
|
assert(m_pData);
|
|
assert (m_pData->hGDIObject == NULL);
|
|
m_pData->hGDIObject = hObject;
|
|
}
|
|
|
|
inline void CGDIObject::AddToMap()
|
|
// Store the HDC and CDC pointer in the HDC map
|
|
{
|
|
assert( GetApp() );
|
|
GetApp()->m_csMapLock.Lock();
|
|
|
|
assert(m_pData->hGDIObject);
|
|
assert(!GetApp()->GetCGDIObjectFromMap(m_pData->hGDIObject));
|
|
|
|
GetApp()->m_mapGDI.insert(std::make_pair(m_pData->hGDIObject, this));
|
|
GetApp()->m_csMapLock.Release();
|
|
}
|
|
|
|
inline void CGDIObject::Attach(HGDIOBJ hObject)
|
|
// Attaches a GDI HANDLE to the CGDIObject.
|
|
// The HGDIOBJ will be automatically deleted when the destructor is called unless it is detached.
|
|
{
|
|
assert(m_pData);
|
|
|
|
if (m_pData->hGDIObject != NULL && m_pData->hGDIObject != hObject)
|
|
{
|
|
::DeleteObject(Detach());
|
|
}
|
|
|
|
CGDIObject* pObject = GetApp()->GetCGDIObjectFromMap(hObject);
|
|
if (pObject)
|
|
{
|
|
delete m_pData;
|
|
m_pData = pObject->m_pData;
|
|
InterlockedIncrement(&m_pData->Count);
|
|
}
|
|
else
|
|
{
|
|
m_pData->hGDIObject = hObject;
|
|
AddToMap();
|
|
}
|
|
}
|
|
|
|
inline HGDIOBJ CGDIObject::Detach()
|
|
// Detaches the HGDIOBJ from this object.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject);
|
|
|
|
GetApp()->m_csMapLock.Lock();
|
|
RemoveFromMap();
|
|
HGDIOBJ hObject = m_pData->hGDIObject;
|
|
m_pData->hGDIObject = 0;
|
|
|
|
if (m_pData->Count)
|
|
{
|
|
if (InterlockedDecrement(&m_pData->Count) == 0)
|
|
{
|
|
delete m_pData;
|
|
}
|
|
}
|
|
|
|
GetApp()->m_csMapLock.Release();
|
|
|
|
// Assign values to our data members
|
|
m_pData = new DataMembers;
|
|
m_pData->hGDIObject = 0;
|
|
m_pData->Count = 1L;
|
|
m_pData->bRemoveObject = TRUE;
|
|
|
|
return hObject;
|
|
}
|
|
|
|
inline HGDIOBJ CGDIObject::GetHandle() const
|
|
{
|
|
assert(m_pData);
|
|
return m_pData->hGDIObject;
|
|
}
|
|
|
|
inline int CGDIObject::GetObject(int nCount, LPVOID pObject) const
|
|
{
|
|
assert(m_pData);
|
|
return ::GetObject(m_pData->hGDIObject, nCount, pObject);
|
|
}
|
|
|
|
inline void CGDIObject::Release()
|
|
{
|
|
assert(m_pData);
|
|
BOOL bSucceeded = TRUE;
|
|
|
|
if (InterlockedDecrement(&m_pData->Count) == 0)
|
|
{
|
|
if (m_pData->hGDIObject != NULL)
|
|
{
|
|
if (m_pData->bRemoveObject)
|
|
bSucceeded = ::DeleteObject(m_pData->hGDIObject);
|
|
else
|
|
bSucceeded = TRUE;
|
|
}
|
|
|
|
RemoveFromMap();
|
|
delete m_pData;
|
|
m_pData = 0;
|
|
}
|
|
|
|
assert(bSucceeded);
|
|
}
|
|
|
|
inline BOOL CGDIObject::RemoveFromMap()
|
|
{
|
|
BOOL Success = FALSE;
|
|
|
|
if( GetApp() )
|
|
{
|
|
// Allocate an iterator for our HDC map
|
|
std::map<HGDIOBJ, CGDIObject*, CompareGDI>::iterator m;
|
|
|
|
CWinApp* pApp = GetApp();
|
|
if (pApp)
|
|
{
|
|
// Erase the CGDIObject pointer entry from the map
|
|
pApp->m_csMapLock.Lock();
|
|
m = pApp->m_mapGDI.find(m_pData->hGDIObject);
|
|
if (m != pApp->m_mapGDI.end())
|
|
{
|
|
pApp->m_mapGDI.erase(m);
|
|
Success = TRUE;
|
|
}
|
|
|
|
pApp->m_csMapLock.Release();
|
|
}
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CBitmap class
|
|
//
|
|
inline CBitmap::CBitmap()
|
|
{
|
|
}
|
|
|
|
inline CBitmap::CBitmap(HBITMAP hBitmap)
|
|
{
|
|
assert(m_pData);
|
|
Attach(hBitmap);
|
|
}
|
|
|
|
inline CBitmap::CBitmap(LPCTSTR lpszName)
|
|
{
|
|
LoadBitmap(lpszName);
|
|
}
|
|
|
|
inline CBitmap::CBitmap(int nID)
|
|
{
|
|
LoadBitmap(nID);
|
|
}
|
|
|
|
inline CBitmap::operator HBITMAP() const
|
|
{
|
|
assert(m_pData);
|
|
return (HBITMAP)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CBitmap::~CBitmap()
|
|
{
|
|
}
|
|
|
|
inline BOOL CBitmap::LoadBitmap(int nID)
|
|
// Loads a bitmap from a resource using the resource ID.
|
|
{
|
|
return LoadBitmap(MAKEINTRESOURCE(nID));
|
|
}
|
|
|
|
inline BOOL CBitmap::LoadBitmap(LPCTSTR lpszName)
|
|
// Loads a bitmap from a resource using the resource string.
|
|
{
|
|
assert(GetApp());
|
|
assert(m_pData);
|
|
|
|
HBITMAP hBitmap = (HBITMAP)::LoadImage(GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
|
if (hBitmap)
|
|
{
|
|
Attach(hBitmap);
|
|
}
|
|
return (0 != hBitmap); // boolean expression
|
|
}
|
|
|
|
inline BOOL CBitmap::LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad)
|
|
// Loads a bitmap from a resource using the resource ID.
|
|
{
|
|
return LoadImage(MAKEINTRESOURCE(nID), cxDesired, cyDesired, fuLoad);
|
|
}
|
|
|
|
inline BOOL CBitmap::LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad)
|
|
// Loads a bitmap from a resource using the resource string.
|
|
{
|
|
assert(GetApp());
|
|
assert(m_pData);
|
|
|
|
HBITMAP hBitmap = (HBITMAP)::LoadImage(GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, cxDesired, cyDesired, fuLoad);
|
|
if (hBitmap)
|
|
{
|
|
Attach(hBitmap);
|
|
}
|
|
return (0 != hBitmap); // boolean expression
|
|
}
|
|
|
|
inline BOOL CBitmap::LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
|
|
// Loads a predefined bitmap
|
|
// Predefined bitmaps include: OBM_BTNCORNERS, OBM_BTSIZE, OBM_CHECK, OBM_CHECKBOXES, OBM_CLOSE, OBM_COMBO
|
|
// OBM_DNARROW, OBM_DNARROWD, OBM_DNARROWI, OBM_LFARROW, OBM_LFARROWD, OBM_LFARROWI, OBM_MNARROW,OBM_OLD_CLOSE
|
|
// OBM_OLD_DNARROW, OBM_OLD_LFARROW, OBM_OLD_REDUCE, OBM_OLD_RESTORE, OBM_OLD_RGARROW, OBM_OLD_UPARROW
|
|
// OBM_OLD_ZOOM, OBM_REDUCE, OBM_REDUCED, OBM_RESTORE, OBM_RESTORED, OBM_RGARROW, OBM_RGARROWD, OBM_RGARROWI
|
|
// OBM_SIZE, OBM_UPARROW, OBM_UPARROWD, OBM_UPARROWI, OBM_ZOOM, OBM_ZOOMD
|
|
{
|
|
assert(m_pData);
|
|
|
|
HBITMAP hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
|
|
if (hBitmap)
|
|
{
|
|
Attach( ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap)) );
|
|
}
|
|
return (0 != hBitmap); // boolean expression
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HBITMAP CBitmap::CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/)
|
|
// Creates a new bitmap using the bitmap data and colors specified by the bitmap resource and the color mapping information.
|
|
{
|
|
assert(GetApp());
|
|
assert(m_pData);
|
|
HBITMAP hBitmap = ::CreateMappedBitmap(GetApp()->GetResourceHandle(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline HBITMAP CBitmap::CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, LPCVOID lpBits)
|
|
// Creates a bitmap with the specified width, height, and color format (color planes and bits-per-pixel).
|
|
{
|
|
assert(m_pData);
|
|
HBITMAP hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HBITMAP CBitmap::CreateBitmapIndirect(LPBITMAP lpBitmap)
|
|
// Creates a bitmap with the width, height, and color format specified in the BITMAP structure.
|
|
{
|
|
assert(m_pData);
|
|
HBITMAP hBitmap = ::CreateBitmapIndirect(lpBitmap);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline HBITMAP CBitmap::CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight)
|
|
// Creates a bitmap compatible with the device that is associated with the specified device context.
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
HBITMAP hBitmap = ::CreateCompatibleBitmap(pDC->GetHDC(), nWidth, nHeight);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
|
|
// Attributes
|
|
inline BITMAP CBitmap::GetBitmapData() const
|
|
// Retrieves the BITMAP structure
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
BITMAP bmp = {0};
|
|
::GetObject(m_pData->hGDIObject, sizeof(BITMAP), &bmp);
|
|
return bmp;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline CSize CBitmap::GetBitmapDimensionEx() const
|
|
// Retrieves the dimensions of a compatible bitmap.
|
|
// The retrieved dimensions must have been set by the SetBitmapDimensionEx function.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
CSize Size;
|
|
::GetBitmapDimensionEx((HBITMAP)m_pData->hGDIObject, &Size);
|
|
return Size;
|
|
}
|
|
|
|
inline CSize CBitmap::SetBitmapDimensionEx(int nWidth, int nHeight)
|
|
// The SetBitmapDimensionEx function assigns preferred dimensions to a bitmap.
|
|
// These dimensions can be used by applications; however, they are not used by the system.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
CSize Size;
|
|
::SetBitmapDimensionEx((HBITMAP)m_pData->hGDIObject, nWidth, nHeight, Size);
|
|
return Size;
|
|
}
|
|
|
|
// DIB support
|
|
inline HBITMAP CBitmap::CreateDIBitmap(CDC* pDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
|
|
// Creates a compatible bitmap (DDB) from a DIB and, optionally, sets the bitmap bits.
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetHDC(), lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline HBITMAP CBitmap::CreateDIBSection(CDC* pDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
|
|
// Creates a DIB that applications can write to directly. The function gives you a pointer to the location of the bitmap bit values.
|
|
// You can supply a handle to a file-mapping object that the function will use to create the bitmap, or you can let the system allocate the memory for the bitmap.
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
HBITMAP hBitmap = ::CreateDIBSection(pDC->GetHDC(), lpbmi, uColorUse, ppvBits, hSection, dwOffset);
|
|
Attach(hBitmap);
|
|
return hBitmap;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline int CBitmap::GetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
|
|
// Retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::GetDIBits(pDC->GetHDC(), (HBITMAP)m_pData->hGDIObject, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
|
|
}
|
|
|
|
inline int CBitmap::SetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
|
|
// Sets the pixels in a compatible bitmap (DDB) using the color data found in the specified DIB.
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::SetDIBits(pDC->GetHDC(), (HBITMAP)m_pData->hGDIObject, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Definitions of the CBrush class
|
|
//
|
|
inline CBrush::CBrush()
|
|
{
|
|
}
|
|
|
|
inline CBrush::CBrush(HBRUSH hBrush)
|
|
{
|
|
assert(m_pData);
|
|
Attach(hBrush);
|
|
}
|
|
|
|
inline CBrush::CBrush(COLORREF crColor)
|
|
{
|
|
Attach( ::CreateSolidBrush(crColor) );
|
|
assert (m_pData->hGDIObject);
|
|
}
|
|
|
|
inline CBrush::operator HBRUSH() const
|
|
{
|
|
assert(m_pData);
|
|
return (HBRUSH)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CBrush::~CBrush()
|
|
{
|
|
}
|
|
|
|
inline HBRUSH CBrush::CreateSolidBrush(COLORREF crColor)
|
|
// Creates a logical brush that has the specified solid color.
|
|
{
|
|
assert(m_pData);
|
|
HBRUSH hBrush = ::CreateSolidBrush(crColor);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HBRUSH CBrush::CreateHatchBrush(int nIndex, COLORREF crColor)
|
|
// Creates a logical brush that has the specified hatch pattern and color.
|
|
{
|
|
assert(m_pData);
|
|
HBRUSH hBrush = ::CreateHatchBrush(nIndex, crColor);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
inline HBRUSH CBrush::CreateBrushIndirect(LPLOGBRUSH lpLogBrush)
|
|
// Creates a logical brush from style, color, and pattern specified in the LOGPRUSH struct.
|
|
{
|
|
assert(m_pData);
|
|
HBRUSH hBrush = ::CreateBrushIndirect(lpLogBrush);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
inline HBRUSH CBrush::CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec)
|
|
// Creates a logical brush that has the pattern specified by the specified device-independent bitmap (DIB).
|
|
{
|
|
assert(m_pData);
|
|
HBRUSH hBrush = ::CreateDIBPatternBrush(hglbDIBPacked, fuColorSpec);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
inline HBRUSH CBrush::CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT nUsage)
|
|
// Creates a logical brush that has the pattern specified by the device-independent bitmap (DIB).
|
|
{
|
|
assert(m_pData);
|
|
HBRUSH hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
#endif // !defined(_WIN32_WCE)
|
|
|
|
inline HBRUSH CBrush::CreatePatternBrush(CBitmap* pBitmap)
|
|
// Creates a logical brush with the specified bitmap pattern. The bitmap can be a DIB section bitmap,
|
|
// which is created by the CreateDIBSection function, or it can be a device-dependent bitmap.
|
|
{
|
|
assert(m_pData);
|
|
assert(pBitmap);
|
|
HBRUSH hBrush = ::CreatePatternBrush(*pBitmap);
|
|
Attach(hBrush);
|
|
return hBrush;
|
|
}
|
|
|
|
inline LOGBRUSH CBrush::GetLogBrush() const
|
|
// Retrieves the LOGBRUSH structure that defines the style, color, and pattern of a physical brush.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
LOGBRUSH LogBrush = {0};
|
|
::GetObject (m_pData->hGDIObject, sizeof(LOGBRUSH), &LogBrush);
|
|
return LogBrush;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Definitions of the CFont class
|
|
//
|
|
inline CFont::CFont()
|
|
{
|
|
}
|
|
|
|
inline CFont::CFont(HFONT hFont)
|
|
{
|
|
assert(m_pData);
|
|
Attach(hFont);
|
|
}
|
|
|
|
inline CFont::CFont(const LOGFONT* lpLogFont)
|
|
{
|
|
assert(m_pData);
|
|
Attach( ::CreateFontIndirect(lpLogFont) );
|
|
}
|
|
|
|
inline CFont::operator HFONT() const
|
|
{
|
|
assert(m_pData);
|
|
return (HFONT)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CFont::~CFont()
|
|
{
|
|
}
|
|
|
|
inline HFONT CFont::CreateFontIndirect(const LOGFONT* lpLogFont)
|
|
// Creates a logical font that has the specified characteristics.
|
|
{
|
|
assert(m_pData);
|
|
HFONT hFont = ::CreateFontIndirect(lpLogFont);
|
|
Attach(hFont);
|
|
return hFont;
|
|
}
|
|
|
|
inline HFONT CFont::CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC /*= NULL*/, BOOL bBold /*= FALSE*/, BOOL bItalic /*= FALSE*/)
|
|
// Creates a font of a specified typeface and point size.
|
|
{
|
|
LOGFONT logFont = { 0 };
|
|
logFont.lfCharSet = DEFAULT_CHARSET;
|
|
logFont.lfHeight = nPointSize;
|
|
|
|
lstrcpy(logFont.lfFaceName, lpszFaceName);
|
|
|
|
if (bBold)
|
|
logFont.lfWeight = FW_BOLD;
|
|
if (bItalic)
|
|
logFont.lfItalic = (BYTE)TRUE;
|
|
|
|
return CreatePointFontIndirect(&logFont, pDC);
|
|
}
|
|
|
|
inline HFONT CFont::CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC /* = NULL*/)
|
|
// Creates a font of a specified typeface and point size.
|
|
// This function automatically converts the height in lfHeight to logical units using the specified device context.
|
|
{
|
|
HDC hDC = pDC? pDC->GetHDC() : NULL;
|
|
HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(HWND_DESKTOP);
|
|
|
|
// 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(((::GetDeviceCaps(hDC1, LOGPIXELSY)* logFont.lfHeight)/ 720));
|
|
#endif // _WIN32_WCE
|
|
|
|
if (hDC == NULL)
|
|
::ReleaseDC (NULL, hDC1);
|
|
|
|
return CreateFontIndirect (&logFont);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
|
|
inline HFONT CFont::CreateFont(int nHeight, int nWidth, int nEscapement,
|
|
int nOrientation, int nWeight, DWORD dwItalic, DWORD dwUnderline,
|
|
DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision,
|
|
DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily,
|
|
LPCTSTR lpszFacename)
|
|
// Creates a logical font with the specified characteristics.
|
|
{
|
|
HFONT hFont = ::CreateFont(nHeight, nWidth, nEscapement,
|
|
nOrientation, nWeight, dwItalic, dwUnderline, dwStrikeOut,
|
|
dwCharSet, dwOutPrecision, dwClipPrecision, dwQuality,
|
|
dwPitchAndFamily, lpszFacename);
|
|
|
|
Attach(hFont);
|
|
return hFont;
|
|
}
|
|
#endif // #ifndef _WIN32_WCE
|
|
|
|
inline LOGFONT CFont::GetLogFont() const
|
|
// Retrieves the Logfont structure that contains font attributes.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
LOGFONT LogFont = {0};
|
|
::GetObject(m_pData->hGDIObject, sizeof(LOGFONT), &LogFont);
|
|
return LogFont;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Definitions of the CPalette class
|
|
//
|
|
inline CPalette::CPalette()
|
|
{
|
|
}
|
|
|
|
inline CPalette::CPalette(HPALETTE hPalette)
|
|
{
|
|
Attach(hPalette);
|
|
}
|
|
|
|
inline CPalette::operator HPALETTE() const
|
|
{
|
|
assert(m_pData);
|
|
return (HPALETTE)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CPalette::~CPalette ()
|
|
{
|
|
}
|
|
|
|
inline HPALETTE CPalette::CreatePalette(LPLOGPALETTE lpLogPalette)
|
|
// Creates a logical palette from the information in the specified LOGPALETTE structure.
|
|
{
|
|
assert(m_pData);
|
|
HPALETTE hPalette = ::CreatePalette (lpLogPalette);
|
|
Attach(hPalette);
|
|
return hPalette;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HPALETTE CPalette::CreateHalftonePalette(CDC* pDC)
|
|
// Creates a halftone palette for the specified device context (DC).
|
|
{
|
|
assert(m_pData);
|
|
assert(pDC);
|
|
HPALETTE hPalette = ::CreateHalftonePalette(pDC->GetHDC());
|
|
Attach(hPalette);
|
|
return hPalette;
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline int CPalette::GetEntryCount() const
|
|
// Retrieve the number of entries in the palette.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
WORD nEntries = 0;
|
|
::GetObject(m_pData->hGDIObject, sizeof(WORD), &nEntries);
|
|
return (int)nEntries;
|
|
}
|
|
|
|
inline UINT CPalette::GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
|
|
// Retrieves a specified range of palette entries from the palette.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::GetPaletteEntries((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
|
|
}
|
|
|
|
inline UINT CPalette::SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
|
|
// Sets RGB (red, green, blue) color values and flags in a range of entries in the palette.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::SetPaletteEntries((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline void CPalette::AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
|
|
// Replaces entries in the palette.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
::AnimatePalette((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
|
|
}
|
|
|
|
inline BOOL CPalette::ResizePalette(UINT nNumEntries)
|
|
// Increases or decreases the size of the palette based on the specified value.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::ResizePalette((HPALETTE)m_pData->hGDIObject, nNumEntries);
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline UINT CPalette::GetNearestPaletteIndex(COLORREF crColor) const
|
|
// Retrieves the index for the entry in the palette most closely matching a specified color value.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::GetNearestPaletteIndex((HPALETTE)m_pData->hGDIObject, crColor);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Declarations for the CPen class
|
|
//
|
|
inline CPen::CPen()
|
|
{
|
|
}
|
|
|
|
inline CPen::CPen(HPEN hPen)
|
|
{
|
|
Attach(hPen);
|
|
}
|
|
|
|
inline CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor)
|
|
{
|
|
assert(m_pData);
|
|
Attach( ::CreatePen(nPenStyle, nWidth, crColor) );
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline CPen::CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount /*= 0*/, const DWORD* lpStyle /*= NULL*/)
|
|
{
|
|
assert(m_pData);
|
|
Attach( ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle) );
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline CPen::operator HPEN () const
|
|
{
|
|
assert(m_pData);
|
|
return (HPEN)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CPen::~CPen()
|
|
{
|
|
}
|
|
|
|
inline HPEN CPen::CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
|
|
// Creates a logical pen that has the specified style, width, and color.
|
|
{
|
|
assert(m_pData);
|
|
HPEN hPen = ::CreatePen(nPenStyle, nWidth, crColor);
|
|
Attach(hPen);
|
|
return hPen;
|
|
}
|
|
|
|
inline HPEN CPen::CreatePenIndirect(LPLOGPEN lpLogPen)
|
|
// Creates a logical cosmetic pen that has the style, width, and color specified in a structure.
|
|
{
|
|
assert(m_pData);
|
|
HPEN hPen = ::CreatePenIndirect(lpLogPen);
|
|
Attach(hPen);
|
|
return hPen;
|
|
}
|
|
|
|
inline LOGPEN CPen::GetLogPen() const
|
|
{
|
|
// Retrieves the LOGPEN struct that specifies the pen's style, width, and color.
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
|
|
LOGPEN LogPen = {0};
|
|
::GetObject(m_pData->hGDIObject, sizeof(LOGPEN), &LogPen);
|
|
return LogPen;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HPEN CPen::ExtCreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount /* = 0*/, const DWORD* lpStyle /*= NULL*/)
|
|
// Creates a logical cosmetic or geometric pen that has the specified style, width, and brush attributes.
|
|
{
|
|
assert(m_pData);
|
|
HPEN hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
|
|
Attach(hPen);
|
|
return hPen;
|
|
}
|
|
|
|
inline EXTLOGPEN CPen::GetExtLogPen() const
|
|
// Retrieves the EXTLOGPEN struct that specifies the pen's style, width, color and brush attributes.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
|
|
EXTLOGPEN ExLogPen = {0};
|
|
::GetObject(m_pData->hGDIObject, sizeof(EXTLOGPEN), &ExLogPen);
|
|
return ExLogPen;
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Definitions of the CRgn class
|
|
//
|
|
inline CRgn::CRgn()
|
|
{
|
|
}
|
|
|
|
inline CRgn::CRgn(HRGN hRgn)
|
|
{
|
|
assert(m_pData);
|
|
Attach(hRgn);
|
|
}
|
|
|
|
inline CRgn::operator HRGN() const
|
|
{
|
|
assert(m_pData);
|
|
return (HRGN)m_pData->hGDIObject;
|
|
}
|
|
|
|
inline CRgn::~CRgn()
|
|
{
|
|
}
|
|
|
|
inline HRGN CRgn::CreateRectRgn(int x1, int y1, int x2, int y2)
|
|
// Creates a rectangular region.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreateRectRgn(x1, y1, x2, y2);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreateRectRgnIndirect(const RECT& rc)
|
|
// Creates a rectangular region.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreateRectRgnIndirect(&rc);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline HRGN CRgn::CreateEllipticRgn(int x1, int y1, int x2, int y2)
|
|
// Creates an elliptical region.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreateEllipticRgnIndirect(const RECT& rc)
|
|
// Creates an elliptical region.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreateEllipticRgnIndirect(&rc);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
|
|
// Creates a polygonal region.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
|
|
// Creates a region consisting of a series of polygons. The polygons can overlap.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
|
|
// Creates a rectangular region with rounded corners.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline HRGN CRgn::CreateFromPath(HDC hDC)
|
|
// Creates a region from the path that is selected into the specified device context.
|
|
// The resulting region uses device coordinates.
|
|
{
|
|
assert(m_pData);
|
|
assert(hDC != NULL);
|
|
HRGN hRgn = ::PathToRegion(hDC);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
#endif // !_WIN32_WCE
|
|
|
|
inline HRGN CRgn::CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
|
|
// Creates a region from the specified region and transformation data.
|
|
{
|
|
assert(m_pData);
|
|
HRGN hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
|
|
Attach(hRgn);
|
|
return hRgn;
|
|
}
|
|
|
|
inline void CRgn::SetRectRgn(int x1, int y1, int x2, int y2)
|
|
// converts the region into a rectangular region with the specified coordinates.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
::SetRectRgn((HRGN)m_pData->hGDIObject, x1, y1, x2, y2);
|
|
}
|
|
|
|
inline void CRgn::SetRectRgn(const RECT& rc)
|
|
// converts the region into a rectangular region with the specified coordinates.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
::SetRectRgn((HRGN)m_pData->hGDIObject, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
inline int CRgn::CombineRgn(CRgn* pRgnSrc1, CRgn* pRgnSrc2, int nCombineMode)
|
|
// Combines two sepcified regions and stores the result.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
assert(pRgnSrc1);
|
|
assert(pRgnSrc2);
|
|
return ::CombineRgn((HRGN)m_pData->hGDIObject, *pRgnSrc1, *pRgnSrc2, nCombineMode);
|
|
}
|
|
|
|
inline int CRgn::CombineRgn(CRgn* pRgnSrc, int nCombineMode)
|
|
// Combines the sepcified region with the current region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
assert(pRgnSrc);
|
|
return ::CombineRgn((HRGN)m_pData->hGDIObject, (HRGN)m_pData->hGDIObject, *pRgnSrc, nCombineMode);
|
|
}
|
|
|
|
inline int CRgn::CopyRgn(CRgn* pRgnSrc)
|
|
// Assigns the specified region to the current region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject == NULL);
|
|
assert(pRgnSrc);
|
|
return ::CombineRgn((HRGN)m_pData->hGDIObject, *pRgnSrc, NULL, RGN_COPY);
|
|
}
|
|
|
|
inline BOOL CRgn::EqualRgn(CRgn* pRgn) const
|
|
// Checks the two specified regions to determine whether they are identical.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
assert(pRgn);
|
|
return ::EqualRgn((HRGN)m_pData->hGDIObject, *pRgn);
|
|
}
|
|
|
|
inline int CRgn::OffsetRgn(int x, int y)
|
|
// Moves a region by the specified offsets.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::OffsetRgn((HRGN)m_pData->hGDIObject, x, y);
|
|
}
|
|
|
|
inline int CRgn::OffsetRgn(POINT& pt)
|
|
// Moves a region by the specified offsets.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::OffsetRgn((HRGN)m_pData->hGDIObject, pt.x, pt.y);
|
|
}
|
|
|
|
inline int CRgn::GetRgnBox(RECT& rc) const
|
|
// Retrieves the bounding rectangle of the region, and stores it in the specified RECT.
|
|
// The return value indicates the region's complexity: NULLREGION;SIMPLEREGION; or COMPLEXREGION.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::GetRgnBox((HRGN)m_pData->hGDIObject, &rc);
|
|
}
|
|
|
|
inline int CRgn::GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
|
|
// Fills the specified buffer with data describing a region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return (int)::GetRegionData((HRGN)m_pData->hGDIObject, nDataSize, lpRgnData);
|
|
}
|
|
|
|
inline BOOL CRgn::PtInRegion(int x, int y) const
|
|
// Determines whether the specified point is inside the specified region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::PtInRegion((HRGN)m_pData->hGDIObject, x, y);
|
|
}
|
|
|
|
inline BOOL CRgn::PtInRegion(POINT& pt) const
|
|
// Determines whether the specified point is inside the specified region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::PtInRegion((HRGN)m_pData->hGDIObject, pt.x, pt.y);
|
|
}
|
|
|
|
inline BOOL CRgn::RectInRegion(const RECT& rc) const
|
|
// Determines whether the specified rect is inside the specified region.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hGDIObject != NULL);
|
|
return ::RectInRegion((HRGN)m_pData->hGDIObject, &rc);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
// Definitions of the CDC class
|
|
//
|
|
inline CDC::CDC()
|
|
{
|
|
// Allocate memory for our data members
|
|
m_pData = new DataMembers;
|
|
|
|
// Assign values to our data members
|
|
m_pData->hDC = 0;
|
|
m_pData->Count = 1L;
|
|
m_pData->bRemoveHDC = TRUE;
|
|
m_pData->hWnd = 0;
|
|
}
|
|
|
|
inline CDC::CDC(HDC hDC, HWND hWnd /*= 0*/)
|
|
// This constructor assigns an existing HDC to the CDC
|
|
// The HDC WILL be released or deleted when the CDC object is destroyed
|
|
// The hWnd paramter is only used in WindowsCE. It specifies the HWND of a Window or
|
|
// Window Client DC
|
|
|
|
// Note: this constructor permits a call like this:
|
|
// CDC MyCDC = SomeHDC;
|
|
// or
|
|
// CDC MyCDC = ::CreateCompatibleDC(SomeHDC);
|
|
// or
|
|
// CDC MyCDC = ::GetDC(SomeHWND);
|
|
{
|
|
UNREFERENCED_PARAMETER(hWnd);
|
|
assert(hDC);
|
|
|
|
CDC* pDC = GetApp()->GetCDCFromMap(hDC);
|
|
if (pDC)
|
|
{
|
|
m_pData = pDC->m_pData;
|
|
InterlockedIncrement(&m_pData->Count);
|
|
}
|
|
else
|
|
{
|
|
// Allocate memory for our data members
|
|
m_pData = new DataMembers;
|
|
|
|
// Assign values to our data members
|
|
m_pData->hDC = hDC;
|
|
m_pData->Count = 1L;
|
|
m_pData->bRemoveHDC = TRUE;
|
|
m_pData->nSavedDCState = ::SaveDC(hDC);
|
|
#ifndef _WIN32_WCE
|
|
m_pData->hWnd = ::WindowFromDC(hDC);
|
|
#else
|
|
m_pData->hWnd = hWnd;
|
|
#endif
|
|
if (m_pData->hWnd)
|
|
AddToMap();
|
|
}
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline void CDC::operator = (const HDC hDC)
|
|
// Note: this assignment operater permits a call like this:
|
|
// CDC MyCDC;
|
|
// MyCDC = SomeHDC;
|
|
{
|
|
Attach(hDC);
|
|
}
|
|
#endif
|
|
|
|
inline CDC::CDC(const CDC& rhs) // Copy constructor
|
|
// The copy constructor is called when a temporary copy of the CDC needs to be created.
|
|
// This can happen when a CDC is passed by value in a function call. Each CDC copy manages
|
|
// the same Device Context and GDI objects.
|
|
{
|
|
m_pData = rhs.m_pData;
|
|
InterlockedIncrement(&m_pData->Count);
|
|
}
|
|
|
|
inline CDC& CDC::operator = (const CDC& rhs)
|
|
// Note: A copy of a CDC is a clone of the original.
|
|
// Both objects manipulate the one HDC
|
|
{
|
|
if (this != &rhs)
|
|
{
|
|
InterlockedIncrement(&rhs.m_pData->Count);
|
|
Release();
|
|
m_pData = rhs.m_pData;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline CDC::~CDC ()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
inline void CDC::AddToMap()
|
|
// Store the HDC and CDC pointer in the HDC map
|
|
{
|
|
assert( GetApp() );
|
|
assert(m_pData->hDC);
|
|
GetApp()->m_csMapLock.Lock();
|
|
|
|
assert(m_pData->hDC);
|
|
assert(!GetApp()->GetCDCFromMap(m_pData->hDC));
|
|
|
|
GetApp()->m_mapHDC.insert(std::make_pair(m_pData->hDC, this));
|
|
GetApp()->m_csMapLock.Release();
|
|
}
|
|
|
|
inline void CDC::Attach(HDC hDC, HWND hWnd /* = 0*/)
|
|
// Attaches a HDC to the CDC object.
|
|
// The HDC will be automatically deleted or released when the destructor is called.
|
|
// The hWnd parameter is only used on WindowsCE. It specifies the HWND of a Window or
|
|
// Window Client DC
|
|
{
|
|
UNREFERENCED_PARAMETER(hWnd);
|
|
assert(m_pData);
|
|
assert(0 == m_pData->hDC);
|
|
assert(hDC);
|
|
|
|
CDC* pDC = GetApp()->GetCDCFromMap(hDC);
|
|
if (pDC)
|
|
{
|
|
delete m_pData;
|
|
m_pData = pDC->m_pData;
|
|
InterlockedIncrement(&m_pData->Count);
|
|
}
|
|
else
|
|
{
|
|
m_pData->hDC = hDC;
|
|
|
|
#ifndef _WIN32_WCE
|
|
m_pData->hWnd = ::WindowFromDC(hDC);
|
|
#else
|
|
m_pData->hWnd = hWnd;
|
|
#endif
|
|
|
|
if (m_pData->hWnd == 0)
|
|
AddToMap();
|
|
m_pData->nSavedDCState = ::SaveDC(hDC);
|
|
}
|
|
}
|
|
|
|
inline HDC CDC::Detach()
|
|
// Detaches the HDC from this object.
|
|
{
|
|
assert(m_pData);
|
|
assert(m_pData->hDC);
|
|
|
|
GetApp()->m_csMapLock.Lock();
|
|
RemoveFromMap();
|
|
HDC hDC = m_pData->hDC;
|
|
m_pData->hDC = 0;
|
|
|
|
if (m_pData->Count)
|
|
{
|
|
if (InterlockedDecrement(&m_pData->Count) == 0)
|
|
{
|
|
delete m_pData;
|
|
}
|
|
}
|
|
|
|
GetApp()->m_csMapLock.Release();
|
|
|
|
// Assign values to our data members
|
|
m_pData = new DataMembers;
|
|
m_pData->hDC = 0;
|
|
m_pData->Count = 1L;
|
|
m_pData->bRemoveHDC = TRUE;
|
|
m_pData->hWnd = 0;
|
|
|
|
return hDC;
|
|
}
|
|
|
|
// Initialization
|
|
inline BOOL CDC::CreateCompatibleDC(CDC* pDC)
|
|
// Returns a memory device context (DC) compatible with the specified device.
|
|
{
|
|
assert(m_pData->hDC == NULL);
|
|
HDC hdcSource = (pDC == NULL)? NULL : pDC->GetHDC();
|
|
HDC hDC = ::CreateCompatibleDC(hdcSource);
|
|
if (hDC)
|
|
{
|
|
m_pData->hDC = hDC;
|
|
AddToMap();
|
|
}
|
|
return (hDC != NULL); // boolean expression
|
|
}
|
|
|
|
inline BOOL CDC::CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData)
|
|
// Returns a device context (DC) for a device using the specified name.
|
|
{
|
|
assert(m_pData->hDC == NULL);
|
|
HDC hDC = ::CreateDC(lpszDriver, lpszDevice, lpszOutput, pInitData);
|
|
if (hDC)
|
|
{
|
|
m_pData->hDC = hDC;
|
|
AddToMap();
|
|
}
|
|
return (hDC != NULL); // boolean expression
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline BOOL CDC::CreateIC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData)
|
|
{
|
|
assert(m_pData->hDC == NULL);
|
|
HDC hDC = ::CreateIC(lpszDriver, lpszDevice, lpszOutput, pInitData);
|
|
if (hDC)
|
|
{
|
|
m_pData->hDC = hDC;
|
|
AddToMap();
|
|
}
|
|
return (hDC != NULL); // boolean expression
|
|
}
|
|
#endif
|
|
|
|
inline void CDC::DrawBitmap(int x, int y, int cx, int cy, CBitmap& Bitmap, COLORREF clrMask)
|
|
// Draws the specified bitmap to the specified DC using the mask colour provided as the transparent colour
|
|
// Suitable for use with a Window DC or a memory DC
|
|
{
|
|
// Create the Image memory DC
|
|
CMemDC dcImage(this);
|
|
dcImage.SetBkColor(clrMask);
|
|
dcImage.SelectObject(&Bitmap);
|
|
|
|
// Create the Mask memory DC
|
|
CMemDC dcMask(this);
|
|
dcMask.CreateBitmap(cx, cy, 1, 1, NULL);
|
|
dcMask.BitBlt(0, 0, cx, cy, &dcImage, 0, 0, SRCCOPY);
|
|
|
|
// Mask the image to 'this' DC
|
|
BitBlt(x, y, cx, cy, &dcImage, 0, 0, SRCINVERT);
|
|
BitBlt(x, y, cx, cy, &dcMask, 0, 0, SRCAND);
|
|
BitBlt(x, y, cx, cy, &dcImage, 0, 0, SRCINVERT);
|
|
}
|
|
|
|
inline CDC* CDC::AddTempHDC(HDC hDC, HWND hWnd)
|
|
// Returns the CDC object associated with the device context handle
|
|
// The HDC is removed when the CDC is destroyed
|
|
{
|
|
assert( GetApp() );
|
|
CDC* pDC = new CDC;
|
|
pDC->m_pData->hDC = hDC;
|
|
GetApp()->AddTmpDC(pDC);
|
|
pDC->m_pData->bRemoveHDC = TRUE;
|
|
pDC->m_pData->hWnd = hWnd;
|
|
return pDC;
|
|
}
|
|
|
|
inline void CDC::GradientFill(COLORREF Color1, COLORREF Color2, const RECT& rc, BOOL bVertical)
|
|
// An efficient color gradient filler compatible with all Windows operating systems
|
|
{
|
|
int Width = rc.right - rc.left;
|
|
int Height = rc.bottom - rc.top;
|
|
|
|
int r1 = GetRValue(Color1);
|
|
int g1 = GetGValue(Color1);
|
|
int b1 = GetBValue(Color1);
|
|
|
|
int r2 = GetRValue(Color2);
|
|
int g2 = GetGValue(Color2);
|
|
int b2 = GetBValue(Color2);
|
|
|
|
COLORREF OldBkColor = GetBkColor();
|
|
|
|
if (bVertical)
|
|
{
|
|
for(int i=0; i < Width; ++i)
|
|
{
|
|
int r = r1 + (i * (r2-r1) / Width);
|
|
int g = g1 + (i * (g2-g1) / Width);
|
|
int b = b1 + (i * (b2-b1) / Width);
|
|
SetBkColor(RGB(r, g, b));
|
|
CRect line( i + rc.left, rc.top, i + 1 + rc.left, rc.top+Height);
|
|
ExtTextOut(0, 0, ETO_OPAQUE, line, NULL, 0, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int i=0; i < Height; ++i)
|
|
{
|
|
int r = r1 + (i * (r2-r1) / Height);
|
|
int g = g1 + (i * (g2-g1) / Height);
|
|
int b = b1 + (i * (b2-b1) / Height);
|
|
SetBkColor(RGB(r, g, b));
|
|
CRect line(rc.left, i + rc.top, rc.left+Width, i + 1 + rc.top);
|
|
ExtTextOut(0, 0, ETO_OPAQUE, line, NULL, 0, 0);
|
|
}
|
|
}
|
|
|
|
SetBkColor(OldBkColor);
|
|
}
|
|
|
|
inline void CDC::Release()
|
|
{
|
|
GetApp()->m_csMapLock.Lock();
|
|
|
|
if (m_pData->Count)
|
|
{
|
|
if (InterlockedDecrement(&m_pData->Count) == 0)
|
|
{
|
|
Destroy();
|
|
delete m_pData;
|
|
m_pData = 0;
|
|
}
|
|
}
|
|
|
|
GetApp()->m_csMapLock.Release();
|
|
}
|
|
|
|
inline BOOL CDC::RemoveFromMap()
|
|
{
|
|
BOOL Success = FALSE;
|
|
|
|
if( GetApp() )
|
|
{
|
|
// Allocate an iterator for our HDC map
|
|
std::map<HDC, CDC*, CompareHDC>::iterator m;
|
|
|
|
CWinApp* pApp = GetApp();
|
|
if (pApp)
|
|
{
|
|
// Erase the CDC pointer entry from the map
|
|
pApp->m_csMapLock.Lock();
|
|
m = pApp->m_mapHDC.find(m_pData->hDC);
|
|
if (m != pApp->m_mapHDC.end())
|
|
{
|
|
pApp->m_mapHDC.erase(m);
|
|
Success = TRUE;
|
|
}
|
|
|
|
pApp->m_csMapLock.Release();
|
|
}
|
|
}
|
|
return Success;
|
|
}
|
|
|
|
inline void CDC::SolidFill(COLORREF Color, const RECT& rc)
|
|
// Fills a rectangle with a solid color
|
|
{
|
|
COLORREF OldColor = SetBkColor(Color);
|
|
ExtTextOut(0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
|
|
SetBkColor(OldColor);
|
|
}
|
|
|
|
// Bitmap functions
|
|
inline CBitmap* CDC::CreateCompatibleBitmap(CDC* pDC, int cx, int cy)
|
|
// Creates a compatible bitmap and selects it into the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateCompatibleBitmap(pDC, cx, cy);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
|
|
inline CBitmap* CDC::CreateBitmap(int cx, int cy, UINT Planes, UINT BitsPerPixel, LPCVOID pvColors)
|
|
// Creates a bitmap and selects it into the device context.
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateBitmap(cx, cy, Planes, BitsPerPixel, pvColors);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline CBitmap* CDC::CreateBitmapIndirect (LPBITMAP lpBitmap)
|
|
// Creates a bitmap and selects it into the device context.
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateBitmapIndirect(lpBitmap);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
|
|
inline CBitmap* CDC::CreateDIBitmap(CDC* pDC, const BITMAPINFOHEADER& bmih, DWORD fdwInit, LPCVOID lpbInit,
|
|
BITMAPINFO& bmi, UINT fuUsage)
|
|
// Creates a bitmap and selects it into the device context.
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateDIBitmap(pDC, &bmih, fdwInit, lpbInit, &bmi, fuUsage);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
#endif
|
|
|
|
inline CBitmap* CDC::CreateDIBSection(CDC* pDC, const BITMAPINFO& bmi, UINT iUsage, LPVOID *ppvBits,
|
|
HANDLE hSection, DWORD dwOffset)
|
|
// Creates a bitmap and selects it into the device context.
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateDIBSection(pDC, &bmi, iUsage, ppvBits, hSection, dwOffset);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
|
|
inline void CDC::Destroy()
|
|
// Deletes or releases the device context and returns the CDC object to its
|
|
// default state, ready for reuse.
|
|
{
|
|
if (m_pData->hDC)
|
|
{
|
|
RemoveFromMap();
|
|
if (m_pData->bRemoveHDC)
|
|
{
|
|
// Return the DC back to its initial state
|
|
::RestoreDC(m_pData->hDC, m_pData->nSavedDCState);
|
|
|
|
// We need to release a Window DC, and delete a memory DC
|
|
if (m_pData->hWnd)
|
|
::ReleaseDC(m_pData->hWnd, m_pData->hDC);
|
|
else
|
|
if (!::DeleteDC(m_pData->hDC))
|
|
::ReleaseDC(NULL, m_pData->hDC);
|
|
|
|
m_pData->hDC = 0;
|
|
m_pData->hWnd = 0;
|
|
m_pData->bRemoveHDC = TRUE;
|
|
}
|
|
}
|
|
|
|
// RemoveFromMap();
|
|
}
|
|
|
|
inline BITMAP CDC::GetBitmapData() const
|
|
// Retrieves the BITMAP information for the current HBITMAP.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
HBITMAP hbm = (HBITMAP)::GetCurrentObject(m_pData->hDC, OBJ_BITMAP);
|
|
BITMAP bm = {0};
|
|
::GetObject(hbm, sizeof(bm), &bm);
|
|
return bm;
|
|
}
|
|
|
|
inline CBitmap* CDC::LoadBitmap(UINT nID)
|
|
// Loads a bitmap from the resource and selects it into the device context
|
|
{
|
|
return LoadBitmap(MAKEINTRESOURCE(nID));
|
|
}
|
|
|
|
inline CBitmap* CDC::LoadBitmap(LPCTSTR lpszName)
|
|
// Loads a bitmap from the resource and selects it into the device context
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
BOOL bResult = pBitmap->LoadBitmap(lpszName);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
|
|
return bResult? SelectObject(pBitmap) : NULL;
|
|
}
|
|
|
|
inline CBitmap* CDC::LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad)
|
|
// Loads a bitmap from the resource and selects it into the device context
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
return LoadImage(nID, cxDesired, cyDesired, fuLoad);
|
|
}
|
|
|
|
inline CBitmap* CDC::LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad)
|
|
// Loads a bitmap from the resource and selects it into the device context
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
BOOL bResult = pBitmap->LoadImage(lpszName, cxDesired, cyDesired, fuLoad);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return bResult? SelectObject(pBitmap) : NULL;
|
|
}
|
|
|
|
inline CBitmap* CDC::LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
|
|
// Loads a predefined system bitmap and selects it into the device context
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
BOOL bResult = pBitmap->LoadOEMBitmap(nIDBitmap);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return bResult? SelectObject(pBitmap) : NULL;
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline CBitmap* CDC::CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/)
|
|
// creates and selects a new bitmap using the bitmap data and colors specified by the bitmap resource and the color mapping information.
|
|
// Returns a pointer to the old bitmap selected out of the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBitmap* pBitmap = new CBitmap;
|
|
pBitmap->CreateMappedBitmap(nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
|
|
m_pData->m_vGDIObjects.push_back(pBitmap);
|
|
return SelectObject(pBitmap);
|
|
}
|
|
#endif // !_WIN32_WCE
|
|
|
|
|
|
// Brush functions
|
|
#ifndef _WIN32_WCE
|
|
inline CBrush* CDC::CreateBrushIndirect(LPLOGBRUSH pLogBrush)
|
|
// Creates the brush and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreateBrushIndirect(pLogBrush);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
|
|
inline CBrush* CDC::CreateHatchBrush(int fnStyle, COLORREF rgb)
|
|
// Creates a brush with the specified hatch pattern and color, and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreateHatchBrush(fnStyle, rgb);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
|
|
inline CBrush* CDC::CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec)
|
|
// Creates a logical from the specified device-independent bitmap (DIB), and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreateDIBPatternBrush(hglbDIBPacked, fuColorSpec);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
|
|
inline CBrush* CDC::CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT iUsage)
|
|
// Creates a logical from the specified device-independent bitmap (DIB), and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreateDIBPatternBrushPt(lpPackedDIB, iUsage);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
#endif
|
|
|
|
inline CBrush* CDC::CreatePatternBrush(CBitmap* pBitmap)
|
|
// Creates the brush with the specified pattern, and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBitmap);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreatePatternBrush(pBitmap);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
|
|
inline CBrush* CDC::CreateSolidBrush(COLORREF rgb)
|
|
// Creates the brush with the specified color, and selects it into the device context.
|
|
// Returns a pointer to the old brush selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CBrush* pBrush = new CBrush;
|
|
pBrush->CreateSolidBrush(rgb);
|
|
m_pData->m_vGDIObjects.push_back(pBrush);
|
|
return SelectObject(pBrush);
|
|
}
|
|
|
|
inline LOGBRUSH CDC::GetLogBrush() const
|
|
// Retrieves the current brush information
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
HBRUSH hBrush = (HBRUSH)::GetCurrentObject(m_pData->hDC, OBJ_BRUSH);
|
|
LOGBRUSH lBrush = {0};
|
|
::GetObject(hBrush, sizeof(lBrush), &lBrush);
|
|
return lBrush;
|
|
}
|
|
|
|
|
|
// Font functions
|
|
#ifndef _WIN32_WCE
|
|
inline CFont* CDC::CreateFont (
|
|
int nHeight, // height of font
|
|
int nWidth, // average character width
|
|
int nEscapement, // angle of escapement
|
|
int nOrientation, // base-line orientation angle
|
|
int fnWeight, // font weight
|
|
DWORD fdwItalic, // italic attribute option
|
|
DWORD fdwUnderline, // underline attribute option
|
|
DWORD fdwStrikeOut, // strikeout attribute option
|
|
DWORD fdwCharSet, // character set identifier
|
|
DWORD fdwOutputPrecision, // output precision
|
|
DWORD fdwClipPrecision, // clipping precision
|
|
DWORD fdwQuality, // output quality
|
|
DWORD fdwPitchAndFamily, // pitch and family
|
|
LPCTSTR lpszFace // typeface name
|
|
)
|
|
|
|
// Creates a logical font with the specified characteristics.
|
|
// Returns a pointer to the old font selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CFont* pFont = new CFont;
|
|
pFont->CreateFont (nHeight, nWidth, nEscapement, nOrientation, fnWeight,
|
|
fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
|
|
fdwOutputPrecision, fdwClipPrecision, fdwQuality,
|
|
fdwPitchAndFamily, lpszFace);
|
|
m_pData->m_vGDIObjects.push_back(pFont);
|
|
return SelectObject(pFont);
|
|
}
|
|
#endif
|
|
|
|
inline CFont* CDC::CreateFontIndirect(LPLOGFONT plf)
|
|
// Creates a logical font and selects it into the device context.
|
|
// Returns a pointer to the old font selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CFont* pFont = new CFont;
|
|
pFont->CreateFontIndirect(plf);
|
|
m_pData->m_vGDIObjects.push_back(pFont);
|
|
return SelectObject(pFont);
|
|
}
|
|
|
|
inline LOGFONT CDC::GetLogFont() const
|
|
// Retrieves the current font information.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
HFONT hFont = (HFONT)::GetCurrentObject(m_pData->hDC, OBJ_FONT);
|
|
LOGFONT lFont = {0};
|
|
::GetObject(hFont, sizeof(lFont), &lFont);
|
|
return lFont;
|
|
}
|
|
|
|
// Pen functions
|
|
inline CPen* CDC::CreatePen (int nStyle, int nWidth, COLORREF rgb)
|
|
// Creates the pen and selects it into the device context.
|
|
// Returns a pointer to the old pen selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CPen* pPen = new CPen;
|
|
pPen->CreatePen(nStyle, nWidth, rgb);
|
|
m_pData->m_vGDIObjects.push_back(pPen);
|
|
return SelectObject(pPen);
|
|
}
|
|
|
|
inline CPen* CDC::CreatePenIndirect (LPLOGPEN pLogPen)
|
|
// Creates the pen and selects it into the device context.
|
|
// Returns a pointer to the old pen selected out of the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CPen* pPen = new CPen;
|
|
pPen->CreatePenIndirect(pLogPen);
|
|
m_pData->m_vGDIObjects.push_back(pPen);
|
|
return SelectObject(pPen);
|
|
}
|
|
|
|
inline LOGPEN CDC::GetLogPen() const
|
|
// Retrieves the current pen information as a LOGPEN
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
HPEN hPen = (HPEN)::GetCurrentObject(m_pData->hDC, OBJ_PEN);
|
|
LOGPEN lPen = {0};
|
|
::GetObject(hPen, sizeof(lPen), &lPen);
|
|
return lPen;
|
|
}
|
|
|
|
// Region functions
|
|
inline int CDC::CreateRectRgn(int left, int top, int right, int bottom)
|
|
// Creates a rectangular region from the rectangle co-ordinates.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreateRectRgn(left, top, right, bottom);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
inline int CDC::CreateRectRgnIndirect(const RECT& rc)
|
|
// Creates a rectangular region from the rectangle co-ordinates.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreateRectRgnIndirect(rc);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
inline int CDC::CreateFromData(const XFORM* Xform, DWORD nCount, const RGNDATA *pRgnData)
|
|
// Creates a region from the specified region data and tranformation data.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
// Notes: GetRegionData can be used to get a region's data
|
|
// If the XFROM pointer is NULL, the identity transformation is used.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreateFromData(Xform, nCount, pRgnData);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline int CDC::CreateEllipticRgn(int left, int top, int right, int bottom)
|
|
// Creates the ellyiptical region from the bounding rectangle co-ordinates
|
|
// and selects it into the device context.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreateEllipticRgn(left, top, right, bottom);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
inline int CDC::CreateEllipticRgnIndirect(const RECT& rc)
|
|
// Creates the ellyiptical region from the bounding rectangle co-ordinates
|
|
// and selects it into the device context.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreateEllipticRgnIndirect(rc);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
inline int CDC::CreatePolygonRgn(LPPOINT ppt, int cPoints, int fnPolyFillMode)
|
|
// Creates the polygon region from the array of points and selects it into
|
|
// the device context. The polygon is presumed closed.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreatePolygonRgn(ppt, cPoints, fnPolyFillMode);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
|
|
inline int CDC::CreatePolyPolygonRgn(LPPOINT ppt, LPINT pPolyCounts, int nCount, int fnPolyFillMode)
|
|
// Creates the polygon region from a series of polygons.The polygons can overlap.
|
|
// The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
CRgn* pRgn = new CRgn;
|
|
pRgn->CreatePolyPolygonRgn(ppt, pPolyCounts, nCount, fnPolyFillMode);
|
|
m_pData->m_vGDIObjects.push_back(pRgn);
|
|
return SelectClipRgn(pRgn);
|
|
}
|
|
#endif
|
|
|
|
|
|
// Wrappers for WinAPI functions
|
|
|
|
inline int CDC::GetDeviceCaps (int nIndex) const
|
|
// Retrieves device-specific information for the specified device.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetDeviceCaps(m_pData->hDC, nIndex);
|
|
}
|
|
|
|
// Brush Functions
|
|
#ifdef GetDCBrushColor
|
|
inline COLORREF CDC::GetDCBrushColor() const
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetDCBrushColor(m_pData->hDC);
|
|
}
|
|
|
|
inline COLORREF CDC::SetDCBrushColor(COLORREF crColor) const
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetDCBrushColor(m_pData->hDC, crColor);
|
|
}
|
|
#endif
|
|
|
|
// Clipping functions
|
|
inline int CDC::ExcludeClipRect(int Left, int Top, int Right, int BottomRect)
|
|
// Creates a new clipping region that consists of the existing clipping region minus the specified rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ExcludeClipRect(m_pData->hDC, Left, Top, Right, BottomRect);
|
|
}
|
|
|
|
inline int CDC::ExcludeClipRect(const RECT& rc)
|
|
// Creates a new clipping region that consists of the existing clipping region minus the specified rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ExcludeClipRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
inline int CDC::GetClipBox (RECT& rc)
|
|
// Retrieves the dimensions of the tightest bounding rectangle that can be drawn around the current visible area on the device.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetClipBox(m_pData->hDC, &rc);
|
|
}
|
|
|
|
inline int CDC::GetClipRgn(HRGN hrgn)
|
|
// Retrieves a handle identifying the current application-defined clipping region for the specified device context.
|
|
// hrgn: A handle to an existing region before the function is called.
|
|
// After the function returns, this parameter is a handle to a copy of the current clipping region.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetClipRgn(m_pData->hDC, hrgn);
|
|
}
|
|
|
|
inline int CDC::IntersectClipRect(int Left, int Top, int Right, int Bottom)
|
|
// Creates a new clipping region from the intersection of the current clipping region and the specified rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::IntersectClipRect(m_pData->hDC, Left, Top, Right, Bottom);
|
|
}
|
|
|
|
inline int CDC::IntersectClipRect(const RECT& rc)
|
|
// Creates a new clipping region from the intersection of the current clipping region and the specified rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::IntersectClipRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
inline BOOL CDC::RectVisible(const RECT& rc)
|
|
// Determines whether any part of the specified rectangle lies within the clipping region of a device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::RectVisible (m_pData->hDC, &rc);
|
|
}
|
|
|
|
inline int CDC::SelectClipRgn(CRgn* pRgn)
|
|
// Selects a region as the current clipping region for the specified device context.
|
|
// Note: Only a copy of the selected region is used.
|
|
// To remove a device-context's clipping region, specify a NULL region handle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SelectClipRgn(m_pData->hDC, pRgn? (HRGN)pRgn->GetHandle() : 0);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline int CDC::ExtSelectClipRgn(CRgn* pRgn, int fnMode)
|
|
// Combines the specified region with the current clipping region using the specified mode.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pRgn);
|
|
return ::ExtSelectClipRgn(m_pData->hDC, *pRgn, fnMode);
|
|
}
|
|
#endif
|
|
|
|
inline CBitmap* CDC::SelectObject(const CBitmap* pBitmap)
|
|
// Use this to attach an existing bitmap.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBitmap);
|
|
|
|
return FromHandle( (HBITMAP)::SelectObject(m_pData->hDC, *pBitmap) );
|
|
}
|
|
|
|
inline CBrush* CDC::SelectObject(const CBrush* pBrush)
|
|
// Use this to attach an existing brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBrush);
|
|
|
|
return FromHandle( (HBRUSH)::SelectObject(m_pData->hDC, *pBrush) );
|
|
}
|
|
|
|
inline CFont* CDC::SelectObject(const CFont* pFont)
|
|
// Use this to attach an existing font.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pFont);
|
|
|
|
return FromHandle( (HFONT)::SelectObject(m_pData->hDC, *pFont) );
|
|
}
|
|
|
|
inline CPalette* CDC::SelectObject(const CPalette* pPalette)
|
|
// Use this to attach an existing Palette.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pPalette);
|
|
|
|
return FromHandle( (HPALETTE)::SelectObject(m_pData->hDC, *pPalette) );
|
|
}
|
|
|
|
inline CPen* CDC::SelectObject(const CPen* pPen)
|
|
// Use this to attach an existing pen.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pPen);
|
|
|
|
return FromHandle( (HPEN)::SelectObject(m_pData->hDC, *pPen) );
|
|
}
|
|
|
|
inline CPalette* CDC::SelectPalette(const CPalette* pPalette, BOOL bForceBkgnd)
|
|
// Use this to attach an existing palette.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pPalette);
|
|
|
|
return FromHandle( (HPALETTE)::SelectPalette(m_pData->hDC, *pPalette, bForceBkgnd) );
|
|
}
|
|
#ifndef _WIN32_WCE
|
|
inline BOOL CDC::PtVisible(int X, int Y)
|
|
// Determines whether the specified point is within the clipping region of a device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PtVisible (m_pData->hDC, X, Y);
|
|
}
|
|
|
|
inline int CDC::OffsetClipRgn(int nXOffset, int nYOffset)
|
|
// Moves the clipping region of a device context by the specified offsets.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::OffsetClipRgn (m_pData->hDC, nXOffset, nYOffset);
|
|
}
|
|
#endif
|
|
|
|
// Point and Line Drawing Functions
|
|
inline CPoint CDC::GetCurrentPosition() const
|
|
// Returns the current "MoveToEx" position.
|
|
{
|
|
assert(m_pData->hDC);
|
|
CPoint pt;
|
|
::MoveToEx(m_pData->hDC, 0, 0, &pt);
|
|
::MoveToEx(m_pData->hDC, pt.x, pt.y, NULL);
|
|
return pt;
|
|
}
|
|
|
|
inline CPoint CDC::MoveTo(int x, int y) const
|
|
// Updates the current position to the specified point.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::MoveToEx(m_pData->hDC, x, y, NULL);
|
|
}
|
|
|
|
inline CPoint CDC::MoveTo(POINT pt) const
|
|
// Updates the current position to the specified point
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::MoveToEx(m_pData->hDC, pt.x, pt.y, NULL);
|
|
}
|
|
|
|
inline BOOL CDC::LineTo(int x, int y) const
|
|
// Draws a line from the current position up to, but not including, the specified point.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::LineTo(m_pData->hDC, x, y);
|
|
}
|
|
|
|
inline BOOL CDC::LineTo(POINT pt) const
|
|
// Draws a line from the current position up to, but not including, the specified point.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::LineTo(m_pData->hDC, pt.x, pt.y);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline BOOL CDC::Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
|
|
// Draws an elliptical arc.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Arc(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
inline BOOL CDC::Arc(RECT& rc, POINT ptStart, POINT ptEnd) const
|
|
// Draws an elliptical arc.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Arc(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
|
|
ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
|
|
}
|
|
|
|
inline BOOL CDC::ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
|
|
// Draws an elliptical arc.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ArcTo(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
inline BOOL CDC::ArcTo(RECT& rc, POINT ptStart, POINT ptEnd) const
|
|
// Draws an elliptical arc.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ArcTo (m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
|
|
ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
|
|
}
|
|
|
|
inline BOOL CDC::AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) const
|
|
// Draws a line segment and an arc.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::AngleArc(m_pData->hDC, x, y, nRadius, fStartAngle, fSweepAngle);
|
|
}
|
|
|
|
inline int CDC::GetArcDirection() const
|
|
// Retrieves the current arc direction ( AD_COUNTERCLOCKWISE or AD_CLOCKWISE ).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetArcDirection(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::SetArcDirection(int nArcDirection) const
|
|
// Sets the current arc direction ( AD_COUNTERCLOCKWISE or AD_CLOCKWISE ).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetArcDirection(m_pData->hDC, nArcDirection);
|
|
}
|
|
|
|
inline BOOL CDC::PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) const
|
|
// Draws a set of line segments and Bzier curves.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolyDraw(m_pData->hDC, lpPoints, lpTypes, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::Polyline(LPPOINT lpPoints, int nCount) const
|
|
// Draws a series of line segments by connecting the points in the specified array.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Polyline(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::PolyPolyline(const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount) const
|
|
// Draws multiple series of connected line segments.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolyPolyline(m_pData->hDC, lpPoints, lpPolyPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::PolylineTo(const POINT* lpPoints, int nCount) const
|
|
// Draws one or more straight lines.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolylineTo(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
inline BOOL CDC::PolyBezier(const POINT* lpPoints, int nCount) const
|
|
// Draws one or more Bzier curves.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolyBezier(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::PolyBezierTo(const POINT* lpPoints, int nCount) const
|
|
// Draws one or more Bzier curves.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolyBezierTo(m_pData->hDC, lpPoints, nCount );
|
|
}
|
|
|
|
inline COLORREF CDC::GetPixel(int x, int y) const
|
|
// Retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetPixel(m_pData->hDC, x, y);
|
|
}
|
|
|
|
inline COLORREF CDC::GetPixel(POINT pt) const
|
|
// Retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetPixel(m_pData->hDC, pt.x, pt.y);
|
|
}
|
|
|
|
inline COLORREF CDC::SetPixel (int x, int y, COLORREF crColor) const
|
|
// Sets the pixel at the specified coordinates to the specified color.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetPixel(m_pData->hDC, x, y, crColor);
|
|
}
|
|
|
|
inline COLORREF CDC::SetPixel(POINT pt, COLORREF crColor) const
|
|
// Sets the pixel at the specified coordinates to the specified color.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetPixel(m_pData->hDC, pt.x, pt.y, crColor);
|
|
}
|
|
|
|
inline BOOL CDC::SetPixelV(int x, int y, COLORREF crColor) const
|
|
// Sets the pixel at the specified coordinates to the closest approximation of the specified color.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetPixelV(m_pData->hDC, x, y, crColor);
|
|
}
|
|
|
|
inline BOOL CDC::SetPixelV(POINT pt, COLORREF crColor) const
|
|
// Sets the pixel at the specified coordinates to the closest approximation of the specified color.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetPixelV(m_pData->hDC, pt.x, pt.y, crColor);
|
|
}
|
|
#endif
|
|
|
|
// Shape Drawing Functions
|
|
inline void CDC::DrawFocusRect(const RECT& rc) const
|
|
// Draws a rectangle in the style used to indicate that the rectangle has the focus.
|
|
{
|
|
assert(m_pData->hDC);
|
|
::DrawFocusRect(m_pData->hDC, &rc);
|
|
}
|
|
|
|
inline BOOL CDC::Ellipse(int x1, int y1, int x2, int y2) const
|
|
// Draws an ellipse. The center of the ellipse is the center of the specified bounding rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Ellipse(m_pData->hDC, x1, y1, x2, y2);
|
|
}
|
|
|
|
inline BOOL CDC::Ellipse(const RECT& rc) const
|
|
// Draws an ellipse. The center of the ellipse is the center of the specified bounding rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Ellipse(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
inline BOOL CDC::Polygon(LPPOINT lpPoints, int nCount) const
|
|
// Draws a polygon consisting of two or more vertices connected by straight lines.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Polygon(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::Rectangle(int x1, int y1, int x2, int y2) const
|
|
// Draws a rectangle. The rectangle is outlined by using the current pen and filled by using the current brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Rectangle(m_pData->hDC, x1, y1, x2, y2);
|
|
}
|
|
|
|
inline BOOL CDC::Rectangle(const RECT& rc) const
|
|
// Draws a rectangle. The rectangle is outlined by using the current pen and filled by using the current brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Rectangle(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
|
|
}
|
|
|
|
inline BOOL CDC::RoundRect(int x1, int y1, int x2, int y2, int nWidth, int nHeight) const
|
|
// Draws a rectangle with rounded corners.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::RoundRect(m_pData->hDC, x1, y1, x2, y2, nWidth, nHeight);
|
|
}
|
|
inline BOOL CDC::RoundRect(const RECT& rc, int nWidth, int nHeight) const
|
|
// Draws a rectangle with rounded corners.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::RoundRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom, nWidth, nHeight );
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline BOOL CDC::Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
|
|
// Draws a chord (a region bounded by the intersection of an ellipse and a line segment, called a secant).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Chord(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
inline BOOL CDC::Chord(const RECT& rc, POINT ptStart, POINT ptEnd) const
|
|
// Draws a chord (a region bounded by the intersection of an ellipse and a line segment, called a secant).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Chord(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
|
|
ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
|
|
}
|
|
|
|
inline BOOL CDC::Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
|
|
// Draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Pie(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
inline BOOL CDC::Pie(const RECT& rc, POINT ptStart, POINT ptEnd) const
|
|
// Draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::Pie(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
|
|
ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
|
|
}
|
|
|
|
inline BOOL CDC::PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) const
|
|
// Draws a series of closed polygons.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PolyPolygon(m_pData->hDC, lpPoints, lpPolyCounts, nCount);
|
|
}
|
|
#endif
|
|
|
|
// Fill and 3D Drawing functions
|
|
inline BOOL CDC::FillRect(const RECT& rc, CBrush* pBrush) const
|
|
// Fills a rectangle by using the specified brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBrush);
|
|
return (BOOL)::FillRect(m_pData->hDC, &rc, *pBrush);
|
|
}
|
|
|
|
inline BOOL CDC::InvertRect(const RECT& rc) const
|
|
// Inverts a rectangle in a window by performing a logical NOT operation on the color values for each pixel in the rectangle's interior.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::InvertRect( m_pData->hDC, &rc);
|
|
}
|
|
|
|
inline BOOL CDC::DrawIconEx(int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, CBrush* pFlickerFreeDraw, UINT diFlags) const
|
|
// draws an icon or cursor, performing the specified raster operations, and stretching or compressing the icon or cursor as specified.
|
|
{
|
|
assert(m_pData->hDC);
|
|
HBRUSH hFlickerFreeDraw = pFlickerFreeDraw? (HBRUSH)pFlickerFreeDraw->GetHandle() : NULL;
|
|
return ::DrawIconEx(m_pData->hDC, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hFlickerFreeDraw, diFlags);
|
|
}
|
|
|
|
inline BOOL CDC::DrawEdge(const RECT& rc, UINT nEdge, UINT nFlags) const
|
|
// Draws one or more edges of rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawEdge(m_pData->hDC, (LPRECT)&rc, nEdge, nFlags);
|
|
}
|
|
|
|
inline BOOL CDC::DrawFrameControl(const RECT& rc, UINT nType, UINT nState) const
|
|
// Draws a frame control of the specified type and style.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawFrameControl(m_pData->hDC, (LPRECT)&rc, nType, nState);
|
|
}
|
|
|
|
inline BOOL CDC::FillRgn(CRgn* pRgn, CBrush* pBrush) const
|
|
// Fills a region by using the specified brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pRgn);
|
|
assert(pBrush);
|
|
return ::FillRgn(m_pData->hDC, *pRgn, *pBrush);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline BOOL CDC::DrawIcon(int x, int y, HICON hIcon) const
|
|
// Draws an icon or cursor.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawIcon(m_pData->hDC, x, y, hIcon);
|
|
}
|
|
|
|
inline BOOL CDC::DrawIcon(POINT pt, HICON hIcon) const
|
|
// Draws an icon or cursor.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawIcon(m_pData->hDC, pt.x, pt.y, hIcon);
|
|
}
|
|
|
|
inline BOOL CDC::FrameRect(const RECT& rc, CBrush* pBrush) const
|
|
// Draws a border around the specified rectangle by using the specified brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBrush);
|
|
return (BOOL)::FrameRect(m_pData->hDC, &rc, *pBrush);
|
|
}
|
|
|
|
inline BOOL CDC::PaintRgn(CRgn* pRgn) const
|
|
// Paints the specified region by using the brush currently selected into the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pRgn);
|
|
return ::PaintRgn(m_pData->hDC, *pRgn);
|
|
}
|
|
#endif
|
|
|
|
// Bitmap Functions
|
|
inline int CDC::StretchDIBits(int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
|
|
int nSrcHeight, CONST VOID *lpBits, BITMAPINFO& bi, UINT iUsage, DWORD dwRop) const
|
|
// Copies the color data for a rectangle of pixels in a DIB to the specified destination rectangle.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::StretchDIBits(m_pData->hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, &bi, iUsage, dwRop);
|
|
}
|
|
|
|
inline BOOL CDC::PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) const
|
|
// Paints the specified rectangle using the brush that is currently selected into the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::PatBlt(m_pData->hDC, x, y, nWidth, nHeight, dwRop);
|
|
}
|
|
|
|
inline BOOL CDC::BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) const
|
|
// Performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pSrcDC);
|
|
return ::BitBlt(m_pData->hDC, x, y, nWidth, nHeight, pSrcDC->GetHDC(), xSrc, ySrc, dwRop);
|
|
}
|
|
|
|
inline BOOL CDC::StretchBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) const
|
|
// Copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pSrcDC);
|
|
return ::StretchBlt(m_pData->hDC, x, y, nWidth, nHeight, pSrcDC->GetHDC(), xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline int CDC::GetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbi, UINT uUsage) const
|
|
// Retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBitmap);
|
|
return ::GetDIBits(m_pData->hDC, *pBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage);
|
|
}
|
|
|
|
inline int CDC::SetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, LPBITMAPINFO lpbi, UINT fuColorUse) const
|
|
// Sets the pixels in a compatible bitmap (DDB) using the color data found in the specified DIB.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetDIBits(m_pData->hDC, *pBitmap, uStartScan, cScanLines, lpvBits, lpbi, fuColorUse);
|
|
}
|
|
|
|
inline int CDC::GetStretchBltMode() const
|
|
// Retrieves the current stretching mode.
|
|
// Possible modes: BLACKONWHITE, COLORONCOLOR, HALFTONE, STRETCH_ANDSCANS, STRETCH_DELETESCANS, STRETCH_HALFTONE, STRETCH_ORSCANS, WHITEONBLACK
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetStretchBltMode(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::SetStretchBltMode(int iStretchMode) const
|
|
// Sets the stretching mode.
|
|
// Possible modes: BLACKONWHITE, COLORONCOLOR, HALFTONE, STRETCH_ANDSCANS, STRETCH_DELETESCANS, STRETCH_HALFTONE, STRETCH_ORSCANS, WHITEONBLACK
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetStretchBltMode(m_pData->hDC, iStretchMode);
|
|
}
|
|
|
|
inline BOOL CDC::FloodFill(int x, int y, COLORREF crColor) const
|
|
// Fills an area of the display surface with the current brush.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::FloodFill(m_pData->hDC, x, y, crColor);
|
|
}
|
|
|
|
inline BOOL CDC::ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) const
|
|
// Fills an area of the display surface with the current brush.
|
|
// Fill type: FLOODFILLBORDER or FLOODFILLSURFACE
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ExtFloodFill(m_pData->hDC, x, y, crColor, nFillType );
|
|
}
|
|
|
|
// co-ordinate functions
|
|
inline BOOL CDC::DPtoLP(LPPOINT lpPoints, int nCount) const
|
|
// Converts device coordinates into logical coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DPtoLP(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::DPtoLP(RECT& rc) const
|
|
// Converts device coordinates into logical coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DPtoLP(m_pData->hDC, (LPPOINT)&rc, 2);
|
|
}
|
|
|
|
inline BOOL CDC::LPtoDP(LPPOINT lpPoints, int nCount) const
|
|
// Converts logical coordinates into device coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::LPtoDP(m_pData->hDC, lpPoints, nCount);
|
|
}
|
|
|
|
inline BOOL CDC::LPtoDP(RECT& rc) const
|
|
// Converts logical coordinates into device coordinates.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::LPtoDP(m_pData->hDC, (LPPOINT)&rc, 2);
|
|
}
|
|
|
|
#endif
|
|
|
|
// Layout Functions
|
|
inline DWORD CDC::GetLayout() const
|
|
// Returns the layout of a device context (LAYOUT_RTL and LAYOUT_BITMAPORIENTATIONPRESERVED).
|
|
{
|
|
#if defined(WINVER) && defined(GetLayout) && (WINVER >= 0x0500)
|
|
return ::GetLayout(m_pData->hDC);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
inline DWORD CDC::SetLayout(DWORD dwLayout) const
|
|
// changes the layout of a device context (DC).
|
|
// dwLayout values: LAYOUT_RTL or LAYOUT_BITMAPORIENTATIONPRESERVED
|
|
{
|
|
#if defined(WINVER) && defined (SetLayout) && (WINVER >= 0x0500)
|
|
// Sets the layout of a device context
|
|
return ::SetLayout(m_pData->hDC, dwLayout);
|
|
#else
|
|
UNREFERENCED_PARAMETER(dwLayout); // no-op
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
// Mapping Functions
|
|
#ifndef _WIN32_WCE
|
|
inline int CDC::GetMapMode() const
|
|
// Rretrieves the current mapping mode.
|
|
// Possible modes: MM_ANISOTROPIC, MM_HIENGLISH, MM_HIMETRIC, MM_ISOTROPIC, MM_LOENGLISH, MM_LOMETRIC, MM_TEXT, and MM_TWIPS.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetMapMode(m_pData->hDC);
|
|
}
|
|
|
|
inline BOOL CDC::GetViewportOrgEx(LPPOINT lpPoint) const
|
|
// Retrieves the x-coordinates and y-coordinates of the viewport origin for the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetViewportOrgEx(m_pData->hDC, lpPoint);
|
|
}
|
|
|
|
inline int CDC::SetMapMode(int nMapMode) const
|
|
// Sets the mapping mode of the specified device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetMapMode(m_pData->hDC, nMapMode);
|
|
}
|
|
|
|
inline BOOL CDC::SetViewportOrgEx(int x, int y, LPPOINT lpPoint /* = NULL */) const
|
|
// Specifies which device point maps to the window origin (0,0).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetViewportOrgEx(m_pData->hDC, x, y, lpPoint);
|
|
}
|
|
|
|
inline BOOL CDC::SetViewportOrgEx(POINT point, LPPOINT lpPointRet /* = NULL */) const
|
|
// Specifies which device point maps to the window origin (0,0).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return SetViewportOrgEx(point.x, point.y, lpPointRet);
|
|
}
|
|
|
|
inline BOOL CDC::OffsetViewportOrgEx(int nWidth, int nHeight, LPPOINT lpPoint /* = NULL */) const
|
|
// Modifies the viewport origin for the device context using the specified horizontal and vertical offsets.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::OffsetViewportOrgEx(m_pData->hDC, nWidth, nHeight, lpPoint);
|
|
}
|
|
|
|
inline BOOL CDC::GetViewportExtEx(LPSIZE lpSize) const
|
|
// Retrieves the x-extent and y-extent of the current viewport for the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetViewportExtEx(m_pData->hDC, lpSize);
|
|
}
|
|
|
|
inline BOOL CDC::SetViewportExtEx(int x, int y, LPSIZE lpSize ) const
|
|
// Sets the horizontal and vertical extents of the viewport for the device context by using the specified values.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetViewportExtEx(m_pData->hDC, x, y, lpSize);
|
|
}
|
|
|
|
inline BOOL CDC::SetViewportExtEx(SIZE size, LPSIZE lpSizeRet ) const
|
|
// Sets the horizontal and vertical extents of the viewport for the device context by using the specified values.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return SetViewportExtEx(size.cx, size.cy, lpSizeRet);
|
|
}
|
|
|
|
inline BOOL CDC::ScaleViewportExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize ) const
|
|
// Modifies the viewport for the device context using the ratios formed by the specified multiplicands and divisors.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ScaleViewportExtEx(m_pData->hDC, xNum, xDenom, yNum, yDenom, lpSize);
|
|
}
|
|
|
|
inline BOOL CDC::GetWindowOrgEx(LPPOINT lpPoint) const
|
|
// Retrieves the x-coordinates and y-coordinates of the window origin for the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetWindowOrgEx(m_pData->hDC, lpPoint);
|
|
}
|
|
|
|
inline BOOL CDC::SetWindowOrgEx(int x, int y, LPPOINT lpPoint ) const
|
|
// Specifies which window point maps to the viewport origin (0,0).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetWindowOrgEx(m_pData->hDC, x, y, lpPoint);
|
|
}
|
|
|
|
inline BOOL CDC::SetWindowOrgEx(POINT point, LPPOINT lpPointRet ) const
|
|
// Specifies which window point maps to the viewport origin (0,0).
|
|
{
|
|
assert(m_pData->hDC);
|
|
return SetWindowOrgEx(point.x, point.y, lpPointRet);
|
|
}
|
|
|
|
inline BOOL CDC::OffsetWindowOrgEx(int nWidth, int nHeight, LPPOINT lpPoint ) const
|
|
// Modifies the window origin for the device context using the specified horizontal and vertical offsets.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::OffsetWindowOrgEx(m_pData->hDC, nWidth, nHeight, lpPoint);
|
|
}
|
|
|
|
inline BOOL CDC::GetWindowExtEx(LPSIZE lpSize) const
|
|
// Retrieves the x-extent and y-extent of the window for the device context.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetWindowExtEx(m_pData->hDC, lpSize);
|
|
}
|
|
|
|
inline BOOL CDC::SetWindowExtEx(int x, int y, LPSIZE lpSize ) const
|
|
// Sets the horizontal and vertical extents of the window for the device context by using the specified values.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetWindowExtEx(m_pData->hDC, x, y, lpSize);
|
|
}
|
|
|
|
inline BOOL CDC::SetWindowExtEx(SIZE size, LPSIZE lpSizeRet) const
|
|
// Sets the horizontal and vertical extents of the window for the device context by using the specified values.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return SetWindowExtEx(size.cx, size.cy, lpSizeRet);
|
|
}
|
|
|
|
inline BOOL CDC::ScaleWindowExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const
|
|
// Modifies the window for the device context using the ratios formed by the specified multiplicands and divisors.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::ScaleWindowExtEx(m_pData->hDC, xNum, xDenom, yNum, yDenom, lpSize);
|
|
}
|
|
#endif
|
|
|
|
// Printer Functions
|
|
inline int CDC::StartDoc(LPDOCINFO lpDocInfo) const
|
|
// Starts a print job.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::StartDoc(m_pData->hDC, lpDocInfo);
|
|
}
|
|
|
|
inline int CDC::EndDoc() const
|
|
// Ends a print job.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::EndDoc(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::StartPage() const
|
|
// Prepares the printer driver to accept data.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::StartPage(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::EndPage() const
|
|
// Notifies the device that the application has finished writing to a page.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::EndPage(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::AbortDoc() const
|
|
// Stops the current print job and erases everything drawn since the last call to the StartDoc function.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::AbortDoc(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) const
|
|
// Sets the application-defined abort function that allows a print job to be canceled during spooling.
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetAbortProc(m_pData->hDC, lpfn);
|
|
}
|
|
|
|
// Text Functions
|
|
inline BOOL CDC::ExtTextOut(int x, int y, UINT nOptions, LPCRECT lprc, LPCTSTR lpszString, int nCount /*= -1*/, LPINT lpDxWidths /*=NULL*/) const
|
|
// Draws text using the currently selected font, background color, and text color
|
|
{
|
|
assert(m_pData->hDC);
|
|
|
|
if (nCount == -1)
|
|
nCount = lstrlen (lpszString);
|
|
|
|
return ::ExtTextOut(m_pData->hDC, x, y, nOptions, lprc, lpszString, nCount, lpDxWidths );
|
|
}
|
|
|
|
inline int CDC::DrawText(LPCTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat) const
|
|
// Draws formatted text in the specified rectangle
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawText(m_pData->hDC, lpszString, nCount, lprc, nFormat );
|
|
}
|
|
|
|
inline UINT CDC::GetTextAlign() const
|
|
// Retrieves the text-alignment setting
|
|
// Values: TA_BASELINE, TA_BOTTOM, TA_TOP, TA_CENTER, TA_LEFT, TA_RIGHT, TA_RTLREADING, TA_NOUPDATECP, TA_UPDATECP
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetTextAlign(m_pData->hDC);
|
|
}
|
|
|
|
inline UINT CDC::SetTextAlign(UINT nFlags) const
|
|
// Sets the text-alignment setting
|
|
// Values: TA_BASELINE, TA_BOTTOM, TA_TOP, TA_CENTER, TA_LEFT, TA_RIGHT, TA_RTLREADING, TA_NOUPDATECP, TA_UPDATECP
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetTextAlign(m_pData->hDC, nFlags);
|
|
}
|
|
|
|
inline int CDC::GetTextFace(int nCount, LPTSTR lpszFacename) const
|
|
// Retrieves the typeface name of the font that is selected into the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetTextFace(m_pData->hDC, nCount, lpszFacename);
|
|
}
|
|
|
|
inline BOOL CDC::GetTextMetrics(TEXTMETRIC& Metrics) const
|
|
// Fills the specified buffer with the metrics for the currently selected font
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetTextMetrics(m_pData->hDC, &Metrics);
|
|
}
|
|
|
|
inline COLORREF CDC::GetBkColor() const
|
|
// Returns the current background color
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetBkColor(m_pData->hDC);
|
|
}
|
|
|
|
inline COLORREF CDC::SetBkColor(COLORREF crColor) const
|
|
// Sets the current background color to the specified color value
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetBkColor(m_pData->hDC, crColor);
|
|
}
|
|
|
|
inline COLORREF CDC::GetTextColor() const
|
|
// Retrieves the current text color
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetTextColor(m_pData->hDC);
|
|
}
|
|
|
|
inline COLORREF CDC::SetTextColor(COLORREF crColor) const
|
|
// Sets the current text color
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetTextColor(m_pData->hDC, crColor);
|
|
}
|
|
|
|
inline int CDC::GetBkMode() const
|
|
// returns the current background mix mode (OPAQUE or TRANSPARENT)
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetBkMode(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::SetBkMode(int iBkMode) const
|
|
// Sets the current background mix mode (OPAQUE or TRANSPARENT)
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetBkMode(m_pData->hDC, iBkMode);
|
|
}
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline int CDC::DrawTextEx(LPTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat, LPDRAWTEXTPARAMS lpDTParams) const
|
|
// Draws formatted text in the specified rectangle with more formatting options
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::DrawTextEx(m_pData->hDC, lpszString, nCount, lprc, nFormat, lpDTParams);
|
|
}
|
|
|
|
inline CSize CDC::GetTextExtentPoint32(LPCTSTR lpszString, int nCount) const
|
|
// Computes the width and height of the specified string of text
|
|
{
|
|
assert(m_pData->hDC);
|
|
CSize sz;
|
|
::GetTextExtentPoint32(m_pData->hDC, lpszString, nCount, &sz);
|
|
return sz;
|
|
}
|
|
|
|
inline CSize CDC::GetTabbedTextExtent(LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions) const
|
|
// Computes the width and height of a character string
|
|
{
|
|
assert(m_pData->hDC);
|
|
DWORD dwSize = ::GetTabbedTextExtent(m_pData->hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions );
|
|
CSize sz(dwSize);
|
|
return sz;
|
|
}
|
|
|
|
inline BOOL CDC::GrayString(CBrush* pBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) const
|
|
// Draws gray text at the specified location
|
|
{
|
|
assert(m_pData->hDC);
|
|
assert(pBrush);
|
|
return ::GrayString(m_pData->hDC, *pBrush, lpOutputFunc, lpData, nCount, x, y, nWidth, nHeight);
|
|
}
|
|
|
|
inline int CDC::SetTextJustification(int nBreakExtra, int nBreakCount) const
|
|
// Specifies the amount of space the system should add to the break characters in a string of text
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetTextJustification(m_pData->hDC, nBreakExtra, nBreakCount);
|
|
}
|
|
|
|
inline int CDC::GetTextCharacterExtra() const
|
|
// Retrieves the current intercharacter spacing for the device context
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::GetTextCharacterExtra(m_pData->hDC);
|
|
}
|
|
|
|
inline int CDC::SetTextCharacterExtra(int nCharExtra) const
|
|
// Sets the intercharacter spacing
|
|
{
|
|
assert(m_pData->hDC);
|
|
return ::SetTextCharacterExtra(m_pData->hDC, nCharExtra);
|
|
}
|
|
|
|
inline CSize CDC::TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin) const
|
|
// Writes a character string at a specified location, expanding tabs to the values specified in an array of tab-stop positions
|
|
{
|
|
assert(m_pData->hDC);
|
|
DWORD dwSize = ::TabbedTextOut(m_pData->hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin );
|
|
CSize sz(dwSize);
|
|
return sz;
|
|
}
|
|
|
|
inline BOOL CDC::TextOut(int x, int y, LPCTSTR lpszString, int nCount/* = -1*/) const
|
|
// Writes a character string at the specified location
|
|
{
|
|
assert(m_pData->hDC);
|
|
if (nCount == -1)
|
|
nCount = lstrlen (lpszString);
|
|
|
|
return ::TextOut(m_pData->hDC, x, y, lpszString, nCount);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Definitions for some global functions in the Win32xx namespace
|
|
//
|
|
|
|
#ifndef _WIN32_WCE
|
|
inline void TintBitmap (CBitmap* pbmSource, int cRed, int cGreen, int cBlue)
|
|
// Modifies the colour of the supplied Device Dependant Bitmap, by the colour
|
|
// correction values specified. The correction values can range from -255 to +255.
|
|
// This function gains its speed by accessing the bitmap colour information
|
|
// directly, rather than using GetPixel/SetPixel.
|
|
{
|
|
// Create our LPBITMAPINFO object
|
|
CBitmapInfoPtr pbmi(pbmSource);
|
|
pbmi->bmiHeader.biBitCount = 24;
|
|
|
|
// Create the reference DC for GetDIBits to use
|
|
CMemDC MemDC(NULL);
|
|
|
|
// Use GetDIBits to create a DIB from our DDB, and extract the colour data
|
|
MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
|
|
std::vector<byte> vBits(pbmi->bmiHeader.biSizeImage, 0);
|
|
byte* pByteArray = &vBits[0];
|
|
|
|
MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
|
|
UINT nWidthBytes = pbmi->bmiHeader.biSizeImage/pbmi->bmiHeader.biHeight;
|
|
|
|
// Ensure sane colour correction values
|
|
cBlue = MIN(cBlue, 255);
|
|
cBlue = MAX(cBlue, -255);
|
|
cRed = MIN(cRed, 255);
|
|
cRed = MAX(cRed, -255);
|
|
cGreen = MIN(cGreen, 255);
|
|
cGreen = MAX(cGreen, -255);
|
|
|
|
// Pre-calculate the RGB modification values
|
|
int b1 = 256 - cBlue;
|
|
int g1 = 256 - cGreen;
|
|
int r1 = 256 - cRed;
|
|
|
|
int b2 = 256 + cBlue;
|
|
int g2 = 256 + cGreen;
|
|
int r2 = 256 + cRed;
|
|
|
|
// Modify the colour
|
|
int yOffset = 0;
|
|
int xOffset;
|
|
int Index;
|
|
for (int Row=0; Row < pbmi->bmiHeader.biHeight; Row++)
|
|
{
|
|
xOffset = 0;
|
|
|
|
for (int Column=0; Column < pbmi->bmiHeader.biWidth; Column++)
|
|
{
|
|
// Calculate Index
|
|
Index = yOffset + xOffset;
|
|
|
|
// Adjust the colour values
|
|
if (cBlue > 0)
|
|
pByteArray[Index] = (BYTE)(cBlue + (((pByteArray[Index] *b1)) >>8));
|
|
else if (cBlue < 0)
|
|
pByteArray[Index] = (BYTE)((pByteArray[Index] *b2) >>8);
|
|
|
|
if (cGreen > 0)
|
|
pByteArray[Index+1] = (BYTE)(cGreen + (((pByteArray[Index+1] *g1)) >>8));
|
|
else if (cGreen < 0)
|
|
pByteArray[Index+1] = (BYTE)((pByteArray[Index+1] *g2) >>8);
|
|
|
|
if (cRed > 0)
|
|
pByteArray[Index+2] = (BYTE)(cRed + (((pByteArray[Index+2] *r1)) >>8));
|
|
else if (cRed < 0)
|
|
pByteArray[Index+2] = (BYTE)((pByteArray[Index+2] *r2) >>8);
|
|
|
|
// Increment the horizontal offset
|
|
xOffset += pbmi->bmiHeader.biBitCount >> 3;
|
|
}
|
|
|
|
// Increment vertical offset
|
|
yOffset += nWidthBytes;
|
|
}
|
|
|
|
// Save the modified colour back into our source DDB
|
|
MemDC.SetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
|
|
}
|
|
|
|
inline void GrayScaleBitmap(CBitmap* pbmSource)
|
|
{
|
|
// Create our LPBITMAPINFO object
|
|
CBitmapInfoPtr pbmi(pbmSource);
|
|
|
|
// Create the reference DC for GetDIBits to use
|
|
CMemDC MemDC(NULL);
|
|
|
|
// Use GetDIBits to create a DIB from our DDB, and extract the colour data
|
|
MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
|
|
std::vector<byte> vBits(pbmi->bmiHeader.biSizeImage, 0);
|
|
byte* pByteArray = &vBits[0];
|
|
|
|
MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
|
|
UINT nWidthBytes = pbmi->bmiHeader.biSizeImage/pbmi->bmiHeader.biHeight;
|
|
|
|
int yOffset = 0;
|
|
int xOffset;
|
|
int Index;
|
|
|
|
for (int Row=0; Row < pbmi->bmiHeader.biHeight; Row++)
|
|
{
|
|
xOffset = 0;
|
|
|
|
for (int Column=0; Column < pbmi->bmiHeader.biWidth; Column++)
|
|
{
|
|
// Calculate Index
|
|
Index = yOffset + xOffset;
|
|
|
|
BYTE byGray = (BYTE) ((pByteArray[Index] + pByteArray[Index+1]*6 + pByteArray[Index+2] *3)/10);
|
|
pByteArray[Index] = byGray;
|
|
pByteArray[Index+1] = byGray;
|
|
pByteArray[Index+2] = byGray;
|
|
|
|
// Increment the horizontal offset
|
|
xOffset += pbmi->bmiHeader.biBitCount >> 3;
|
|
}
|
|
|
|
// Increment vertical offset
|
|
yOffset += nWidthBytes;
|
|
}
|
|
|
|
// Save the modified colour back into our source DDB
|
|
MemDC.SetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
|
|
}
|
|
|
|
inline HIMAGELIST CreateDisabledImageList(HIMAGELIST himlNormal)
|
|
// Returns a greyed image list, created from hImageList
|
|
{
|
|
int cx, cy;
|
|
int nCount = ImageList_GetImageCount(himlNormal);
|
|
if (0 == nCount)
|
|
return NULL;
|
|
|
|
ImageList_GetIconSize(himlNormal, &cx, &cy);
|
|
|
|
// Create the disabled ImageList
|
|
HIMAGELIST himlDisabled = ImageList_Create(cx, cy, ILC_COLOR24 | ILC_MASK, nCount, 0);
|
|
|
|
// Process each image in the ImageList
|
|
for (int i = 0 ; i < nCount; ++i)
|
|
{
|
|
CClientDC DesktopDC(NULL);
|
|
CMemDC MemDC(NULL);
|
|
CBitmap* pOldBitmap = MemDC.CreateCompatibleBitmap(&DesktopDC, cx, cx);
|
|
CRect rc;
|
|
rc.SetRect(0, 0, cx, cx);
|
|
|
|
// Set the mask color to grey for the new ImageList
|
|
COLORREF crMask = RGB(200, 199, 200);
|
|
if ( GetDeviceCaps(DesktopDC, BITSPIXEL) < 24)
|
|
{
|
|
HPALETTE hPal = (HPALETTE)GetCurrentObject(DesktopDC, OBJ_PAL);
|
|
UINT Index = GetNearestPaletteIndex(hPal, crMask);
|
|
if (Index != CLR_INVALID) crMask = PALETTEINDEX(Index);
|
|
}
|
|
|
|
MemDC.SolidFill(crMask, rc);
|
|
|
|
// Draw the image on the memory DC
|
|
ImageList_SetBkColor(himlNormal, crMask);
|
|
ImageList_Draw(himlNormal, i, MemDC, 0, 0, ILD_NORMAL);
|
|
|
|
// Convert colored pixels to gray
|
|
for (int x = 0 ; x < cx; ++x)
|
|
{
|
|
for (int y = 0; y < cy; ++y)
|
|
{
|
|
COLORREF clr = ::GetPixel(MemDC, x, y);
|
|
|
|
if (clr != crMask)
|
|
{
|
|
BYTE byGray = (BYTE) (95 + (GetRValue(clr) *3 + GetGValue(clr)*6 + GetBValue(clr))/20);
|
|
MemDC.SetPixel(x, y, RGB(byGray, byGray, byGray));
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// Detach the bitmap so we can use it.
|
|
CBitmap* pBitmap = MemDC.SelectObject(pOldBitmap);
|
|
ImageList_AddMasked(himlDisabled, *pBitmap, crMask);
|
|
}
|
|
|
|
return himlDisabled;
|
|
}
|
|
#endif
|
|
|
|
////////////////////////////////////////////
|
|
// Global Function Definitions
|
|
//
|
|
|
|
inline CDC* FromHandle(HDC hDC)
|
|
// Returns the CDC object associated with the device context handle
|
|
// If a CDC object doesn't already exist, a temporary CDC object is created.
|
|
// The HDC belonging to a temporary CDC is not released or destroyed when the
|
|
// temporary CDC is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CDC* pDC = GetApp()->GetCDCFromMap(hDC);
|
|
if (hDC != 0 && pDC == 0)
|
|
{
|
|
pDC = new CDC;
|
|
GetApp()->AddTmpDC(pDC);
|
|
pDC->m_pData->hDC = hDC;
|
|
pDC->m_pData->bRemoveHDC = FALSE;
|
|
}
|
|
return pDC;
|
|
}
|
|
|
|
inline CBitmap* FromHandle(HBITMAP hBitmap)
|
|
// Returns the CBitmap associated with the Bitmap handle
|
|
// If a CBitmap object doesn't already exist, a temporary CBitmap object is created.
|
|
// The HBITMAP belonging to a temporary CBitmap is not released or destroyed
|
|
// when the temporary CBitmap is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CBitmap* pBitmap = (CBitmap*)GetApp()->GetCGDIObjectFromMap(hBitmap);
|
|
if (hBitmap != 0 && pBitmap == 0)
|
|
{
|
|
pBitmap = new CBitmap;
|
|
GetApp()->AddTmpGDI(pBitmap);
|
|
pBitmap->m_pData->hGDIObject = hBitmap;
|
|
pBitmap->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pBitmap;
|
|
}
|
|
|
|
inline CBrush* FromHandle(HBRUSH hBrush)
|
|
// Returns the CBrush associated with the Brush handle
|
|
// If a CBrush object doesn't already exist, a temporary CBrush object is created.
|
|
// The HBRUSH belonging to a temporary CBrush is not released or destroyed
|
|
// when the temporary CBrush is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CBrush* pBrush = (CBrush*)GetApp()->GetCGDIObjectFromMap(hBrush);
|
|
if (hBrush != 0 && pBrush == 0)
|
|
{
|
|
pBrush = new CBrush;
|
|
GetApp()->AddTmpGDI(pBrush);
|
|
pBrush->m_pData->hGDIObject = hBrush;
|
|
pBrush->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pBrush;
|
|
}
|
|
|
|
inline CFont* FromHandle(HFONT hFont)
|
|
// Returns the CFont associated with the Font handle
|
|
// If a CFont object doesn't already exist, a temporary CFont object is created.
|
|
// The HFONT belonging to a temporary CFont is not released or destroyed
|
|
// when the temporary CFont is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CFont* pFont = (CFont*)GetApp()->GetCGDIObjectFromMap(hFont);
|
|
if (hFont != 0 && pFont == 0)
|
|
{
|
|
pFont = new CFont;
|
|
GetApp()->AddTmpGDI(pFont);
|
|
pFont->m_pData->hGDIObject = hFont;
|
|
pFont->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pFont;
|
|
}
|
|
|
|
inline CPalette* FromHandle(HPALETTE hPalette)
|
|
// Returns the CPalette associated with the palette handle
|
|
// If a CPalette object doesn't already exist, a temporary CPalette object is created.
|
|
// The HPALETTE belonging to a temporary CPalette is not released or destroyed
|
|
// when the temporary CPalette is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CPalette* pPalette = (CPalette*)GetApp()->GetCGDIObjectFromMap(hPalette);
|
|
if (hPalette != 0 && pPalette == 0)
|
|
{
|
|
pPalette = new CPalette;
|
|
GetApp()->AddTmpGDI(pPalette);
|
|
pPalette->m_pData->hGDIObject = hPalette;
|
|
pPalette->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pPalette;
|
|
}
|
|
|
|
inline CPen* FromHandle(HPEN hPen)
|
|
// Returns the CPen associated with the HPEN.
|
|
// If a CPen object doesn't already exist, a temporary CPen object is created.
|
|
// The HPEN belonging to a temporary CPen is not released or destroyed
|
|
// when the temporary CPen is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CPen* pPen = (CPen*)GetApp()->GetCGDIObjectFromMap(hPen);
|
|
if (hPen != 0 && pPen == 0)
|
|
{
|
|
pPen = new CPen;
|
|
GetApp()->AddTmpGDI(pPen);
|
|
pPen->m_pData->hGDIObject = hPen;
|
|
pPen->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pPen;
|
|
}
|
|
|
|
inline CRgn* FromHandle(HRGN hRgn)
|
|
// Returns the CRgn associated with the HRGN.
|
|
// If a CRgn object doesn't already exist, a temporary CRgn object is created.
|
|
// The HRGN belonging to a temporary CRgn is not released or destroyed
|
|
// when the temporary CRgn is deconstructed.
|
|
{
|
|
assert( GetApp() );
|
|
CRgn* pRgn = (CRgn*)GetApp()->GetCGDIObjectFromMap(hRgn);
|
|
if (hRgn != 0 && pRgn == 0)
|
|
{
|
|
pRgn = new CRgn;
|
|
GetApp()->AddTmpGDI(pRgn);
|
|
pRgn->m_pData->hGDIObject = hRgn;
|
|
pRgn->m_pData->bRemoveObject = FALSE;
|
|
}
|
|
return pRgn;
|
|
}
|
|
|
|
|
|
|
|
} // namespace Win32xx
|
|
|
|
#endif // _WIN32XX_GDI_H_
|
|
|