首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【MFC 突然被问到,怎么实现一个星星按钮】原来问的是继承xs

【MFC 突然被问到,怎么实现一个星星按钮】原来问的是继承xs

作者头像
flos chen
发布2026-01-23 17:12:35
发布2026-01-23 17:12:35
990
举报

在 MFC 中实现一个星星形状的按钮,通常需要自定义按钮控件(CButton 或其派生类),并使用 自绘(Owner Draw)位图按钮(CBitmapButton) 的方式来实现。以下是几种实现方法:


方法 1:使用自绘按钮(Owner Draw Button)

步骤 1:创建自定义按钮类

在 Visual Studio 中,右键项目 -> 添加类 -> MFC 类,选择基类 CButton,命名为 CStarButton

在类声明中,添加 DrawItem 方法(用于自绘):

代码语言:javascript
复制
class CStarButton : public CButton
{
public:
    DECLARE_DYNAMIC(CStarButton)
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
步骤 2:实现 DrawItem 方法

.cpp 文件中,实现 DrawItem 方法,绘制星星形状:

代码语言:javascript
复制
void CStarButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect = lpDrawItemStruct->rcItem;

    // 1. 绘制背景(可选)
    pDC->FillSolidRect(rect, RGB(255, 255, 255)); // 白色背景

    // 2. 绘制星星(使用多边形)
    POINT starPoints[10] = {
        {rect.left + 50, rect.top + 0},    // 顶点
        {rect.left + 60, rect.top + 40},   // 右上角
        {rect.left + 100, rect.top + 40},  // 右下角
        {rect.left + 65, rect.top + 65},   // 中间右
        {rect.left + 75, rect.top + 100},  // 底部
        {rect.left + 50, rect.top + 80},   // 中间左
        {rect.left + 25, rect.top + 100}, // 底部左
        {rect.left + 35, rect.top + 65},   // 中间左
        {rect.left + 0, rect.top + 40},    // 左上角
        {rect.left + 40, rect.top + 40}    // 右上角
    };

    // 3. 填充星星
    CBrush brush(RGB(255, 215, 0)); // 金色
    CBrush* pOldBrush = pDC->SelectObject(&brush);
    pDC->Polygon(starPoints, 10);
    pDC->SelectObject(pOldBrush);
}
步骤 3:在对话框中使用自定义按钮

在资源编辑器中添加一个按钮,设置其属性:

  • Owner Draw = True

在对话框类中关联变量:

代码语言:javascript
复制
CStarButton m_btnStar;

OnInitDialog 中关联控件:

代码语言:javascript
复制
m_btnStar.SubclassDlgItem(IDC_BUTTON_STAR, this);

方法 2:使用 CBitmapButton(位图按钮)

如果希望按钮有不同状态(正常、悬停、按下),可以使用 CBitmapButton

步骤 1:准备星星图片

准备 4 张位图(.bmp 文件),分别对应:

  • 正常状态star_normal.bmp
  • 按下状态star_pressed.bmp
  • 悬停状态star_hover.bmp
  • 禁用状态star_disabled.bmp
步骤 2:加载位图

在对话框类的 .h 文件中声明:

代码语言:javascript
复制
CBitmapButton m_btnStar;

OnInitDialog 中加载位图:

代码语言:javascript
复制
m_btnStar.LoadBitmaps(
    IDB_STAR_NORMAL,    // 正常状态
    IDB_STAR_PRESSED,   // 按下状态
    IDB_STAR_HOVER,     // 悬停状态(可选)
    IDB_STAR_DISABLED   // 禁用状态(可选)
);
m_btnStar.SubclassDlgItem(IDC_BUTTON_STAR, this);
m_btnStar.SizeToContent(); // 自动调整按钮大小
步骤 3:在资源编辑器中设置按钮
  • 设置按钮的 Owner Draw 属性为 True

方法 3:使用 GDI+ 绘制更复杂的星星

如果需要更平滑的星星,可以使用 GDI+(需链接 gdiplus.lib):

代码语言:javascript
复制
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

void CStarButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    using namespace Gdiplus;
    Graphics graphics(lpDrawItemStruct->hDC);
    SolidBrush brush(Color(255, 215, 0)); // 金色

    PointF points[10] = {
        PointF(50, 0), PointF(60, 40), PointF(100, 40),
        PointF(65, 65), PointF(75, 100), PointF(50, 80),
        PointF(25, 100), PointF(35, 65), PointF(0, 40),
        PointF(40, 40)
    };

    graphics.FillPolygon(&brush, points, 10);
}

总结

方法

适用场景

优点

缺点

自绘按钮 (DrawItem)

简单星星形状

纯代码控制,无需图片

需要手动计算坐标

位图按钮 (CBitmapButton)

带不同状态的按钮

视觉效果更好

需要准备多张图片

GDI+ 绘制

复杂平滑图形

抗锯齿效果更好

需要额外依赖

推荐:

  • 如果只是简单星星,用 自绘按钮
  • 如果需要不同状态效果,用 CBitmapButton
  • 如果需要高质量图形,用 GDI+

这样,你就可以在 MFC 中实现一个星星按钮了!🌟

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 方法 1:使用自绘按钮(Owner Draw Button)
    • 步骤 1:创建自定义按钮类
    • 步骤 2:实现 DrawItem 方法
    • 步骤 3:在对话框中使用自定义按钮
  • 方法 2:使用 CBitmapButton(位图按钮)
    • 步骤 1:准备星星图片
    • 步骤 2:加载位图
    • 步骤 3:在资源编辑器中设置按钮
  • 方法 3:使用 GDI+ 绘制更复杂的星星
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档