Button控件的重绘

来源:互联网 发布:python 创建数组 编辑:程序博客网 时间:2024/05/22 03:03
 
在用VC6.0编写windows程序时,你是不是时常因为自己的界面不好看而自卑。从现在开始我就来尝试着使我们的程序旋起来。
按钮是我们编写windows程序时不可缺少的控件之一。按一般用户的理解,不管窗口是否为输入焦点,当鼠标(准确的说应该是光标cursor)划过按钮时,按钮应该变色,表示这个地方是可以按下的。可是用VC6.0原始给出的按钮像个傻瓜一样,没有丝毫反应。
其实要让他有反应还是很简单的,下面就是我们该做的。
1.         派生一个类,其基类为CButton。假如叫:CMyButton
2.         为该类添加WM_MOUSEMOVE消息,message handle里应该这样写:
     void CMyButton::OnMouseMove(UINT nFlags, CPoint point) 
{
       
if(!m_bOverControl)
       
{
              m_bOverControl 
= TRUE;
              Invalidate();
              SetTimer(m_nTimerID, 
100, NULL);
       }

       
       CButton::OnMouseMove(nFlags, point);
}

m_bOverControl:通过名字就可以猜到他是一个布尔变量,用来表示现在光标是否在按钮上放。
Invalidate():强制使按钮发生重绘。
SetTimer():设置一个定时器,定时检查光标是否还在按钮上方。
3.         添加WM_TIMER消息:message handle里应该这样写: 
     void CMyButton::OnTimer(UINT nIDEvent) 
{
    CPoint p(GetMessagePos());
    CRect rc;
    ScreenToClient(
&p);
    
    GetClientRect(
&rc);
    
    
if(! rc.PtInRect(p))
    
{
        m_bOverControl 
= FALSE;
        KillTimer(m_nTimerID);
        Invalidate();
    }

    
    CButton::OnTimer(nIDEvent);
}

GetMessagePos():获得上次消息发送时,光标的位置。如果要获得当前光标的位置就要用GetCursorPos()。
4.         重载基类的PreSubclassWindow。这个函数其实是在CWnd里定义的。当控件子类化是由framework知道调用。我们常常在这个函数里修改控件的style。在这里我们要将控件改为自绘的。
        
      void CMyButton::PreSubclassWindow() 
{     
       CButton::PreSubclassWindow();
       
       ModifyStyle(
0, BS_OWNERDRAW);
}

5.         最后,也是最重要的,就是具体的绘制操作。在这里重载
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)就可以了。具体如下:                  
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
       CDC 
*pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
       CRect rc 
= lpDrawItemStruct->rcItem;
       UINT state 
= lpDrawItemStruct->itemState;
 
       CString text;
       GetWindowText(text);
 
       
if(state & ODS_SELECTED)
       
{
              pDC
->DrawFrameControl(rc, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED);
       }

       
else
       
{
              pDC
->DrawFrameControl(rc , DFC_BUTTON, DFCS_BUTTONPUSH);
       }

 
    rc.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
    
if (m_bOverControl)
        pDC
->FillSolidRect(rc, RGB(2552550)); // yellow
 
       
if(!text.IsEmpty())
       
{
              CSize size 
= pDC->GetTextExtent(text);
              CPoint pt(rc.CenterPoint().x
-size.cx/2, rc.CenterPoint().y - size.cy/2);
 
              
if(state & ODS_SELECTED)
                     pt.Offset(
11);
 
              
int mode = pDC->SetBkMode(TRANSPARENT);
              
if(state & ODS_DISABLED)
                     pDC
->DrawState(pt, size, text, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
              
else
                     pDC
->TextOut(pt.x, pt.y, text);
 
              pDC
->SetBkMode(mode);
 
 
       }

}

 
原创粉丝点击