#pragma once
class CUniBtnEx : public CButton
{
public:
CUniBtnEx(); // constructor
virtual ~CUniBtnEx(); // destructor
// point - position of the button on the parent window (in parent coordinates)
// hRgn - handle to region which represents the button (in button client coordinates)
// pParentWnd - handle to parent window
// nID - control Id
// nBorder - specifies width of the border in pixels for 3D highlight (allowed values are 1, 2)
// lpszCaption - window caption
// nColor - normal color
// sColor - selected color
// hColor - hover color
// dColor - disabled color
// dwStyle - window styles
BOOL Create(const CPoint point,
const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder,
LPCTSTR lpszCaption,
COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor,
DWORD dwStyle = WS_CHILD | WS_VISIBLE);
BOOL Create(const CPoint point,
const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder,
LPCTSTR lpszCaption,
CBitmap* pNormal, CBitmap* pSelected, CBitmap* pOver, CBitmap* pDisabled,
DWORD dwStyle = WS_CHILD | WS_VISIBLE );
void SetTextColor(COLORREF nTextColor, COLORREF sTextColor, COLORREF dTextColor);
void SetTextState(CPoint ptStart, CSize csText, UINT nTextType);
protected:
void delBmp();
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void PreSubclassWindow();
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
protected:
UINT m_nBorder; // 3D高亮边界的象素宽度
COLORREF m_nColor, m_sColor, m_hColor, m_dColor; // 对normal/selected/hover/disabled不同状态的背景色
COLORREF m_nTextColor, m_sTextColor, m_dTextColor; // 字体色
CRect m_rtText; // 字体矩形
CSize m_csText; // 字体大小
UINT m_nTextType; // 字体状态
CBitmap* m_pNormal; // 非按下非触摸位图
CBitmap* m_pSelected; // 按下位图
CBitmap* m_pHover; // 触摸位图
CBitmap* m_pDisabled; // 禁止位图
CPoint m_CenterPoint; // 按钮的中心点--绘制标题用
BOOL m_bMouseDown; // 鼠标按下
BOOL m_bHover; // 鼠标在按钮上
BOOL m_bCapture; // 鼠标是否被本按钮捕捉
HRGN m_hRgn; // region in screen coordinates
int m_iAutoCreate; // 要自动创造的位图按钮次数
virtual void DrawButton(CDC * pDC, CRect * pRect, UINT state); // 绘制按钮函数
virtual void DrawUserText(HDC* pHDC, COLORREF clrText);
BOOL Create(LPCTSTR lpszCaption, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, DWORD dwStyle);
BOOL HitTest(CPoint point); // determines if point is inside the button region
void PrepareStateBitmaps(CDC * pDC, CRect * pRect); // 根据按钮状态准备不同位图
void RgnPixelWork(CDC * pDC, CRgn * pRgn); // region pixel work - unused
void FrameRgn3D(HDC hDC, const HRGN hRgn, BOOL bSunken);// frames region to show 3D shadows
void CheckHover(CPoint point);
void PrepareNormalState(CDC * pDC, CDC * pMemDC, CRect * pRect); // prepare normal state button bitmap
void PrepareSelectedState(CDC * pDC, CDC * pMemDC, CRect * pRect); // prepare selectedstate button bitmap
void PrepareHoverState(CDC * pDC, CDC * pMemDC, CRect * pRect); // prepare hover state button bitmap
void PrepareDisabledState(CDC * pDC, CDC * pMemDC, CRect * pRect); // prepare disabled state button bitmap
void DrawButtonCaption(HDC hDC, CRect * pRect, BOOL bEnabled, BOOL bSunken); // draws button caption
void PaintRgn(CDC * pDC, CDC * pMemDC, CBitmap * pBitmap, COLORREF color,
CRect * pRect, BOOL bEnabled, BOOL bSunken); // paint button
friend class BuilderCtl;
friend class BuilderPcCtl;
};
class CUniCheckEx: public CUniBtnEx
{
public:
CUniCheckEx();
virtual ~CUniCheckEx();
void SetCheck(bool bSign);
bool GetCheck();
private:
virtual void DrawButton(CDC * pDC, CRect * pRect, UINT state); // 绘制按钮函数
bool m_bIsCheck;
};
//////////////////////////////////////////////////
// UniButton.cpp : implementation file
//
#include "stdafx.h"
#include "UniBtnEx.h"
#include "AFX.h"
#include "..//..//SdeFont//SdeFontEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const bool IS_WINDOWS_XP = false;
/////////////////////////////////////////////////////////////////////////////
// CUniBtnEx
void CUniBtnEx::DrawUserText(HDC* pHDC, COLORREF clrText)
{
CString text = L"";
GetWindowText(text);
//::SetTextColor(*hDC, clrText);
//::DrawText(*hDC,text,text.GetLength(),&m_rtText,m_nTextType);
CSdeFontEx::SetEvent(true);
CSdeFontEx::SetTextColor(clrText);
CSdeFontEx::SetFontSize(m_csText.cx,m_csText.cy);
CSdeFontEx::DrawText(pHDC,text,&m_rtText,m_nTextType);
CSdeFontEx::PrevFontSize();
CSdeFontEx::PrevTextColor();
CSdeFontEx::SetEvent(false);
}
CUniBtnEx::CUniBtnEx()
{
m_nColor = GetSysColor(COLOR_BTNFACE); // 取得系统颜色 -- 正常
m_sColor = m_nColor; // -- 被选择时颜色
m_hColor = m_nColor; // -- 鼠标在按钮上时颜色
m_dColor = m_nColor; // -- 被禁用时颜色
m_nBorder = 1;
m_pNormal = NULL;
m_pSelected = NULL;
m_pHover = NULL;
m_pDisabled = NULL;
m_hRgn = 0;
m_bHover = false;
m_bCapture = false;
m_bMouseDown = false;
m_iAutoCreate = 0;
}
CUniBtnEx::~CUniBtnEx()
{
if( m_iAutoCreate > 0)
{
delBmp();
}
m_pNormal = NULL;
m_pSelected = NULL;
m_pHover = NULL;
m_pDisabled = NULL;
DeleteObject(m_hRgn);
}
void CUniBtnEx::delBmp()
{
if( NULL != m_pNormal)
{
delete m_pNormal;
}
if( NULL != m_pSelected)
{
delete m_pSelected;
}
if( NULL != m_pHover)
{
delete m_pHover;
}
if( NULL != m_pDisabled)
{
delete m_pDisabled;
}
m_pNormal = NULL;
m_pSelected = NULL;
m_pHover = NULL;
m_pDisabled = NULL;
}
BEGIN_MESSAGE_MAP(CUniBtnEx, CButton)
//{{AFX_MSG_MAP(CUniBtnEx)
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
ON_WM_PAINT()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CUniBtnEx message handlers
BOOL CUniBtnEx::Create(LPCTSTR lpszCaption, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, DWORD dwStyle)
{
// store region in member variable
DeleteObject(m_hRgn);
m_hRgn = CreateRectRgn(0, 0, 31, 31);
CRect box(0, 0, 0, 0);
if (m_hRgn != 0)
CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
// make sure that region bounding rect is located in (0, 0)
GetRgnBox(m_hRgn, &box);
OffsetRgn(m_hRgn, -box.left, -box.top);
GetRgnBox(m_hRgn, &box);
// update position of region center for caption output
m_CenterPoint = CPoint(box.left + box.Width() /2 , box.top + box.Height() /2);
box.OffsetRect(point);
BOOL bRet = CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
SetTextColor(GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_BTNTEXT));
SetTextState(CPoint(0,0),CSize(20,20),DT_TEXT_CENTER|DT_TEXT_VCENTER);
return bRet;
}
BOOL CUniBtnEx::Create(const CPoint point, const HRGN hRgn,
CWnd* pParentWnd, UINT nID, UINT nBorder,
LPCTSTR lpszCaption,
COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor,
DWORD dwStyle)
{
// change default colors
delBmp();
m_nBorder = nBorder;
m_nColor = nColor;
m_sColor = sColor;
m_hColor = hColor;
m_dColor = dColor;
m_iAutoCreate = 1;
// call another constructor
return Create(lpszCaption, point, hRgn, pParentWnd, nID, dwStyle);
}
BOOL CUniBtnEx::Create(const CPoint point,
const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder,
LPCTSTR lpszCaption,
CBitmap* pNormal, CBitmap* pSelected, CBitmap* pOver, CBitmap* pDisabled,
DWORD dwStyle)
{
// change default colors
m_nBorder = nBorder;
m_pNormal = pNormal;
m_pSelected = pSelected;
m_pHover = pOver;
m_pDisabled = pDisabled;
m_iAutoCreate = 0;
// call another constructor
return Create(lpszCaption, point, hRgn, pParentWnd, nID, dwStyle);
}
// 修改为自绘属性
void CUniBtnEx::PreSubclassWindow()
{
// change window style to allow owner draw
ModifyStyle(0, BS_OWNERDRAW | BS_PUSHBUTTON);
CButton::PreSubclassWindow();
}
int CUniBtnEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CButton::OnCreate(lpCreateStruct) == -1)
return -1;
// assign new region to a window
SetWindowRgn(m_hRgn, true);
return 0;
}
void CUniBtnEx::OnLButtonDown(UINT nFlags, CPoint point)
{
// record that mouse is down
m_bMouseDown = true;
if (!m_bCapture)
{
SetCapture();
m_bCapture = true;
}
CButton::OnLButtonDown(nFlags, point);
}
void CUniBtnEx::OnLButtonUp(UINT nFlags, CPoint point)
{
// record that mouse is released
CButton::OnLButtonUp(nFlags, point);
m_bMouseDown = false;
if (m_bCapture)
{
ReleaseCapture();
m_bCapture = false;
}
//PC的鼠标移动是连续的, 故可进行检测。wince的触摸屏鼠标移动是离散的,故分情况进行检测。
const bool WINCE_MOUSE_MODE = true;
if( WINCE_MOUSE_MODE)
{
m_bHover = false;
RedrawWindow();
}
else
{
CheckHover(point);
}
}
// 鼠标移动
void CUniBtnEx::OnMouseMove(UINT nFlags, CPoint point)
{
// Test if mouse is above the button.
if (!m_bMouseDown)
CheckHover(point);
CButton::OnMouseMove(nFlags, point);
}
//
void CUniBtnEx::CheckHover(CPoint point)
{
if (HitTest(point))
{
if (!m_bCapture)
{
SetCapture();
m_bCapture = true;
}
if (!m_bHover)
{
m_bHover = true;
RedrawWindow();
}
}
else
{
if (m_bCapture)
{
ReleaseCapture();
m_bCapture = false;
}
m_bHover = false;
RedrawWindow();
}
}
LRESULT CUniBtnEx::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// I have noticed that default windows buttons can be clicked very quickly.
// Double or single click both result in a button being pushed down.
// For owner drawn buttons this is not the case. Double click does
// not push button down. Here is a solution for the problem:
// double click message is substituted for single click.
if (message == WM_LBUTTONDBLCLK)
message = WM_LBUTTONDOWN;
return CButton::DefWindowProc(message, wParam, lParam);
}
BOOL CUniBtnEx::HitTest(CPoint point)
{
BOOL result = false;
// Obtain handle to window region.
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
CRect rgnRect;
GetRgnBox(hRgn, &rgnRect);
// First check if point is in region bounding rect.
// Then check if point is in the region in adition to being in the bouding rect.
result = PtInRect(&rgnRect, point) && PtInRegion(hRgn, point.x, point.y);
// Clean up and exit.
DeleteObject(hRgn);
return result;
}
// 不擦除背景
BOOL CUniBtnEx::OnEraseBkgnd(CDC* pDC)
{
// do not erase background
return TRUE;
}
//////////////////////// DRAWING ROUTINES ////////////////////////////
// 绘制函数
void CUniBtnEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// prepare DC
CDC* pDC = CDC::FromHandle(lpDrawItemStruct -> hDC);
CRect rect;
GetClientRect(rect);
// prepare bitmaps they need to be prepared
if (1 == m_iAutoCreate)
PrepareStateBitmaps(pDC, &rect);
// draw button to the screen
DrawButton(pDC, &rect, lpDrawItemStruct -> itemState);
}
// 准备位图
void CUniBtnEx::PrepareStateBitmaps(CDC * pDC, CRect * pRect)
{
// prepare memory DC
CDC * pMemDC;
pMemDC = new CDC;
pMemDC -> CreateCompatibleDC(pDC);
// prepare bitmaps for all button states and for the mask
PrepareNormalState(pDC, pMemDC, pRect);
PrepareSelectedState(pDC, pMemDC, pRect);
PrepareHoverState(pDC, pMemDC, pRect);
PrepareDisabledState(pDC, pMemDC, pRect);
// clean up
delete pMemDC;
m_iAutoCreate++;
}
// 正常按钮状态
void CUniBtnEx::PrepareNormalState(CDC * pDC, CDC * pMemDC, CRect * pRect)
{
// prepare MYBS_NORMAL state bitmap
delete m_pNormal;
m_pNormal = new CBitmap;
PaintRgn(pDC, pMemDC, m_pNormal, m_nColor, pRect, true, false);
}
// 被选择状态
void CUniBtnEx::PrepareSelectedState(CDC * pDC, CDC * pMemDC, CRect * pRect)
{
// prepare MYBS_SELECTED state bitmap
delete m_pSelected;
m_pSelected = new CBitmap;
PaintRgn(pDC, pMemDC, m_pSelected, m_sColor, pRect, true, true);
}
// 鼠标在按钮上的状态
void CUniBtnEx::PrepareHoverState(CDC * pDC, CDC * pMemDC, CRect * pRect)
{
// prepare MYBS_HOVER state bitmap
delete m_pHover;
m_pHover = new CBitmap;
PaintRgn(pDC, pMemDC, m_pHover, m_hColor, pRect, true, false);
}
// 按钮禁用状态
void CUniBtnEx::PrepareDisabledState(CDC * pDC, CDC * pMemDC, CRect * pRect)
{
// prepare MYBS_DISABLED state bitmap
delete m_pDisabled;
m_pDisabled = new CBitmap;
PaintRgn(pDC, pMemDC, m_pDisabled, m_dColor, pRect, false, false);
}
// 根据区域绘制形状
void CUniBtnEx::PaintRgn(CDC * pDC, CDC * pMemDC, CBitmap * pBitmap, COLORREF color, CRect * pRect, BOOL bEnabled, BOOL bSunken)
{
// create bitmap
pBitmap -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
CBitmap * pOldBitmap = pMemDC -> SelectObject(pBitmap);
// prepare region
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// fill rect a with transparent color and fill rgn
HBRUSH hBrush = CreateSolidBrush(color);
pMemDC -> FillSolidRect(pRect, RGB(0, 0, 0));
FillRgn(pMemDC -> GetSafeHdc(), hRgn, hBrush);
DeleteObject(hBrush);
// draw 3D border and text
DrawButtonCaption(pMemDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
if( m_nBorder > 0)
{
FrameRgn3D(pMemDC -> GetSafeHdc(), hRgn, bSunken);
}
// clean up
DeleteObject(hRgn);
pMemDC -> SelectObject(pOldBitmap);
}
// 绘制按钮标题
void CUniBtnEx::DrawButtonCaption(HDC hDC, CRect * pRect, BOOL bEnabled, BOOL bSunken)
{
// select parent font
int nOldMode = SetBkMode(hDC, TRANSPARENT);
LOGFONT lf;
GetParent() -> GetFont() -> GetLogFont(&lf);
HFONT hFont = CreateFontIndirect(&lf);
HFONT hOldFont = (HFONT) SelectObject(hDC, hFont);
// determine point where to output text
TEXTMETRIC tm;
GetTextMetrics(hDC, &tm);
CPoint p = CPoint(m_CenterPoint.x, m_CenterPoint.y + tm.tmHeight/ 2);
if (bSunken)
p.Offset(m_nBorder, m_nBorder);
// draw button caption depending upon button state
if (bEnabled)
{
SetTextAlign(hDC, TA_CENTER | TA_BOTTOM);
DrawUserText(&hDC, m_dTextColor);
}
else
{
if( bSunken)
{
DrawUserText(&hDC, m_sTextColor);
}
else
{
DrawUserText(&hDC, m_nTextColor);
}
}
SelectObject(hDC, hOldFont);
DeleteObject(hFont);
SetBkMode(hDC, nOldMode);
}
// 3D效果
void CUniBtnEx::FrameRgn3D(HDC hDC, const HRGN hRgn, BOOL bSunken)
{
// we need two differenr regions to keep base region and border region
HBRUSH hBrush;
HRGN hBaseRgn = CreateRectRgn(0, 0, 0, 0);
COLORREF ltOuter, ltInner, rbOuter, rbInner; // colors of inner and outer shadow for top-left and right-bottom corners
// decide on color scheme
if (!bSunken)
{
ltOuter = GetSysColor(COLOR_3DLIGHT);
ltInner = GetSysColor(COLOR_3DHILIGHT);
rbOuter = GetSysColor(COLOR_3DDKSHADOW);
rbInner = GetSysColor(COLOR_3DSHADOW);
}
else
{
rbInner = GetSysColor(COLOR_3DLIGHT);
rbOuter = GetSysColor(COLOR_3DHILIGHT);
ltInner = GetSysColor(COLOR_3DDKSHADOW);
ltOuter = GetSysColor(COLOR_3DSHADOW);
}
// offset highlight and shadow regions
// substract them from the base region
switch (m_nBorder)
{
case 2:
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 2, 2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -2, -2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 1, 1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -1, -1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
break;
default:
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 1, 1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -1, -1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
break;
}
// clean up regions
DeleteObject(hBaseRgn);
}
void CUniBtnEx::DrawButton(CDC * pDC, CRect * pRect, UINT state)
{
// create memory DC
CDC * pMemDC = new CDC;
pMemDC -> CreateCompatibleDC(pDC);
CBitmap * pOldBitmap;
// select bitmap to paint depending upon button state
BOOL bEnabled = FALSE;
BOOL bSunken = FALSE;
if (state & ODS_DISABLED)
{
TRACE(_T("DrawButton DISABLED!/n"));
if( NULL != m_pDisabled)
pOldBitmap = pMemDC -> SelectObject(m_pDisabled);
else
pOldBitmap = pMemDC -> SelectObject(m_pNormal);
bEnabled = TRUE;
}
else
{
if (state & ODS_SELECTED)
{
TRACE(_T("DrawButton SELECTED!/n"));
if( NULL != m_pSelected)
pOldBitmap = pMemDC -> SelectObject(m_pSelected);
bSunken = TRUE;
}
else
{
if (m_bHover)
{
TRACE(_T("DrawButton Over!/n"));
if( NULL != m_pHover)
pOldBitmap = pMemDC -> SelectObject(m_pHover);
else if( NULL != m_pNormal)
pOldBitmap = pMemDC -> SelectObject(m_pNormal);
}
else
{
TRACE(_T("DrawButton Normal!/n"));
pOldBitmap = pMemDC -> SelectObject(m_pNormal);
}
}
}
if( IS_WINDOWS_XP)
{
// get region
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// paint using region for clipping
::SelectClipRgn(pDC -> GetSafeHdc(), hRgn);
pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
::SelectClipRgn(pDC -> GetSafeHdc(), NULL);
//clean up
DeleteObject(hRgn);
}
else
{
pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
}
if (0 == m_iAutoCreate)
DrawButtonCaption(pDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
pMemDC -> SelectObject(pOldBitmap);
delete pMemDC;
}
void CUniBtnEx::RgnPixelWork(CDC * pDC, CRgn * pRgn)
{
// get size of data composing region
int size = pRgn -> GetRegionData(NULL, 0);
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
RGNDATA * pData = (RGNDATA *)GlobalLock(hData);
// retrieve region data
int res = pRgn -> GetRegionData(pData, size);
RECT * pRect = (RECT *) pData -> Buffer;
// now we know how region is represented and we are able to manipulate it as we like
for (DWORD i = 0; i < pData -> rdh.nCount; i++) {
RECT rect = *(pRect + i);
for (int x = rect.left; x < rect.right; x++)
for (int y = rect.top; y < rect.bottom; y++) {
// use SetPixel(x, y, color) to do pixel work
}
}
// free region data
GlobalUnlock(hData);
GlobalFree(hData);
}
void CUniBtnEx::OnPaint()
{
//CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CButton::OnPaint() for painting messages
if( IS_WINDOWS_XP)
{
CButton::OnPaint();
}
else
{
CRect rect;
GetClientRect(rect);
CPaintDC dc(this);
DrawButton(&dc,&rect,ODS_FOCUS);
}
}
void CUniBtnEx::SetTextColor(COLORREF nTextColor, COLORREF sTextColor, COLORREF dTextColor)
{
m_nTextColor = nTextColor;
m_sTextColor = sTextColor;
m_dTextColor = dTextColor;
}
void CUniBtnEx::SetTextState(CPoint ptStart, CSize csText, UINT nTextType)
{
CRect rtClient;
GetClientRect(rtClient);
m_rtText.CopyRect(&CRect(ptStart.x,ptStart.y,rtClient.Width(),rtClient.Height()));
m_csText = csText;
m_nTextType = nTextType;
}
//-----------------------------------------------------------------------------
CUniCheckEx::CUniCheckEx(){ m_bIsCheck = false; }
CUniCheckEx::~CUniCheckEx(){ NULL; }
void CUniCheckEx::SetCheck(bool bSign)
{
m_bIsCheck = bSign;
Invalidate();
}
bool CUniCheckEx::GetCheck() { return m_bIsCheck; }
void CUniCheckEx::DrawButton(CDC * pDC, CRect * pRect, UINT state)
{
CDC * pMemDC = new CDC;
pMemDC -> CreateCompatibleDC(pDC);
CBitmap * pOldBitmap;
// select bitmap to paint depending upon button state
BOOL bEnabled = FALSE;
BOOL bSunken = FALSE;
if (state & ODS_DISABLED)
{
TRACE(_T("DrawButton DISABLED!/n"));
if( NULL != m_pDisabled)
pOldBitmap = pMemDC -> SelectObject(m_pDisabled);
else
pOldBitmap = pMemDC -> SelectObject(m_pNormal);
bEnabled = TRUE;
}
else
{
if (state & ODS_SELECTED)
{
TRACE(_T("DrawButton SELECTED!/n"));
if( m_bIsCheck)
m_bIsCheck = false;
else
m_bIsCheck = true;
}
if( !m_bIsCheck)
{
pOldBitmap = pMemDC -> SelectObject(m_pNormal);
}
else
{
pOldBitmap = pMemDC -> SelectObject(m_pSelected);
bSunken = TRUE;
}
}
if( IS_WINDOWS_XP)
{
// get region
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// paint using region for clipping
::SelectClipRgn(pDC -> GetSafeHdc(), hRgn);
pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
::SelectClipRgn(pDC -> GetSafeHdc(), NULL);
//clean up
DeleteObject(hRgn);
}
else
{
pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
}
if (0 == m_iAutoCreate)
DrawButtonCaption(pDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
pMemDC -> SelectObject(pOldBitmap);
delete pMemDC;
}