我们继续来了解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; }