zoukankan      html  css  js  c++  java
  • 自己动手做按钮

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

    一、用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;
    }
    这样一个新的按钮类的核心部分就完成了

  • 相关阅读:
    UITableView多选全选
    iOS16进制设置颜色
    svg矢量图
    canvas 时钟案例
    canvas 方块旋转案例
    canvas万花筒案例
    swiper(轮播)组件
    canvas介绍(画布)
    scroll-view组件
    view组件
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/5146157.html
Copyright © 2011-2022 走看看