自绘按纽

来源:互联网 发布:人工智能 专项资金 编辑:程序博客网 时间:2024/05/17 04:22

#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;
}

原创粉丝点击