送分!分享圆角按钮

xladykiller 2010-08-13 04:28:57
方案:
重写虚函数DrawItem
先创一个圆角矩型CreateRoundRectRgn.
然后把按钮区域设置在刚建的圆角矩型区域内SetWindowRgn.
最后把按钮画出来RoundRect.
其中,
函数 SetWindowRgn(),可以将绘画和鼠标消息限定在窗口的一个指定的区域,可以是CreateRectRgn(),CreatePolyRgn(),CreatePolygonRgn(),CreateRoundRectRgn()和 CreateEllipticRgn(),等.
#pragma once


// CCustomButton

class CCustomButton : public CButton
{
DECLARE_DYNAMIC(CCustomButton)

public:
CCustomButton();
virtual ~CCustomButton();

protected:
DECLARE_MESSAGE_MAP()
public:
// afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
BOOL m_IsPressed;//鼠标是否按下
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
CBrush m_Brush;
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};

CCustomButton::CCustomButton()
{
m_IsPressed = FALSE;
}

重写虚函数
void CCustomButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

// TODO: 添加您的代码以绘制指定项
CRect rect;
//GetClientRect(&rect);
//得到原先按扭区域
rect = lpDrawItemStruct->rcItem;
CDC dc;
//连接到设备环境,(我喜欢称设备上下文为设备环境)
dc.Attach(lpDrawItemStruct->hDC);

m_Brush.CreateStockObject(NULL_BRUSH);
dc.SelectObject(&m_Brush);
if(m_IsPressed)//鼠标按下
{
CPen pen(PS_SOLID,2,RGB(255,100,0));
//选择画笔
dc.SelectObject(&pen);
//创建圆角矩型
HRGN h_rgn = CreateRoundRectRgn(0,0,rect.right,rect.bottom,rect.Width()/2,rect.Height());
//设置按钮区域
SetWindowRgn(h_rgn,TRUE);
//圆出按钮
dc.RoundRect(0,0,rect.right,rect.bottom,rect.Width()/2,rect.Height());
dc.SetTextColor(RGB(255,100,0));
}
else//鼠标没有按下
{
CPen pen(PS_SOLID,2,RGB(198,198,198));
dc.SelectObject(&pen);
HRGN h_rgn = CreateRoundRectRgn(0,0,rect.right,rect.bottom,rect.Width()/2,rect.Height());
SetWindowRgn(h_rgn,TRUE);
dc.RoundRect(0,0,rect.right,rect.bottom,rect.Width()/2,rect.Height());
dc.SetTextColor(RGB(255,100,0));
}

CString str;
GetWindowText(str);
//写上文本
dc.DrawText(str,rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
删除设备环境
dc.DeleteDC();

}

响应鼠标

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

CButton::OnLButtonUp(nFlags, point);
}

BOOL CCustomButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值


return CButton::OnEraseBkgnd(pDC);
}

这里要注意的地方就是DrawItem是虚函数,而不是消息OnDrawItem.
另外要将OwnerDraw设为true;
...全文
1544 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
aidelong 2012-12-21
  • 打赏
  • 举报
回复
借鉴学习,谢谢!
niulei 2012-12-17
  • 打赏
  • 举报
回复
学习了,谢谢!
kkk925 2012-11-25
  • 打赏
  • 举报
回复
顶, 学习了
痴才 2012-10-16
  • 打赏
  • 举报
回复
ding
BIN_WX 2012-06-22
  • 打赏
  • 举报
回复
学习一下~~~
布心 2012-05-05
  • 打赏
  • 举报
回复
学习了 但是我现在还是不会弄
jinkun890210 2011-11-03
  • 打赏
  • 举报
回复
学习了
gnuljf 2011-06-12
  • 打赏
  • 举报
回复
学习了。
jilianglijie 2011-03-21
  • 打赏
  • 举报
回复
悲剧啊 我用API竟然做不出来...
hywangyc 2011-03-20
  • 打赏
  • 举报
回复
找了半天,终于找到一个有用的了!
deiniyiqiannian 2010-10-10
  • 打赏
  • 举报
回复
哈哈,太感谢了。
我在做一个和楼主的圆角矩形差不多的东西,就是一个传一个point数组,然后可以生成一个多边形的static,然后还要在这个多边形区域响应mousemove。
开始我将 SetWindowRgn(h_rgn,TRUE)这一句放在了PreSubclassWindow()里,然后重载DrawItem,这样外形显示出来没问题,可是在响应消息时出问题了,在这个多边形的外部某些区域也会响应消息 ,在多边形的某些区域却不会响应。。。陷了我两天啊,这个小问题
刚刚看到LZ将SetWindowRgn直接放在DrawItem里。。。试下,哇,成功!消息不会再乱响应了!楼主能帮分析一下原因么?
多谢。。。哈哈
deiniyiqiannian 2010-10-10
  • 打赏
  • 举报
回复
问题解决了没???楼主。。
gamer243 2010-09-14
  • 打赏
  • 举报
回复
mark
sdytdhl 2010-09-03
  • 打赏
  • 举报
回复
mark
公子九 2010-09-02
  • 打赏
  • 举报
回复
学习,谢谢
gavinma 2010-08-18
  • 打赏
  • 举报
回复
为了河蟹社会进来看一眼
jhayumu 2010-08-15
  • 打赏
  • 举报
回复
接点分也不错
猴头 2010-08-13
  • 打赏
  • 举报
回复
楼主好人
ctwoz 2010-08-13
  • 打赏
  • 举报
回复
学习…
无幻 2010-08-13
  • 打赏
  • 举报
回复
那也给我点分吧 哈哈
加载更多回复(18)

1,650

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 非技术类
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧