MFC基本控件3-Button的风格

简介: 我们继续来了解MFC控件的基本使用, 按钮的使用大家肯定都很熟悉了, 我们今天来了解一下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;
}




目录
打赏
0
0
0
0
0
分享
相关文章
快速上手阿里云RDS MySQL实例创建,轻松管理数据库
快速上手阿里云RDS MySQL实例创建,轻松管理数据库 在数字化时代,数据已成为企业的核心资产。如何高效、安全地存储和管理这些数据,成为企业在云计算时代亟待解决的问题。阿里云的RDS(关系型数据库服务)应运而生,为用户提供稳定、可靠的云上数据库解决方案。本文将详细介绍如何通过阿里云RDS管理控制台快速创建RDS MySQL实例,让您轻松上手,快速部署数据库。
649 2
C#数据类型之枚举类型
C#数据类型之枚举类型
387 0
|
11月前
MFC基本控件2-单选按钮的使用
MFC基本控件2-单选按钮的使用
实战.NET Framework 迁移到 .NET 5/6
从.NET Framework 迁移到.NET 5/6 是一次重要的技术革新,涵盖开发环境与应用架构的全面升级。本文通过具体案例详细解析迁移流程,包括评估现有应用、利用.NET Portability Analyzer 工具识别可移植代码、创建新项目、逐步迁移代码及处理依赖项更新等关键步骤。特别关注命名空间调整、JSON 序列化工具更换及数据库访问层重构等内容,旨在帮助开发者掌握最佳实践,确保迁移过程平稳高效,同时提升应用性能与可维护性。
295 2
在K8S中,Pod中关于资源有request和limit两个字段?这么设计的原因是什么?
在K8S中,Pod中关于资源有request和limit两个字段?这么设计的原因是什么?
自动化办公:AI如何改变工作方式
【7月更文第19天】随着人工智能技术的飞速发展,我们的工作方式正经历着前所未有的转型。从繁琐的文档处理到高效的会议安排,再到个性化的邮件回复,AI正逐步成为现代办公不可或缺的一部分。本文将深入探讨AI如何在这些核心办公场景中发挥作用,提升工作效率,优化工作流程,从而推动工作方式的全面革新。
1060 3
【深度解析】超越RMSE和MSE:揭秘更多机器学习模型性能指标,助你成为数据分析高手!
【8月更文挑战第17天】本文探讨机器学习模型评估中的关键性能指标。从均方误差(MSE)和均方根误差(RMSE)入手,这两种指标对较大预测偏差敏感,适用于回归任务。通过示例代码展示如何计算这些指标及其它如平均绝对误差(MAE)和决定系数(R²)。此外,文章还介绍了分类任务中的准确率、精确率、召回率和F1分数,并通过实例说明这些指标的计算方法。最后,强调根据应用场景选择合适的性能指标的重要性。
1186 0
MFC控件介绍(三)
MFC控件介绍(三)
169 0
MFC添加年月日时分秒控件
MFC添加年月日时分秒控件
204 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等