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

  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/5146157.html
Copyright © 2011-2022 走看看