自己动手做按钮

 

自己动手做按钮

作者:风林

现在网上发布的自制按钮很多,实际上其制作方法都很类似,以下给出几个关键步骤,具体细节你大可以发挥你的想象力,制作出你想要的各种按钮。

一、用ClassWizard生成一个新类,名字假设起为CMyButton,基类选为CButton;

二、在新类中用ClassWizard添加函数:PreSubclassWindow()、DrawItem()、OnMouseMove()、OnLButtonDown()、OnLButtonUp();

① PreSubclassWindow()函数在绘制按钮前执行,在这里我只做了一个工作:
void  CMyButton::PreSubclassWindow() 
{
CButton::PreSubclassWindow();
ModifyStyle( 
0 , BS_OWNERDRAW );  // 设置按钮属性为自画式
}
这样你就无需在放置按钮时非得设置按钮属性为“OwnerDraw”了。

② DrawItem()函数是最重要的函数,所有自己绘制按钮的工作都在这里进行,它的作用类似于View类中的OnDraw()函数。
例:
void  CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
CDC 
* pDC  =  CDC::FromHandle( lpDrawItemStruct -> hDC );
m_ButRect 
=  lpDrawItemStruct -> rcItem;  // 获取按钮尺寸
GetWindowText( m_strText );  // 获取按钮文本
CPoint m_ptCentre  =  m_ButRect.CenterPoint();  // 求按钮中心点
CSize Extent  =  pDC -> GetTextExtent( m_strText );  // 求文本尺寸
m_textPt  =  CPoint( m_ptCentre.x  -  Extent.cx / 2 ,
m_ptCentre.y 
-  Extent.cy / 2  );  // 设置文本坐标
int  nSavedDC  =  pDC -> SaveDC();
VERIFY( pDC );

if ! (::GetWindowLong(m_hWnd,GWL_STYLE)  &  WS_DISABLED) )
{
if ! b_Flag )
{
NormalButton( pDC ); 
// 画正常按钮
}
else
{
PassButton( pDC ); 
// 画鼠标经过时的按钮
}
}
else
{
LockButton( pDC ); 
// 画锁定的按钮
}

pDC
-> RestoreDC( nSavedDC );
}
其中的变量在CMyButton.h中定义:
BOOL b_Flag; 
// 按钮状态(false-正常,true-当前)
BOOL b_InRect;  // 鼠标进入标志
CString m_strText;  // 按钮文字
COLORREF m_ForeColor;  // 文本颜色
COLORREF m_BkColor;  // 背景色
COLORREF m_LockForeColor;  // 锁定按钮的文字颜色
CRect m_ButRect;  // 按钮尺寸
CPoint m_textPt;  // 文字坐标(左上角)
具体绘制按钮的函数是另外定义的,只要你会用VC绘图,就可随心所欲的画出你想要的任何形态按钮,这里我定义了三种情况的按钮:
绘制正常状态下的按钮:
void  CMyButton::NormalButton(CDC  * pDC)
{
……
}
绘制鼠标进入按钮区域后的按钮:
void  CMyButton::PassButton(CDC  * pDC)
{
……
}
绘制锁定(变灰)状态下的按钮:
void  CMyButton::LockButton(CDC  * pDC)
{
……
}
有些人还希望绘制“鼠标按下时的按钮”、“拥有焦点的按钮”使效果更好,可在相应位置做如下修改:
int  b_Flag;  // 0-正常、1-鼠标进入、2-鼠标按下、3-拥有焦点

switch (b_Flag)
{
case   0 :画正常按钮; break ;
case   1 :画鼠标进入后的按钮; break ;
case   2 :画鼠标按下后的按钮; break ;
case   3 :画拥有焦点的按钮; break ;
}
而b_Flag的值在鼠标消息函数中进行修改。

③ OnMouseMove()函数用于判定鼠标是否在按钮上:
void  CMyButton::OnMouseMove(UINT nFlags, CPoint point) 
{
CButton::OnMouseMove(nFlags, point);

if ! b_InRect  ||  GetCapture() != this  )  // 鼠标进入按钮
{
b_InRect 
=   true ;
SetCapture();
b_Flag 
=   true ;
Invalidate(); 
// 重绘按钮
}
else
{
CRect rc;
this -> GetClientRect(  & rc );
if  (  ! rc.PtInRect(point) )  // 鼠标离开按钮
{
b_InRect 
=   false ;
ReleaseCapture();
b_Flag 
=   false ;
Invalidate(); 
// 重绘按钮
}
}
}
变量b_InRect用于判定鼠标是进入了按钮区还是从按钮中离开,b_Flag决定了绘制何种按钮,Invalidate()函数调用DrawItem()函数重绘按钮。

④ OnLButtonDown()函数和OnLButtonUp()函数与OnMouseMove()函数类似,用于鼠标按下和弹起时重绘按钮。
void  CMyButton::OnLButtonDown(UINT nFlags, CPoint point) 
{
b_Flag 
=   false ;
if  (GetFocus() != this )
{
this -> SetFocus();
}
CButton::OnLButtonDown( nFlags, point );
Invalidate(); 
// 重绘按钮
}
本例中我在鼠标按下时绘制的是“正常状态”的按钮。
void  CMyButton::OnLButtonUp(UINT nFlags, CPoint point) 
{
b_Flag 
=   true ;
if  (GetFocus() != this )
{
this -> SetFocus();
}
CButton::OnLButtonUp( nFlags, point );
Invalidate(); 
// 重绘按钮
}
我在鼠标弹起后绘制的是“鼠标进入按钮区状态”的按钮。

三、在CMyButton类的构造函数中设置变量的初值:
CMyButton::CMyButton()
{
b_InRect 
=   false ;
b_Flag 
=   false ;
}
这样一个新的按钮类的核心部分就完成了,你还可以根据需要再设计一些接口函数,如设置按钮颜色、设置按钮状态等,使得调用时更灵活方便。

在我提供的示例程序中,我仿造Dreamweaver的界面制作了几个按钮类,你用我上面提供的方法看一看,应该容易看得懂,再自己发挥一下应该能设计你所需要的按钮了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值