
在 MFC 中实现一个星星形状的按钮,通常需要自定义按钮控件(CButton 或其派生类),并使用 自绘(Owner Draw) 或 位图按钮(CBitmapButton) 的方式来实现。以下是几种实现方法:
在 Visual Studio 中,右键项目 -> 添加类 -> MFC 类,选择基类 CButton,命名为 CStarButton。
在类声明中,添加 DrawItem 方法(用于自绘):
class CStarButton : public CButton
{
public:
DECLARE_DYNAMIC(CStarButton)
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};DrawItem 方法在 .cpp 文件中,实现 DrawItem 方法,绘制星星形状:
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);
}在资源编辑器中添加一个按钮,设置其属性:
True在对话框类中关联变量:
CStarButton m_btnStar;在 OnInitDialog 中关联控件:
m_btnStar.SubclassDlgItem(IDC_BUTTON_STAR, this);CBitmapButton(位图按钮)如果希望按钮有不同状态(正常、悬停、按下),可以使用 CBitmapButton。
准备 4 张位图(.bmp 文件),分别对应:
star_normal.bmp)star_pressed.bmp)star_hover.bmp)star_disabled.bmp)在对话框类的 .h 文件中声明:
CBitmapButton m_btnStar;在 OnInitDialog 中加载位图:
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(); // 自动调整按钮大小True。如果需要更平滑的星星,可以使用 GDI+(需链接 gdiplus.lib):
#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。这样,你就可以在 MFC 中实现一个星星按钮了!🌟