MFC基本控件3-Button的风格

        我们继续来了解MFC控件的基本使用, 按钮的使用大家肯定都很熟悉了, 我们今天来了解一下Button按钮的功能扩展怎么实现。

我们来看头文件代码:

#pragma once


// CMyButton

class CMyButton : public CButton
{
	DECLARE_DYNAMIC(CMyButton)

public:
	CMyButton();
	virtual ~CMyButton();

	CFont	m_fontMouseMove;	//鼠标移动到按钮上时用的字体
	HCURSOR	m_hCurSorMouseMove;	//鼠标移动到按钮上时用的光标
	BOOL	m_isLButtonDown;	//鼠标左键是否按下
	BOOL	m_isMouseInButton;	//鼠标是否在按钮上面

protected:
	DECLARE_MESSAGE_MAP()
public:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);//绘制控件消息
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//左键按下消息
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);//左键抬起消息
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);//鼠标移动
	afx_msg void OnTimer(UINT_PTR nIDEvent);//计时器
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);//设置光标
};

下面是函数实现:

// CMyButton.cpp: 实现文件
//

#include "pch.h"
#include "class08.h"
#include "CMyButton.h"


// CMyButton

IMPLEMENT_DYNAMIC(CMyButton, CButton)

CMyButton::CMyButton()
{

}

CMyButton::~CMyButton()
{
}


BEGIN_MESSAGE_MAP(CMyButton, CButton)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_SETCURSOR()
END_MESSAGE_MAP()



// CMyButton 消息处理程序




void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	//整个按钮的外观都是在这里进行绘制
	CDC* pDc = CDC::FromHandle(lpDrawItemStruct->hDC);//获取dc
	CRect rect(lpDrawItemStruct->rcItem);//按钮的rect结构

	pDc->SetBkMode(TRANSPARENT);

	UINT buttonState = lpDrawItemStruct->itemState;//获取按钮状态
	CFont* pOldFont = NULL;
	CString strText;
	GetWindowText(strText);

	if (m_isMouseInButton)
	{
		if (buttonState & ODS_SELECTED)//判断有没有点击按钮
		{
			pDc->Draw3dRect(rect,//指定范围内的矩形
				GetSysColor(COLOR_3DSHADOW),//三维矩形的顶部和左侧的颜色
				GetSysColor(COLOR_3DHILIGHT)//三维矩形的底部和右侧的颜色
			);
		}
		else
			pDc->Draw3dRect(rect, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));

		pDc->SetTextColor(RGB(255, 0, 0));

		if (m_fontMouseMove.GetSafeHandle() == NULL)
		{
			CFont* font = GetFont();
			LOGFONT lf;
			font->GetLogFont(&lf);
			lf.lfUnderline = true;
			m_fontMouseMove.CreateFontIndirect(&lf);
		}
		pOldFont = pDc->SelectObject(&m_fontMouseMove);
	}
	else
	{
		pDc->SetTextColor(RGB(0, 0, 0));
	}
	pDc->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

	if (pOldFont)
		pDc->SelectObject(pOldFont);


	// TODO:  添加您的代码以绘制指定项
}


void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_isLButtonDown = true;
	CButton::OnLButtonDown(nFlags, point);
}


void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	m_isLButtonDown = false;
	if (m_isMouseInButton)
	{
		m_isMouseInButton = false;
		InvalidateRect(NULL);//整个按钮的区域无效
	}

	CButton::OnLButtonUp(nFlags, point);
}


void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	SetTimer(1, 10, NULL);
	CButton::OnMouseMove(nFlags, point);
}


void CMyButton::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	static BOOL bPainted = false;	//防止重绘用的

	POINT pt;
	GetCursorPos(&pt);//获取鼠标关于屏幕的位置

	CRect rect;
	GetWindowRect(&rect);//获得CWnd的屏幕坐标

	if (m_isLButtonDown)
	{
		KillTimer(1);
		return;
	}

	if (!rect.PtInRect(pt))//判断光标的坐标在不在按钮的矩形区域内
	{
		m_isMouseInButton = false;
		KillTimer(1);
		if (bPainted)
			InvalidateRect(NULL);
		bPainted = false;
		return;
	}
	else
	{
		m_isMouseInButton = true;
		if (!bPainted)
		{
			bPainted = true;
			InvalidateRect(NULL);
		}
	}

	CButton::OnTimer(nIDEvent);
}


BOOL CMyButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if (m_isMouseInButton)
	{
		::SetCursor(::LoadCursorFromFile(_T("res\\CURSOR1.CUR")));
	}

	//return CButton::OnSetCursor(pWnd, nHitTest, message);//需要注释掉
	return true;
}

猜你喜欢

转载自blog.csdn.net/H520xcodenodev/article/details/126320308
今日推荐