⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unibutton.cpp

📁 码头手持机项目,用于统计集装箱,轮船的情况,手持机采用S3C2440处理器,数据传输采用2.4G无线,上位机用VC编写
💻 CPP
字号:
// UniButton.cpp : implementation file
//

#include "stdafx.h"
#include "UniButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CUniButton

CUniButton::CUniButton()
{
	m_nColor = GetSysColor(COLOR_BTNFACE);		// 取得系统颜色 -- 正常
	m_sColor = m_nColor;						// -- 被选择时颜色
	m_hColor = m_nColor;						// -- 鼠标在按钮上时颜色
	m_dColor = m_nColor;						// -- 被禁用时颜色
	m_nBorder = 4;
	m_pNormal = NULL;
	m_hRgn = 0;
	m_bHover = false;
	m_bTracking = FALSE;
	bSunken =false;
	m_bCapture =false;
}

CUniButton::~CUniButton()
{
	delete m_pNormal;
	DeleteObject(m_hRgn);
}

BEGIN_MESSAGE_MAP(CUniButton, CButton)
	//{{AFX_MSG_MAP(CUniButton)
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder, COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor)
{
	m_nBorder = nBorder;
	m_nColor = nColor;
	m_sColor = sColor;
	m_hColor = hColor;
	m_dColor = dColor;

	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);

	return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
}

// 修改为自绘属性
void CUniButton::PreSubclassWindow() 
{
	// change window style to allow owner draw
	ModifyStyle(0, BS_OWNERDRAW | BS_PUSHBUTTON);	
				m_Font.CreateFont(
		18,                        // nHeight
		0,                         // nWidth
		0,                         // nEscapement
		0,                         // nOrientation
		FW_BOLD,                 // nWeight
		FALSE,                     // bItalic
		FALSE,                     // bUnderline
		0,                         // cStrikeOut
		ANSI_CHARSET,              // nCharSet
		OUT_DEFAULT_PRECIS,        // nOutPrecision
		CLIP_DEFAULT_PRECIS,       // nClipPrecision
		DEFAULT_QUALITY,           // nQuality
		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
		_T("新宋体"));                 // lpszFacename

	CButton::PreSubclassWindow();
}

int CUniButton::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CButton::OnCreate(lpCreateStruct) == -1)
		return -1;
	SetWindowRgn(m_hRgn, true);

	return 0;
}

// 鼠标移动
void CUniButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (HitTest(point))
	{
		if (!m_bCapture) 
		{
			SetCapture();
			m_bCapture = true;
		}
		if (!m_bHover) 
		{
			m_bHover = true;
			InvalidateRect(NULL);
		}
	}
	else
	{
		if (m_bCapture) 
		{
			ReleaseCapture();
			m_bCapture = false;
		}
		m_bHover = false;
		InvalidateRect(NULL);
	}
	CButton::OnMouseMove(nFlags, point);
}

// 不擦除背景
BOOL CUniButton::OnEraseBkgnd(CDC* pDC) 
{
	// do not erase background
	return 1;
}

//////////////////////// DRAWING ROUTINES ////////////////////////////

// 绘制函数
void CUniButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	// prepare DC
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct -> hDC);
	CRect rect1;
	GetClientRect(rect1);
    CRect* pRect;
	pRect=&rect1;
	CDC * pMemDC;
	pMemDC = new CDC;
	pMemDC -> CreateCompatibleDC(pDC);

    UINT state = lpDrawItemStruct->itemState;

	COLORREF color;
	if (m_bHover)
        color = m_hColor;
	else
        color = m_nColor;
	if (state & ODS_FOCUS)
	{
		bSunken=false;
        color = m_sColor;
	}
	if (state & ODS_SELECTED)
	{
		bSunken=true;
	}
	delete m_pNormal;
	m_pNormal = new CBitmap;
	m_pNormal -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
    pMemDC -> SelectObject(m_pNormal); 

	// 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);
	FrameRgn3D(pMemDC -> GetSafeHdc(), hRgn, bSunken);
	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);
	DeleteObject(hRgn);
	CString m_btntext;
	GetWindowText(m_btntext);
	if (m_btntext!="")
	{
	    if (bSunken) 
		    rect1.OffsetRect(-m_nBorder,-m_nBorder); 
        pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(RGB(0,0,0));
	    pDC->SelectObject(&m_Font);
        pDC->DrawText(m_btntext,&rect1,DT_VCENTER | DT_CENTER | DT_SINGLELINE);
	}
	delete pMemDC;
}

// 3D效果
void CUniButton::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);
	}

		CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
		OffsetRgn(hBaseRgn, 4, 4);
		CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
		hBrush = CreateSolidBrush(ltInner);
		FillRgn(hDC, hBaseRgn, hBrush);
		DeleteObject(hBrush);

		CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
		OffsetRgn(hBaseRgn, -4, -4);
		CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
		hBrush = CreateSolidBrush(rbInner);
		FillRgn(hDC, hBaseRgn, hBrush);
		DeleteObject(hBrush);

		CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
		OffsetRgn(hBaseRgn, 2, 2);
		CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
		hBrush = CreateSolidBrush(ltOuter);
		FillRgn(hDC, hBaseRgn, hBrush);
		DeleteObject(hBrush);

		CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
		OffsetRgn(hBaseRgn, -2, -2);
		CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
		hBrush = CreateSolidBrush(rbOuter);
		FillRgn(hDC, hBaseRgn, hBrush);
		DeleteObject(hBrush);
	
	// clean up regions
	DeleteObject(hBaseRgn);
}

BOOL CUniButton::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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -