WEB开发网
开发学院软件开发VC 用VC6扩展CButton类制作风格独特的按钮 阅读

用VC6扩展CButton类制作风格独特的按钮

 2008-01-19 20:25:53 来源:WEB开发网   
核心提示:三、 派生类CLinkButton的具体实现:1、重载函数 DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct), void CLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){// 获取一个CDC指针CDC* pDC =
三、 派生类CLinkButton 的具体实现:

1、重载函数  DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)。 void CLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  // 获取一个CDC指针
  CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  //定义按钮区域并初始化
  CRect rect(lpDrawItemStruct->rcItem);
  //设置背景模式
  COLORREF oc = pDC->GetTextColor();
  int iObk = pDC->SetBkMode(TRANSPARENT);
  //初始化按钮状态
  UINT state = lpDrawItemStruct->itemState;
  CFont * pOldFont = NULL;
  int iYOffset = 0, iXOffset = 0;
  CString strText;
  GetWindowText(strText);
  rect.top += iYOffset;
  rect.left += iXOffset;
  if (state & ODS_DISABLED)
  {    
    //按钮置灰(DISABLED)
    CBrush grayBrush;
    grayBrush.CreateSolidBrush (GetSysColor (COLOR_GRAYTEXT));
    CSize sz = pDC->GetTextExtent(strText);
    int x = rect.left + (rect.Width() - sz.cx)/2;
    int y = rect.top + (rect.Height() - sz.cy)/2;
    rect.top += 2;
    rect.left += 2;
    pDC->SetTextColor(GetSysColor(COLOR_3DHIGHLIGHT));
    pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    rect.top -= 2;
    rect.left -= 2;
    pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
    pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  }
  else
  {
    if (bHighlight)//光标在按钮上
    {
      if (state & ODS_SELECTED)
        //按下按钮
        pDC->Draw3dRect(rect,GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
      else
        //未按下按钮
        pDC->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
       //字体颜色
      pDC->SetTextColor(RGB(0,0,255));
      //加下画线(也可以用其他字体)
      if (fUnderline.GetSafeHandle() == NULL)
      {
        CFont * pFont = GetFont();
        ASSERT(pFont);
        LOGFONT lf;
        pFont->GetLogFont(&lf);
        lf.lfUnderline = TRUE;
        fUnderline.CreateFontIndirect(&lf);    
      }
      pOldFont = pDC->SelectObject(&fUnderline);
    }
    else pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
    pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    if (pOldFont) pDC->SelectObject(pOldFont);
  }
}
2、定制的消息处理函数 void CLinkButton::OnMouseMove(UINT nFlags, CPoint point)
{
  //设置一个定时器
  SetTimer(1,10,NULL);
  CButton::OnMouseMove(nFlags, point);
}   
  当鼠标光标移到按钮上时,执行此函数,定时器将发送一个 WM_TIMER消息到消息队列。由OnTimer(UINT nIDEvent)函数处理这个消息。 void CLinkButton::OnTimer(UINT nIDEvent)
{
  static bool pPainted = false;
  POINT pt;
  GetCursorPos(&pt);
  CRect rect;
  GetWindowRect (rect);
  if (bLBtnDown)  
  {    
    KillTimer (1);
    if (pPainted) InvalidateRect (NULL);    
    pPainted = FALSE;    
    return;  
  }
  if (!rect.PtInRect (pt))  
  {    
    bHighlight = false;
    KillTimer (1);
    if (pPainted)      
      InvalidateRect(NULL);
    pPainted = false;
    return;  
  }
  else
  {
    bHighlight = true;
    if (!pPainted)
    {
      pPainted = true;
      InvalidateRect(NULL);
    }
  }
  CButton::OnTimer(nIDEvent);
}
BOOL CLinkButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
  if (bHighlight)
  {
    ::SetCursor(hHand);
    return true;
  }
  return CButton::OnSetCursor(pWnd, nHitTest, message);
}
int CLinkButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CButton::OnCreate(lpCreateStruct) == -1)
    return -1;
  CFont * pFont = GetFont();
  ASSERT(pFont);
  LOGFONT lf;
  pFont->GetLogFont(&lf);
  lf.lfUnderline = TRUE;
  fUnderline.CreateFontIndirect(&lf);
  return 0;
}   
这个函数由框架在显示出按钮之前自动调用,我在这里初始化按钮上显示的字体。 void CLinkButton::OnLButtonUp(UINT nFlags, CPoint point)
{
  bLBtnDown = false;
  if (bHighlight)  
  {
    bHighlight = false;
    InvalidateRect(NULL);
  }
  CButton::OnLButtonUp(nFlags, point);
}   
当按下按钮又放开时调用这个函数。 void CLinkButton::OnLButtonDown(UINT nFlags, CPoint point)
{
  bLBtnDown = true;
  CButton::OnLButtonDown(nFlags, point);
}   
当按下按钮时调用这个函数。 BOOL CLinkButton::OnEraseBkgnd(CDC* pDC)
{
  COLORREF cr = GetSysColor(COLOR_3DFACE);
  int r = GetRValue(cr);
  int g = GetGValue(cr);
  int b = GetBValue(cr);
  if (r > 1) r -= 2;
  if (g > 1) g -= 2;
  if (r < 3 && g < 3 && b < 253) b += 2;
  COLORREF cr1 = RGB(r,g,b);
  CRect rc;
  GetClientRect(rc);
  pDC->FillSolidRect(rc, cr1);
  return CButton::OnEraseBkgnd(pDC);
}  
当按钮的背景需要重画时,应用程序框架调用此函数。

其他实现细节请下载源代码。运行程序的效果图见图一、图二和图三。

上一页  1 2 

Tags:VC 扩展 CButton

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接