CMKDraw主要是用于位图的绘制,代码如下
1.头文件
//
/
//
// Draw.h : header file
//
// /
#pragma once
// /
typedef DWORD HLSCOLOR;
#define HLS(h,l,s) ((HLSCOLOR)(((BYTE)(h) | ((WORD)((BYTE)(l)) << 8 )) | (((DWORD)(BYTE)(s)) << 16 )))
// /
#define HLS_H(hls) ((BYTE)(hls))
#define HLS_L(hls) ((BYTE)(((WORD)(hls)) >> 8 ))
#define HLS_S(hls) ((BYTE)((hls) >> 16 ))
#define BMP_BACK 0
#define BMP_NORMAL 1
#define BMP_FOCUS 2
#define BMP_DOWN 3
#define BMP_DISABLE 4
#define BMP_ACTIVE 1
#define BMP_INACTIVE 2
#define BMP_SLIDER 3
#define BMP_CHECK 1
#define BMP_UNCHECK 2
// 在指定的位置绘制阴影
#define SM_CXSHADOW 10
// /
HLSCOLOR RGB2HLS (COLORREF rgb);
COLORREF HLS2RGB (HLSCOLOR hls);
// /
// Performs some modifications on the specified color : luminance and saturation
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S);
// /
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect);
class CMKClientRect : public CRect
... {
public:
CMKClientRect (HWND hWnd)
...{
::GetClientRect (hWnd, this);
};
CMKClientRect (const CWnd* pWnd)
...{
::GetClientRect (pWnd->GetSafeHwnd(), this);
};
} ;
// /
// /
class CMKWindowRect : public CRect
... {
public:
CMKWindowRect (HWND hWnd)
...{
::GetWindowRect (hWnd, this);
};
CMKWindowRect (const CWnd* pWnd)
...{
::GetWindowRect (pWnd->GetSafeHwnd(), this);
};
} ;
// /
// /
class CMKWindowText : public CString
... {
public:
CMKWindowText (HWND hWnd)
...{
CWnd::FromHandle (hWnd)->GetWindowText (*this);
};
CMKWindowText (const CWnd* pWnd)
...{
pWnd->GetWindowText (*this);
};
} ;
class CMemDC : public CDC
... {
private:
CBitmap* m_bitmap;
CBitmap* m_oldBitmap;
CDC* m_pDC;
CRect m_rcBounds;
public:
CMemDC(CDC* pDC, const CRect& rcBounds) : CDC()
...{
CreateCompatibleDC(pDC);
m_bitmap = new CBitmap;
m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.right, rcBounds.bottom);
m_oldBitmap = SelectObject(m_bitmap);
m_pDC = pDC;
m_rcBounds = rcBounds;
}
~CMemDC()
...{
m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(),
this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
SelectObject(m_oldBitmap);
if (m_bitmap != NULL)
delete m_bitmap;
}
CMemDC* operator->()
...{
return this;
}
} ;
// /
// /
class CBufferDC : public CDC
... {
HDC m_hDestDC;
CBitmap m_bitmap; // Bitmap in Memory DC
CRect m_rect;
HGDIOBJ m_hOldBitmap; // Previous Bitmap
public:
CBufferDC (HDC hDestDC, const CRect& rcPaint = CRect(0,0,0,0));
~CBufferDC ();
} ;
// /
// /
class CPenDC
... {
protected:
CPen m_pen;
HDC m_hDC;
HPEN m_hOldPen;
public:
CPenDC (HDC hDC, COLORREF crColor = CLR_NONE);
~CPenDC ();
void Color (COLORREF crColor);
COLORREF Color () const;
} ;
// /
// /
class CBrushDC
... {
protected:
CBrush m_brush;
HDC m_hDC;
HBRUSH m_hOldBrush;
public:
CBrushDC (HDC hDC, COLORREF crColor = CLR_NONE);
~CBrushDC ();
void Color (COLORREF crColor);
COLORREF Color () const;
} ;
// /
// /
class CFontDC
... {
protected:
HFONT m_hFont;
HDC m_hDC;
HFONT m_hDefFont;
COLORREF m_crTextOld;
public:
CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText = CLR_DEFAULT);
CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText = CLR_DEFAULT);
CFontDC (HDC hDC, HFONT hFont, COLORREF crText = CLR_DEFAULT);
~CFontDC ();
const CFontDC& operator = (LPCTSTR sFaceName);
const CFontDC& operator = (BYTE nStockFont);
const CFontDC& operator = (HFONT hFont);
const CFontDC& operator = (COLORREF crText);
operator LPCTSTR ();
operator COLORREF ();
} ;
// /
// /
class CBoldDC
... {
protected:
CFont m_fontBold;
HDC m_hDC;
HFONT m_hDefFont;
public:
CBoldDC (HDC hDC, bool bBold);
~CBoldDC ();
} ;
//
//
class CMKBitmap : public CBitmap
... {
public:
CMKBitmap();
virtual ~CMKBitmap();
BOOL LoadImage(LPCTSTR szImagePath, COLORREF crBack = 0);
BOOL LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst = NULL, COLORREF crBack = 0);
BOOL LoadBitmap (UINT nIDResource)
...{
return CBitmap::LoadBitmap(nIDResource);
}
// helpers
static BOOL GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize);
static IPicture* LoadFromBuffer(BYTE* pBuff, int nSize);
BOOL Draw( CDC *pDC, LPRECT r);
//draw sub bmp to special point
BOOL Draw( CDC *pDC, int x, int y, LPRECT sr );
BOOL Draw( CDC *pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans );
BOOL StretchDraw(CDC *pDC, LPRECT tr, LPRECT sr );
BOOL StretchDraw(CDC *pDC, LPRECT r);
int Width() ...{ return GetWidth(); }
int Height()...{ return GetHeight();}
int GetWidth()
...{
if (!GetSafeHandle())
return 0;
BITMAP bm;
memset( &bm, 0, sizeof(bm) );
GetBitmap(&bm);
return bm.bmWidth;
}
int GetHeight()
...{
if (!GetSafeHandle())
return 0;
BITMAP bm;
memset( &bm, 0, sizeof(bm) );
GetBitmap(&bm);
return bm.bmHeight;
}
BOOL Attach(HBITMAP hbmp) ...{ return CBitmap::Attach( hbmp );}
BOOL LoadBitmap(LPCTSTR szFilename)
...{
ASSERT(szFilename);
DeleteObject();
return LoadImage( szFilename );
}
BOOL DrawTransparent(CDC * pDC, int x, int y, COLORREF crColour);
HRGN CreateRgnFromFile( COLORREF color );
static void MKTransparentBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth,
int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc,
COLORREF colorTransparent, HPALETTE hPal );
protected:
BOOL Attach(IPicture* pPicture, COLORREF crBack);
} ;
class CMKDraw
... {
public:
typedef enum _tagDrawMode
...{
DrawModeFill = 0,
DrawModeWidthStretch = 1,
DrawModeHeightStretch = 2,
DrawModeAllStretch = 3,
DrawMode3D = 4,
DrawModeState = 5,
DrawModeHeightCenter3D = 6,
DrawModeHeightStretch3D = 7
}DrawMode;
static BOOL MKDrawBitmap(CDC* pDC, LPCRECT lpRect, CBitmap* pBitmap,UINT Mode = DrawModeHeightStretch);
static BOOL MKDrawVerticalText(CDC* pDC,LPCRECT lpRect,LPCTSTR lpText,int length,UINT format,LOGFONT *lf);
static HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010);
static BOOL MKFillGradient(CDC *pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz = TRUE ) ;
static void MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT& rc) ;
} ;
//
// Draw.h : header file
//
// /
#pragma once
// /
typedef DWORD HLSCOLOR;
#define HLS(h,l,s) ((HLSCOLOR)(((BYTE)(h) | ((WORD)((BYTE)(l)) << 8 )) | (((DWORD)(BYTE)(s)) << 16 )))
// /
#define HLS_H(hls) ((BYTE)(hls))
#define HLS_L(hls) ((BYTE)(((WORD)(hls)) >> 8 ))
#define HLS_S(hls) ((BYTE)((hls) >> 16 ))
#define BMP_BACK 0
#define BMP_NORMAL 1
#define BMP_FOCUS 2
#define BMP_DOWN 3
#define BMP_DISABLE 4
#define BMP_ACTIVE 1
#define BMP_INACTIVE 2
#define BMP_SLIDER 3
#define BMP_CHECK 1
#define BMP_UNCHECK 2
// 在指定的位置绘制阴影
#define SM_CXSHADOW 10
// /
HLSCOLOR RGB2HLS (COLORREF rgb);
COLORREF HLS2RGB (HLSCOLOR hls);
// /
// Performs some modifications on the specified color : luminance and saturation
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S);
// /
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect);
class CMKClientRect : public CRect
... {
public:
CMKClientRect (HWND hWnd)
...{
::GetClientRect (hWnd, this);
};
CMKClientRect (const CWnd* pWnd)
...{
::GetClientRect (pWnd->GetSafeHwnd(), this);
};
} ;
// /
// /
class CMKWindowRect : public CRect
... {
public:
CMKWindowRect (HWND hWnd)
...{
::GetWindowRect (hWnd, this);
};
CMKWindowRect (const CWnd* pWnd)
...{
::GetWindowRect (pWnd->GetSafeHwnd(), this);
};
} ;
// /
// /
class CMKWindowText : public CString
... {
public:
CMKWindowText (HWND hWnd)
...{
CWnd::FromHandle (hWnd)->GetWindowText (*this);
};
CMKWindowText (const CWnd* pWnd)
...{
pWnd->GetWindowText (*this);
};
} ;
class CMemDC : public CDC
... {
private:
CBitmap* m_bitmap;
CBitmap* m_oldBitmap;
CDC* m_pDC;
CRect m_rcBounds;
public:
CMemDC(CDC* pDC, const CRect& rcBounds) : CDC()
...{
CreateCompatibleDC(pDC);
m_bitmap = new CBitmap;
m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.right, rcBounds.bottom);
m_oldBitmap = SelectObject(m_bitmap);
m_pDC = pDC;
m_rcBounds = rcBounds;
}
~CMemDC()
...{
m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(),
this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
SelectObject(m_oldBitmap);
if (m_bitmap != NULL)
delete m_bitmap;
}
CMemDC* operator->()
...{
return this;
}
} ;
// /
// /
class CBufferDC : public CDC
... {
HDC m_hDestDC;
CBitmap m_bitmap; // Bitmap in Memory DC
CRect m_rect;
HGDIOBJ m_hOldBitmap; // Previous Bitmap
public:
CBufferDC (HDC hDestDC, const CRect& rcPaint = CRect(0,0,0,0));
~CBufferDC ();
} ;
// /
// /
class CPenDC
... {
protected:
CPen m_pen;
HDC m_hDC;
HPEN m_hOldPen;
public:
CPenDC (HDC hDC, COLORREF crColor = CLR_NONE);
~CPenDC ();
void Color (COLORREF crColor);
COLORREF Color () const;
} ;
// /
// /
class CBrushDC
... {
protected:
CBrush m_brush;
HDC m_hDC;
HBRUSH m_hOldBrush;
public:
CBrushDC (HDC hDC, COLORREF crColor = CLR_NONE);
~CBrushDC ();
void Color (COLORREF crColor);
COLORREF Color () const;
} ;
// /
// /
class CFontDC
... {
protected:
HFONT m_hFont;
HDC m_hDC;
HFONT m_hDefFont;
COLORREF m_crTextOld;
public:
CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText = CLR_DEFAULT);
CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText = CLR_DEFAULT);
CFontDC (HDC hDC, HFONT hFont, COLORREF crText = CLR_DEFAULT);
~CFontDC ();
const CFontDC& operator = (LPCTSTR sFaceName);
const CFontDC& operator = (BYTE nStockFont);
const CFontDC& operator = (HFONT hFont);
const CFontDC& operator = (COLORREF crText);
operator LPCTSTR ();
operator COLORREF ();
} ;
// /
// /
class CBoldDC
... {
protected:
CFont m_fontBold;
HDC m_hDC;
HFONT m_hDefFont;
public:
CBoldDC (HDC hDC, bool bBold);
~CBoldDC ();
} ;
//
//
class CMKBitmap : public CBitmap
... {
public:
CMKBitmap();
virtual ~CMKBitmap();
BOOL LoadImage(LPCTSTR szImagePath, COLORREF crBack = 0);
BOOL LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst = NULL, COLORREF crBack = 0);
BOOL LoadBitmap (UINT nIDResource)
...{
return CBitmap::LoadBitmap(nIDResource);
}
// helpers
static BOOL GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize);
static IPicture* LoadFromBuffer(BYTE* pBuff, int nSize);
BOOL Draw( CDC *pDC, LPRECT r);
//draw sub bmp to special point
BOOL Draw( CDC *pDC, int x, int y, LPRECT sr );
BOOL Draw( CDC *pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans );
BOOL StretchDraw(CDC *pDC, LPRECT tr, LPRECT sr );
BOOL StretchDraw(CDC *pDC, LPRECT r);
int Width() ...{ return GetWidth(); }
int Height()...{ return GetHeight();}
int GetWidth()
...{
if (!GetSafeHandle())
return 0;
BITMAP bm;
memset( &bm, 0, sizeof(bm) );
GetBitmap(&bm);
return bm.bmWidth;
}
int GetHeight()
...{
if (!GetSafeHandle())
return 0;
BITMAP bm;
memset( &bm, 0, sizeof(bm) );
GetBitmap(&bm);
return bm.bmHeight;
}
BOOL Attach(HBITMAP hbmp) ...{ return CBitmap::Attach( hbmp );}
BOOL LoadBitmap(LPCTSTR szFilename)
...{
ASSERT(szFilename);
DeleteObject();
return LoadImage( szFilename );
}
BOOL DrawTransparent(CDC * pDC, int x, int y, COLORREF crColour);
HRGN CreateRgnFromFile( COLORREF color );
static void MKTransparentBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth,
int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc,
COLORREF colorTransparent, HPALETTE hPal );
protected:
BOOL Attach(IPicture* pPicture, COLORREF crBack);
} ;
class CMKDraw
... {
public:
typedef enum _tagDrawMode
...{
DrawModeFill = 0,
DrawModeWidthStretch = 1,
DrawModeHeightStretch = 2,
DrawModeAllStretch = 3,
DrawMode3D = 4,
DrawModeState = 5,
DrawModeHeightCenter3D = 6,
DrawModeHeightStretch3D = 7
}DrawMode;
static BOOL MKDrawBitmap(CDC* pDC, LPCRECT lpRect, CBitmap* pBitmap,UINT Mode = DrawModeHeightStretch);
static BOOL MKDrawVerticalText(CDC* pDC,LPCRECT lpRect,LPCTSTR lpText,int length,UINT format,LOGFONT *lf);
static HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010);
static BOOL MKFillGradient(CDC *pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz = TRUE ) ;
static void MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT& rc) ;
} ;
2.实现文件,CPP文件如下:
//
/
//
// Draw.cpp : implementation file
//
// /
#include " stdafx.h "
#include " MKDraw.h "
// /
HLSCOLOR RGB2HLS (COLORREF rgb)
... {
unsigned char minval = min(GetRValue(rgb), min(GetGValue(rgb), GetBValue(rgb)));
unsigned char maxval = max(GetRValue(rgb), max(GetGValue(rgb), GetBValue(rgb)));
float mdiff = float(maxval) - float(minval);
float msum = float(maxval) + float(minval);
float luminance = msum / 510.0f;
float saturation = 0.0f;
float hue = 0.0f;
if ( maxval != minval )
...{
float rnorm = (maxval - GetRValue(rgb) ) / mdiff;
float gnorm = (maxval - GetGValue(rgb)) / mdiff;
float bnorm = (maxval - GetBValue(rgb) ) / mdiff;
saturation = (luminance <= 0.5f) ? (mdiff / msum) : (mdiff / (510.0f - msum));
if (GetRValue(rgb) == maxval) hue = 60.0f * (6.0f + bnorm - gnorm);
if (GetGValue(rgb) == maxval) hue = 60.0f * (2.0f + rnorm - bnorm);
if (GetBValue(rgb) == maxval) hue = 60.0f * (4.0f + gnorm - rnorm);
if (hue > 360.0f) hue = hue - 360.0f;
}
return HLS ((hue*255)/360, luminance*255, saturation*255);
}
// /
static BYTE _ToRGB ( float rm1, float rm2, float rh)
... {
if (rh > 360.0f) rh -= 360.0f;
else if (rh < 0.0f) rh += 360.0f;
if (rh < 60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;
else if (rh < 180.0f) rm1 = rm2;
else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;
return (BYTE)(rm1 * 255);
}
// /
COLORREF HLS2RGB (HLSCOLOR hls)
... {
float hue = ((int)HLS_H(hls)*360)/255.0f;
float luminance = HLS_L(hls)/255.0f;
float saturation = HLS_S(hls)/255.0f;
if ( saturation == 0.0f )
...{
return RGB (HLS_L(hls), HLS_L(hls), HLS_L(hls));
}
float rm1, rm2;
if ( luminance <= 0.5f ) rm2 = luminance + luminance * saturation;
else rm2 = luminance + saturation - luminance * saturation;
rm1 = 2.0f * luminance - rm2;
BYTE red = _ToRGB (rm1, rm2, hue + 120.0f);
BYTE green = _ToRGB (rm1, rm2, hue);
BYTE blue = _ToRGB (rm1, rm2, hue - 120.0f);
return RGB (red, green, blue);
}
// /
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S)
... {
HLSCOLOR hls = RGB2HLS (rgb);
BYTE h = HLS_H(hls);
BYTE l = HLS_L(hls);
BYTE s = HLS_S(hls);
if ( percent_L > 0 )
...{
l = BYTE(l + ((255 - l) * percent_L) / 100);
}
else if ( percent_L < 0 )
...{
l = BYTE((l * (100+percent_L)) / 100);
}
if ( percent_S > 0 )
...{
s = BYTE(s + ((255 - s) * percent_S) / 100);
}
else if ( percent_S < 0 )
...{
s = BYTE((s * (100+percent_S)) / 100);
}
return HLS2RGB (HLS(h, l, s));
}
/
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect)
... {
HDC hDC;
HDC hMemDC;
HBITMAP hNewBitmap = NULL;
if ( (hDC = ::GetDC (NULL)) != NULL )
...{
if ( (hMemDC = ::CreateCompatibleDC (hDC)) != NULL )
...{
if ( (hNewBitmap = ::CreateCompatibleBitmap (hDC, pRect->right - pRect->left, pRect->bottom - pRect->top)) != NULL )
...{
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hNewBitmap);
::BitBlt (hMemDC, 0, 0, pRect->right - pRect->left, pRect->bottom - pRect->top,
hDC, pRect->left, pRect->top, SRCCOPY);
::SelectObject (hMemDC, (HGDIOBJ) hOldBitmap);
}
::DeleteDC (hMemDC);
}
::ReleaseDC (NULL, hDC);
}
return hNewBitmap;
}
// /
// /
CBufferDC::CBufferDC (HDC hDestDC, const CRect & rcPaint) : m_hDestDC (hDestDC)
... {
if ( rcPaint.IsRectEmpty() )
...{
::GetClipBox (m_hDestDC, m_rect);
}
else
...{
m_rect = rcPaint;
}
VERIFY(Attach (::CreateCompatibleDC (m_hDestDC)));
m_bitmap.Attach (::CreateCompatibleBitmap (m_hDestDC, m_rect.right, m_rect.bottom));
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
if ( m_rect.top > 0 )
...{
ExcludeClipRect (0, 0, m_rect.right, m_rect.top);
}
if ( m_rect.left > 0 )
...{
ExcludeClipRect (0, m_rect.top, m_rect.left, m_rect.bottom);
}
}
// /
CBufferDC:: ~ CBufferDC ()
... {
VERIFY(::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), m_hDC, m_rect.left, m_rect.top, SRCCOPY));
::SelectObject (m_hDC, m_hOldBitmap);
}
// /
// /
CPenDC::CPenDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
... {
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
// /
CPenDC:: ~ CPenDC ()
... {
::SelectObject (m_hDC, m_hOldPen);
}
// /
void CPenDC::Color (COLORREF crColor)
... {
::SelectObject (m_hDC, m_hOldPen);
VERIFY(m_pen.DeleteObject());
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
// /
COLORREF CPenDC::Color () const
... {
LOGPEN logPen;
((CPenDC*)this)->m_pen.GetLogPen (&logPen);
return logPen.lopnColor;
}
// /
// /
CBrushDC::CBrushDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
... {
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
// /
CBrushDC:: ~ CBrushDC ()
... {
::SelectObject (m_hDC, m_hOldBrush);
}
// /
void CBrushDC::Color (COLORREF crColor)
... {
::SelectObject (m_hDC, m_hOldBrush);
VERIFY(m_brush.DeleteObject());
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
// /
COLORREF CBrushDC::Color () const
... {
LOGBRUSH logBrush;
((CBrushDC*)this)->m_brush.GetLogBrush (&logBrush);
return logBrush.lbColor;
}
/
/
CFontDC::CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = sFaceName;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC::CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = nStockFont;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC::CFontDC (HDC hDC, HFONT hFont, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = hFont;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC:: ~ CFontDC ()
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
if ( m_crTextOld != CLR_NONE )
...{
::SetTextColor (m_hDC, m_crTextOld);
}
}
/
const CFontDC & CFontDC::operator = (LPCTSTR sFaceName)
... {
LOGFONT lf;
::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), &lf);
if ( _tcsicmp (sFaceName, lf.lfFaceName) )
...{
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
_tcscpy (lf.lfFaceName, sFaceName);
m_hFont = ::CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
}
return *this;
}
/
const CFontDC & CFontDC::operator = (BYTE nStockFont)
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = (HFONT)::GetStockObject (nStockFont);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/
const CFontDC & CFontDC::operator = (HFONT hFont)
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = hFont;
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/
const CFontDC & CFontDC::operator = (COLORREF crText)
... {
if ( m_crTextOld == CLR_NONE )
...{
m_crTextOld = ::GetTextColor (m_hDC);
}
::SetTextColor (m_hDC, crText);
return *this;
}
/
CFontDC::operator LPCTSTR ()
... {
LOGFONT lf;
::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), &lf);
return lf.lfFaceName;
}
/
CFontDC::operator COLORREF ()
... {
return ::GetTextColor (m_hDC);
}
/
/
CBoldDC::CBoldDC (HDC hDC, bool bBold) : m_hDC (hDC), m_hDefFont (NULL)
... {
LOGFONT lf;
CFont::FromHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT))->GetLogFont (&lf);
if ( ( bBold && lf.lfWeight != FW_BOLD) ||
(!bBold && lf.lfWeight == FW_BOLD) )
...{
lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
m_fontBold.CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_fontBold);
}
}
/
CBoldDC:: ~ CBoldDC ()
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
}
}
/
/
#define DB_GETTYPE(Style) ((Style) & 0x00FF )
#define DB_ISENABLED(Style) ( ! ((Style) & DB_DISABLED))
#define DB_ISBORDER(Style) (((Style) & DB_BORDER) == DB_BORDER)
#define DB_ISWINDOWDC(Style) (((Style) & DB_WINDOWDC) == DB_WINDOWDC)
#define DB_ISFLAT(Style) (((Style) & DB_FLAT) == DB_FLAT)
#define DB_ISPRESSED(Style) (((Style) & (DB_PRESSED | DB_PRESSED2)) != 0 )
#define DB_ISPRESSED1(Style) (((Style) & DB_PRESSED) == DB_PRESSED)
#define DB_ISPRESSED2(Style) (((Style) & DB_PRESSED2) == DB_PRESSED2)
#define DB_ISOVER(Style) (((Style) & DB_OVER) == DB_OVER)
#define DB_ISTRANSPARENT(Style) (((Style) & DB_TRANSPARENT) == DB_TRANSPARENT)
/
static void _DrawTriangle (CDC * pDC, int x, int y, int nSize, bool bDown)
... {
for ( int i = 0; i < nSize; i++ )
...{
pDC->MoveTo (x-i, bDown ? y-i : y+i);
pDC->LineTo (x+i+1, bDown ? y-i : y+i);
}
}
BOOL CMKDraw::MKDrawVerticalText(CDC * pDC,LPCRECT lpRect,LPCTSTR lpText, int length,UINT format,LOGFONT * lf)
... {
char *ptr = (char *)lpText;
char *start = (char *)lpText;
char *end = (char *)(lpText + length - 1);
char temp = NULL;
BOOL IsUnicode = FALSE;
while(ptr <= end)
...{
if(*ptr & 0x80)
...{
IsUnicode = TRUE;
break;
}
}
ptr = (char *)lpText;
CRect rtText;
CSize sz;
int top = lpRect->top;
if(!IsUnicode)
...{
lf->lfEscapement = 900;
lf->lfOrientation = 900;
CFont font;
font.CreateFontIndirect(lf);
pDC->SelectObject(&font);
sz = pDC->GetTextExtent(start,(int)(end - start));
rtText.left = lpRect->left + (lpRect->right - lpRect->left - sz.cy)/2;
rtText.top = top;
rtText.bottom = rtText.top + sz.cx;
rtText.right = lpRect->right;
pDC->TextOut(rtText.left,rtText.bottom,start,(int)(end - start));
return TRUE;
}
lf->lfEscapement = 0;
lf->lfOrientation = 0;
CFont font;
font.CreateFontIndirect(lf);
pDC->SelectObject(&font);
while(ptr <= end)
...{
//UNICODE
if(*ptr & 0x80)
...{
if(ptr + 1 > end)break;
start = ptr;
ptr += 2;
sz = pDC->GetTextExtent(start,(int)(ptr - start));
CRect rtText;
rtText.SetRect(lpRect->left + (lpRect->right - lpRect->left - sz.cx)/2,
top,lpRect->right,lpRect->bottom);
pDC->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
top += sz.cy;
}
else
...{
start = ptr;
ptr += 1;
sz = pDC->GetTextExtent(start,(int)(ptr - start));
CRect rtText;
rtText.SetRect(lpRect->left + (lpRect->right - lpRect->left - sz.cx)/2,
top,lpRect->right,lpRect->bottom);
pDC->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
top += sz.cy;
}
}
return TRUE;
}
// BITMAP Width and height > 9
BOOL CMKDraw::MKDrawBitmap(CDC * pDC, LPCRECT lpRect, CBitmap * pBitmap,UINT Mode)
... {
if(pDC == NULL)return FALSE;
if(pBitmap == NULL)return FALSE;
BITMAP bitmap;
pBitmap->GetBitmap(&bitmap);
if(bitmap.bmWidth < 9)return FALSE;
if(bitmap.bmHeight < 9)return FALSE;
CDC srcDC;
srcDC.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap = srcDC.SelectObject(pBitmap);
if(Mode == DrawModeState)
...{
pDC->StretchBlt(lpRect->left,lpRect->top,bitmap.bmWidth,bitmap.bmHeight,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
return TRUE;
}
if((DrawMode)Mode == DrawModeAllStretch)
...{
pDC->StretchBlt(lpRect->left,lpRect->top,lpRect->right - lpRect->left,
lpRect->bottom - lpRect->top,&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
int height;
int width;
if((DrawMode)Mode == DrawModeFill)
...{
int left = lpRect->left;
int top = lpRect->top;
while(left < lpRect->right)
...{
if(lpRect->right - left <= bitmap.bmWidth)
...{
width = lpRect->right - left;
if(lpRect->bottom - top <= bitmap.bmHeight)
...{
height = lpRect->bottom - top;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
break;
}
else
...{
height = bitmap.bmHeight;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
top += height;
left = lpRect->left;
}
}
else
...{
width = bitmap.bmWidth;
if(lpRect->bottom - top <= bitmap.bmHeight)
...{
height = lpRect->bottom - top;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
}
else
...{
height = bitmap.bmHeight;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
}
left += width;
}
}
srcDC.SelectObject(pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightStretch)
...{
height = lpRect->bottom - lpRect->top;
int top = lpRect->top;
int left = lpRect->left;
int right = lpRect->right;
while((right - left) >= bitmap.bmWidth)
...{
pDC->StretchBlt(left,top,bitmap.bmWidth,height,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
left += bitmap.bmWidth;
}
width = right - left;
pDC->StretchBlt(left,top,width,height,
&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeWidthStretch)
...{
height = lpRect->bottom - lpRect->top;
int top = lpRect->top;
width = lpRect->right - lpRect->left;
int left = lpRect->left;
int bottom = lpRect->bottom;
while((bottom - top) >= bitmap.bmHeight)
...{
pDC->StretchBlt(left,top,width,bitmap.bmHeight,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
top += bitmap.bmHeight;
}
height = bottom - top;
pDC->StretchBlt(left,top,width,height,
&srcDC,4,0,bitmap.bmWidth,height,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
}
if(Mode == DrawMode3D)
...{
int width = bitmap.bmWidth/3;
int height = bitmap.bmHeight/3;
int x = lpRect->left + width;
int y = lpRect->top + height;
//fill center
while( x + width < lpRect->right)
...{
while(y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,height,SRCCOPY);
y += height;
}
y = lpRect->top + height;
x += width;
}
//draw top border
x = lpRect->left + width;
y = lpRect->top;
pDC->BitBlt(lpRect->left,y,width,height,&srcDC,0,0,SRCCOPY);
while( x + width < lpRect->right)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,0,SRCCOPY);
x += width;
}
pDC->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,0,SRCCOPY);
//draw left border
x = lpRect->left;
y = lpRect->top + height;
while( y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,0,height,SRCCOPY);
y += height;
}
//draw right border
x = lpRect->right - width;
y = lpRect->top + height;
while( y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width + width,height,SRCCOPY);
y += height;
}
//draw bottom border
x = lpRect->left + width;
y = lpRect->bottom - height;
pDC->BitBlt(lpRect->left,y,width,height,&srcDC,0,height + height,SRCCOPY);
while( x + width < lpRect->right)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,height + height,SRCCOPY);
x += width;
}
pDC->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,height + height,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightStretch3D)
...{
int width = bitmap.bmWidth / 3;
int height = lpRect->bottom - lpRect->top;
int x = lpRect->left;
int y = lpRect->top;
int right = lpRect->right;
pDC->StretchBlt(x,y,width,height,&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);
while((x + width) < right)
...{
pDC->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
x += width;
}
pDC->StretchBlt(right - width,y,width,height,&srcDC,width + width,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightCenter3D)
...{
int width = bitmap.bmWidth / 3;
int height = lpRect->bottom - lpRect->top;
int x = lpRect->left;
int y = lpRect->top;
int right = lpRect->right;
while((x + width) < right)
...{
pDC->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
x += width;
}
pDC->StretchBlt(right - width,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
HRGN CMKDraw::BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
... {
HRGN hRgn = NULL;
if (hBmp)
...{
// Create a memory DC inside which we will scan the bitmap content
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
...{
// Get bitmap size
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
// Create a 32 bits depth bitmap and select it into the memory DC
BITMAPINFOHEADER RGB32BITSBITMAPINFO = ...{
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
...{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
// Create a DC just to copy the bitmap into the memory DC
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
...{
// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
// Copy the bitmap into the memory DC
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
// For better performances, we will use the ExtCreateRegion() function to create the
// region. This function take a RGNDATA structure on entry. We will add rectangles by
// amount of ALLOC_UNIT number in this structure.
#define ALLOC_UNIT 100
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
// Keep on hand highest and lowest values for the "transparent" pixels
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = min(0xff, lr + GetRValue(cTolerance));
BYTE hg = min(0xff, lg + GetGValue(cTolerance));
BYTE hb = min(0xff, lb + GetBValue(cTolerance));
// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
...{
TRACE(" ");
// Scan each bitmap pixel from left to right
for (int x = 0; x < bm.bmWidth; x++)
...{
// Search for a continuous range of "non transparent pixels"
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
...{
TRACE("1");
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
...{
b = GetGValue(*p);
if (b >= lg && b <= hg)
...{
b = GetBValue(*p);
if (b >= lb && b <= hb)
...{
TRACE("0");
// This pixel is "transparent"
break;
}
}
}
p++;
x++;
}
if (x > x0)
...{
// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
if (pData->rdh.nCount >= maxRects)
...{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
if (pData->rdh.nCount == 2000)
...{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
...{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// Go to next row (remember, the bitmap is inverted vertically)
p32 -= bm32.bmWidthBytes;
}
// Create or extend the region with the remaining rectangles
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
...{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
// Clean up
GlobalFree(hData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
return hRgn;
}
BOOL CMKDraw::MKFillGradient(CDC * pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz /**/ /*= TRUE*/ )
... {
int nShift = 6;
int nSteps = 1 << nShift;
for (int i = 0; i < nSteps; i++)
...{
BYTE bR = (BYTE) ((GetRValue(colorStart) * (nSteps - i) +
GetRValue(colorFinish) * i) >> nShift);
BYTE bG = (BYTE) ((GetGValue(colorStart) * (nSteps - i) +
GetGValue(colorFinish) * i) >> nShift);
BYTE bB = (BYTE) ((GetBValue(colorStart) * (nSteps - i) +
GetBValue(colorFinish) * i) >> nShift);
CBrush br (RGB(bR, bG, bB));
CRect r2 = rect;
if (bHorz)
...{
r2.bottom = rect.bottom -
((i * rect.Height()) >> nShift);
r2.top = rect.bottom -
(((i + 1) * rect.Height()) >> nShift );
if (r2.Height() > 0)
pDC->FillRect(r2, &br);
}
else
...{
r2.left = rect.left +
((i * rect.Width()) >> nShift);
r2.right = rect.left +
(((i + 1) * rect.Width()) >> nShift);
if (r2.Width() > 0)
pDC->FillRect(r2, &br);
}
}
return TRUE ;
}
void CMKDraw::MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT & rc)
... {
for ( int x = 0; x < rc.right-1; x++ )
...{
int nEnd = ( x > rc.right-SM_CXSHADOW*2 ) ? rc.right-SM_CXSHADOW-x : SM_CXSHADOW;
for ( int y = ( x < 2 ) ? 2-x : x > rc.right-SM_CXSHADOW-3 ? x-rc.right+SM_CXSHADOW+3 : 0; y < nEnd; y++ )
...{
int nMakeSpec = 78+(3-(x==0?0:(x==1?(y<2?0:1):(x==2?(y<2?y:2):y))))*5;
COLORREF cr = GetPixel (hDCIn, x+SM_CXSHADOW, rc.bottom-y-1);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, x+SM_CXSHADOW, rc.bottom-y-1, cr2);
}
}
for ( x = 0; x < SM_CXSHADOW; x++ )
...{
for ( int y = rc.top ; y < rc.bottom-x-SM_CXSHADOW-((x>0)?1:2); y++ )
...{
int nMakeSpec = 78+(3-(y==0?0:(y==1?(x<2?0:1):(y==2?(x<2?x:2):x))))*5;
COLORREF cr = GetPixel (hDCIn, rc.right-x-1, y+SM_CXSHADOW);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, rc.right-x-1, y+SM_CXSHADOW, cr2);
}
}
}
//
// Draw.cpp : implementation file
//
// /
#include " stdafx.h "
#include " MKDraw.h "
// /
HLSCOLOR RGB2HLS (COLORREF rgb)
... {
unsigned char minval = min(GetRValue(rgb), min(GetGValue(rgb), GetBValue(rgb)));
unsigned char maxval = max(GetRValue(rgb), max(GetGValue(rgb), GetBValue(rgb)));
float mdiff = float(maxval) - float(minval);
float msum = float(maxval) + float(minval);
float luminance = msum / 510.0f;
float saturation = 0.0f;
float hue = 0.0f;
if ( maxval != minval )
...{
float rnorm = (maxval - GetRValue(rgb) ) / mdiff;
float gnorm = (maxval - GetGValue(rgb)) / mdiff;
float bnorm = (maxval - GetBValue(rgb) ) / mdiff;
saturation = (luminance <= 0.5f) ? (mdiff / msum) : (mdiff / (510.0f - msum));
if (GetRValue(rgb) == maxval) hue = 60.0f * (6.0f + bnorm - gnorm);
if (GetGValue(rgb) == maxval) hue = 60.0f * (2.0f + rnorm - bnorm);
if (GetBValue(rgb) == maxval) hue = 60.0f * (4.0f + gnorm - rnorm);
if (hue > 360.0f) hue = hue - 360.0f;
}
return HLS ((hue*255)/360, luminance*255, saturation*255);
}
// /
static BYTE _ToRGB ( float rm1, float rm2, float rh)
... {
if (rh > 360.0f) rh -= 360.0f;
else if (rh < 0.0f) rh += 360.0f;
if (rh < 60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;
else if (rh < 180.0f) rm1 = rm2;
else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;
return (BYTE)(rm1 * 255);
}
// /
COLORREF HLS2RGB (HLSCOLOR hls)
... {
float hue = ((int)HLS_H(hls)*360)/255.0f;
float luminance = HLS_L(hls)/255.0f;
float saturation = HLS_S(hls)/255.0f;
if ( saturation == 0.0f )
...{
return RGB (HLS_L(hls), HLS_L(hls), HLS_L(hls));
}
float rm1, rm2;
if ( luminance <= 0.5f ) rm2 = luminance + luminance * saturation;
else rm2 = luminance + saturation - luminance * saturation;
rm1 = 2.0f * luminance - rm2;
BYTE red = _ToRGB (rm1, rm2, hue + 120.0f);
BYTE green = _ToRGB (rm1, rm2, hue);
BYTE blue = _ToRGB (rm1, rm2, hue - 120.0f);
return RGB (red, green, blue);
}
// /
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S)
... {
HLSCOLOR hls = RGB2HLS (rgb);
BYTE h = HLS_H(hls);
BYTE l = HLS_L(hls);
BYTE s = HLS_S(hls);
if ( percent_L > 0 )
...{
l = BYTE(l + ((255 - l) * percent_L) / 100);
}
else if ( percent_L < 0 )
...{
l = BYTE((l * (100+percent_L)) / 100);
}
if ( percent_S > 0 )
...{
s = BYTE(s + ((255 - s) * percent_S) / 100);
}
else if ( percent_S < 0 )
...{
s = BYTE((s * (100+percent_S)) / 100);
}
return HLS2RGB (HLS(h, l, s));
}
/
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect)
... {
HDC hDC;
HDC hMemDC;
HBITMAP hNewBitmap = NULL;
if ( (hDC = ::GetDC (NULL)) != NULL )
...{
if ( (hMemDC = ::CreateCompatibleDC (hDC)) != NULL )
...{
if ( (hNewBitmap = ::CreateCompatibleBitmap (hDC, pRect->right - pRect->left, pRect->bottom - pRect->top)) != NULL )
...{
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hNewBitmap);
::BitBlt (hMemDC, 0, 0, pRect->right - pRect->left, pRect->bottom - pRect->top,
hDC, pRect->left, pRect->top, SRCCOPY);
::SelectObject (hMemDC, (HGDIOBJ) hOldBitmap);
}
::DeleteDC (hMemDC);
}
::ReleaseDC (NULL, hDC);
}
return hNewBitmap;
}
// /
// /
CBufferDC::CBufferDC (HDC hDestDC, const CRect & rcPaint) : m_hDestDC (hDestDC)
... {
if ( rcPaint.IsRectEmpty() )
...{
::GetClipBox (m_hDestDC, m_rect);
}
else
...{
m_rect = rcPaint;
}
VERIFY(Attach (::CreateCompatibleDC (m_hDestDC)));
m_bitmap.Attach (::CreateCompatibleBitmap (m_hDestDC, m_rect.right, m_rect.bottom));
m_hOldBitmap = ::SelectObject (m_hDC, m_bitmap);
if ( m_rect.top > 0 )
...{
ExcludeClipRect (0, 0, m_rect.right, m_rect.top);
}
if ( m_rect.left > 0 )
...{
ExcludeClipRect (0, m_rect.top, m_rect.left, m_rect.bottom);
}
}
// /
CBufferDC:: ~ CBufferDC ()
... {
VERIFY(::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), m_hDC, m_rect.left, m_rect.top, SRCCOPY));
::SelectObject (m_hDC, m_hOldBitmap);
}
// /
// /
CPenDC::CPenDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
... {
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
// /
CPenDC:: ~ CPenDC ()
... {
::SelectObject (m_hDC, m_hOldPen);
}
// /
void CPenDC::Color (COLORREF crColor)
... {
::SelectObject (m_hDC, m_hOldPen);
VERIFY(m_pen.DeleteObject());
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
// /
COLORREF CPenDC::Color () const
... {
LOGPEN logPen;
((CPenDC*)this)->m_pen.GetLogPen (&logPen);
return logPen.lopnColor;
}
// /
// /
CBrushDC::CBrushDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
... {
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
// /
CBrushDC:: ~ CBrushDC ()
... {
::SelectObject (m_hDC, m_hOldBrush);
}
// /
void CBrushDC::Color (COLORREF crColor)
... {
::SelectObject (m_hDC, m_hOldBrush);
VERIFY(m_brush.DeleteObject());
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
// /
COLORREF CBrushDC::Color () const
... {
LOGBRUSH logBrush;
((CBrushDC*)this)->m_brush.GetLogBrush (&logBrush);
return logBrush.lbColor;
}
/
/
CFontDC::CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = sFaceName;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC::CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = nStockFont;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC::CFontDC (HDC hDC, HFONT hFont, COLORREF crText)
: m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
... {
*this = hFont;
if ( crText != CLR_DEFAULT )
...{
*this = crText;
}
}
/
CFontDC:: ~ CFontDC ()
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
if ( m_crTextOld != CLR_NONE )
...{
::SetTextColor (m_hDC, m_crTextOld);
}
}
/
const CFontDC & CFontDC::operator = (LPCTSTR sFaceName)
... {
LOGFONT lf;
::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), &lf);
if ( _tcsicmp (sFaceName, lf.lfFaceName) )
...{
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
_tcscpy (lf.lfFaceName, sFaceName);
m_hFont = ::CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
}
return *this;
}
/
const CFontDC & CFontDC::operator = (BYTE nStockFont)
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = (HFONT)::GetStockObject (nStockFont);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/
const CFontDC & CFontDC::operator = (HFONT hFont)
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = hFont;
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/
const CFontDC & CFontDC::operator = (COLORREF crText)
... {
if ( m_crTextOld == CLR_NONE )
...{
m_crTextOld = ::GetTextColor (m_hDC);
}
::SetTextColor (m_hDC, crText);
return *this;
}
/
CFontDC::operator LPCTSTR ()
... {
LOGFONT lf;
::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), &lf);
return lf.lfFaceName;
}
/
CFontDC::operator COLORREF ()
... {
return ::GetTextColor (m_hDC);
}
/
/
CBoldDC::CBoldDC (HDC hDC, bool bBold) : m_hDC (hDC), m_hDefFont (NULL)
... {
LOGFONT lf;
CFont::FromHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT))->GetLogFont (&lf);
if ( ( bBold && lf.lfWeight != FW_BOLD) ||
(!bBold && lf.lfWeight == FW_BOLD) )
...{
lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
m_fontBold.CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_fontBold);
}
}
/
CBoldDC:: ~ CBoldDC ()
... {
if ( m_hDefFont != NULL )
...{
::SelectObject (m_hDC, m_hDefFont);
}
}
/
/
#define DB_GETTYPE(Style) ((Style) & 0x00FF )
#define DB_ISENABLED(Style) ( ! ((Style) & DB_DISABLED))
#define DB_ISBORDER(Style) (((Style) & DB_BORDER) == DB_BORDER)
#define DB_ISWINDOWDC(Style) (((Style) & DB_WINDOWDC) == DB_WINDOWDC)
#define DB_ISFLAT(Style) (((Style) & DB_FLAT) == DB_FLAT)
#define DB_ISPRESSED(Style) (((Style) & (DB_PRESSED | DB_PRESSED2)) != 0 )
#define DB_ISPRESSED1(Style) (((Style) & DB_PRESSED) == DB_PRESSED)
#define DB_ISPRESSED2(Style) (((Style) & DB_PRESSED2) == DB_PRESSED2)
#define DB_ISOVER(Style) (((Style) & DB_OVER) == DB_OVER)
#define DB_ISTRANSPARENT(Style) (((Style) & DB_TRANSPARENT) == DB_TRANSPARENT)
/
static void _DrawTriangle (CDC * pDC, int x, int y, int nSize, bool bDown)
... {
for ( int i = 0; i < nSize; i++ )
...{
pDC->MoveTo (x-i, bDown ? y-i : y+i);
pDC->LineTo (x+i+1, bDown ? y-i : y+i);
}
}
BOOL CMKDraw::MKDrawVerticalText(CDC * pDC,LPCRECT lpRect,LPCTSTR lpText, int length,UINT format,LOGFONT * lf)
... {
char *ptr = (char *)lpText;
char *start = (char *)lpText;
char *end = (char *)(lpText + length - 1);
char temp = NULL;
BOOL IsUnicode = FALSE;
while(ptr <= end)
...{
if(*ptr & 0x80)
...{
IsUnicode = TRUE;
break;
}
}
ptr = (char *)lpText;
CRect rtText;
CSize sz;
int top = lpRect->top;
if(!IsUnicode)
...{
lf->lfEscapement = 900;
lf->lfOrientation = 900;
CFont font;
font.CreateFontIndirect(lf);
pDC->SelectObject(&font);
sz = pDC->GetTextExtent(start,(int)(end - start));
rtText.left = lpRect->left + (lpRect->right - lpRect->left - sz.cy)/2;
rtText.top = top;
rtText.bottom = rtText.top + sz.cx;
rtText.right = lpRect->right;
pDC->TextOut(rtText.left,rtText.bottom,start,(int)(end - start));
return TRUE;
}
lf->lfEscapement = 0;
lf->lfOrientation = 0;
CFont font;
font.CreateFontIndirect(lf);
pDC->SelectObject(&font);
while(ptr <= end)
...{
//UNICODE
if(*ptr & 0x80)
...{
if(ptr + 1 > end)break;
start = ptr;
ptr += 2;
sz = pDC->GetTextExtent(start,(int)(ptr - start));
CRect rtText;
rtText.SetRect(lpRect->left + (lpRect->right - lpRect->left - sz.cx)/2,
top,lpRect->right,lpRect->bottom);
pDC->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
top += sz.cy;
}
else
...{
start = ptr;
ptr += 1;
sz = pDC->GetTextExtent(start,(int)(ptr - start));
CRect rtText;
rtText.SetRect(lpRect->left + (lpRect->right - lpRect->left - sz.cx)/2,
top,lpRect->right,lpRect->bottom);
pDC->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
top += sz.cy;
}
}
return TRUE;
}
// BITMAP Width and height > 9
BOOL CMKDraw::MKDrawBitmap(CDC * pDC, LPCRECT lpRect, CBitmap * pBitmap,UINT Mode)
... {
if(pDC == NULL)return FALSE;
if(pBitmap == NULL)return FALSE;
BITMAP bitmap;
pBitmap->GetBitmap(&bitmap);
if(bitmap.bmWidth < 9)return FALSE;
if(bitmap.bmHeight < 9)return FALSE;
CDC srcDC;
srcDC.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap = srcDC.SelectObject(pBitmap);
if(Mode == DrawModeState)
...{
pDC->StretchBlt(lpRect->left,lpRect->top,bitmap.bmWidth,bitmap.bmHeight,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
return TRUE;
}
if((DrawMode)Mode == DrawModeAllStretch)
...{
pDC->StretchBlt(lpRect->left,lpRect->top,lpRect->right - lpRect->left,
lpRect->bottom - lpRect->top,&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
int height;
int width;
if((DrawMode)Mode == DrawModeFill)
...{
int left = lpRect->left;
int top = lpRect->top;
while(left < lpRect->right)
...{
if(lpRect->right - left <= bitmap.bmWidth)
...{
width = lpRect->right - left;
if(lpRect->bottom - top <= bitmap.bmHeight)
...{
height = lpRect->bottom - top;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
break;
}
else
...{
height = bitmap.bmHeight;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
top += height;
left = lpRect->left;
}
}
else
...{
width = bitmap.bmWidth;
if(lpRect->bottom - top <= bitmap.bmHeight)
...{
height = lpRect->bottom - top;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
}
else
...{
height = bitmap.bmHeight;
pDC->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
}
left += width;
}
}
srcDC.SelectObject(pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightStretch)
...{
height = lpRect->bottom - lpRect->top;
int top = lpRect->top;
int left = lpRect->left;
int right = lpRect->right;
while((right - left) >= bitmap.bmWidth)
...{
pDC->StretchBlt(left,top,bitmap.bmWidth,height,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
left += bitmap.bmWidth;
}
width = right - left;
pDC->StretchBlt(left,top,width,height,
&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeWidthStretch)
...{
height = lpRect->bottom - lpRect->top;
int top = lpRect->top;
width = lpRect->right - lpRect->left;
int left = lpRect->left;
int bottom = lpRect->bottom;
while((bottom - top) >= bitmap.bmHeight)
...{
pDC->StretchBlt(left,top,width,bitmap.bmHeight,
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
top += bitmap.bmHeight;
}
height = bottom - top;
pDC->StretchBlt(left,top,width,height,
&srcDC,4,0,bitmap.bmWidth,height,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
}
if(Mode == DrawMode3D)
...{
int width = bitmap.bmWidth/3;
int height = bitmap.bmHeight/3;
int x = lpRect->left + width;
int y = lpRect->top + height;
//fill center
while( x + width < lpRect->right)
...{
while(y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,height,SRCCOPY);
y += height;
}
y = lpRect->top + height;
x += width;
}
//draw top border
x = lpRect->left + width;
y = lpRect->top;
pDC->BitBlt(lpRect->left,y,width,height,&srcDC,0,0,SRCCOPY);
while( x + width < lpRect->right)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,0,SRCCOPY);
x += width;
}
pDC->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,0,SRCCOPY);
//draw left border
x = lpRect->left;
y = lpRect->top + height;
while( y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,0,height,SRCCOPY);
y += height;
}
//draw right border
x = lpRect->right - width;
y = lpRect->top + height;
while( y + height < lpRect->bottom)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width + width,height,SRCCOPY);
y += height;
}
//draw bottom border
x = lpRect->left + width;
y = lpRect->bottom - height;
pDC->BitBlt(lpRect->left,y,width,height,&srcDC,0,height + height,SRCCOPY);
while( x + width < lpRect->right)
...{
pDC->BitBlt(x,y,width,height,&srcDC,width,height + height,SRCCOPY);
x += width;
}
pDC->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,height + height,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightStretch3D)
...{
int width = bitmap.bmWidth / 3;
int height = lpRect->bottom - lpRect->top;
int x = lpRect->left;
int y = lpRect->top;
int right = lpRect->right;
pDC->StretchBlt(x,y,width,height,&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);
while((x + width) < right)
...{
pDC->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
x += width;
}
pDC->StretchBlt(right - width,y,width,height,&srcDC,width + width,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
if(Mode == DrawModeHeightCenter3D)
...{
int width = bitmap.bmWidth / 3;
int height = lpRect->bottom - lpRect->top;
int x = lpRect->left;
int y = lpRect->top;
int right = lpRect->right;
while((x + width) < right)
...{
pDC->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
x += width;
}
pDC->StretchBlt(right - width,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
srcDC.SelectObject(&pOldBitmap);
srcDC.DeleteDC();
return TRUE;
}
HRGN CMKDraw::BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
... {
HRGN hRgn = NULL;
if (hBmp)
...{
// Create a memory DC inside which we will scan the bitmap content
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
...{
// Get bitmap size
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
// Create a 32 bits depth bitmap and select it into the memory DC
BITMAPINFOHEADER RGB32BITSBITMAPINFO = ...{
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
...{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
// Create a DC just to copy the bitmap into the memory DC
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
...{
// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
// Copy the bitmap into the memory DC
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
// For better performances, we will use the ExtCreateRegion() function to create the
// region. This function take a RGNDATA structure on entry. We will add rectangles by
// amount of ALLOC_UNIT number in this structure.
#define ALLOC_UNIT 100
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
// Keep on hand highest and lowest values for the "transparent" pixels
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = min(0xff, lr + GetRValue(cTolerance));
BYTE hg = min(0xff, lg + GetGValue(cTolerance));
BYTE hb = min(0xff, lb + GetBValue(cTolerance));
// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
...{
TRACE(" ");
// Scan each bitmap pixel from left to right
for (int x = 0; x < bm.bmWidth; x++)
...{
// Search for a continuous range of "non transparent pixels"
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
...{
TRACE("1");
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
...{
b = GetGValue(*p);
if (b >= lg && b <= hg)
...{
b = GetBValue(*p);
if (b >= lb && b <= hb)
...{
TRACE("0");
// This pixel is "transparent"
break;
}
}
}
p++;
x++;
}
if (x > x0)
...{
// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
if (pData->rdh.nCount >= maxRects)
...{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
if (pData->rdh.nCount == 2000)
...{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
...{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// Go to next row (remember, the bitmap is inverted vertically)
p32 -= bm32.bmWidthBytes;
}
// Create or extend the region with the remaining rectangles
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
...{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
// Clean up
GlobalFree(hData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
return hRgn;
}
BOOL CMKDraw::MKFillGradient(CDC * pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz /**/ /*= TRUE*/ )
... {
int nShift = 6;
int nSteps = 1 << nShift;
for (int i = 0; i < nSteps; i++)
...{
BYTE bR = (BYTE) ((GetRValue(colorStart) * (nSteps - i) +
GetRValue(colorFinish) * i) >> nShift);
BYTE bG = (BYTE) ((GetGValue(colorStart) * (nSteps - i) +
GetGValue(colorFinish) * i) >> nShift);
BYTE bB = (BYTE) ((GetBValue(colorStart) * (nSteps - i) +
GetBValue(colorFinish) * i) >> nShift);
CBrush br (RGB(bR, bG, bB));
CRect r2 = rect;
if (bHorz)
...{
r2.bottom = rect.bottom -
((i * rect.Height()) >> nShift);
r2.top = rect.bottom -
(((i + 1) * rect.Height()) >> nShift );
if (r2.Height() > 0)
pDC->FillRect(r2, &br);
}
else
...{
r2.left = rect.left +
((i * rect.Width()) >> nShift);
r2.right = rect.left +
(((i + 1) * rect.Width()) >> nShift);
if (r2.Width() > 0)
pDC->FillRect(r2, &br);
}
}
return TRUE ;
}
void CMKDraw::MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT & rc)
... {
for ( int x = 0; x < rc.right-1; x++ )
...{
int nEnd = ( x > rc.right-SM_CXSHADOW*2 ) ? rc.right-SM_CXSHADOW-x : SM_CXSHADOW;
for ( int y = ( x < 2 ) ? 2-x : x > rc.right-SM_CXSHADOW-3 ? x-rc.right+SM_CXSHADOW+3 : 0; y < nEnd; y++ )
...{
int nMakeSpec = 78+(3-(x==0?0:(x==1?(y<2?0:1):(x==2?(y<2?y:2):y))))*5;
COLORREF cr = GetPixel (hDCIn, x+SM_CXSHADOW, rc.bottom-y-1);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, x+SM_CXSHADOW, rc.bottom-y-1, cr2);
}
}
for ( x = 0; x < SM_CXSHADOW; x++ )
...{
for ( int y = rc.top ; y < rc.bottom-x-SM_CXSHADOW-((x>0)?1:2); y++ )
...{
int nMakeSpec = 78+(3-(y==0?0:(y==1?(x<2?0:1):(y==2?(x<2?x:2):x))))*5;
COLORREF cr = GetPixel (hDCIn, rc.right-x-1, y+SM_CXSHADOW);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
SetPixel (hDCOut, rc.right-x-1, y+SM_CXSHADOW, cr2);
}
}
}
下一步介绍如何用这个绘制对话框.