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

2016-02-19 21:44 46 1 收藏

下面,图老师小编带您去了解一下用VC6扩展CButton类制作风格独特的按钮,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - 编程语言 】

  一、 本文介绍一个CButton的派生类CLinkButton,用此派生类制作的按钮具有以下特点:

  1、按钮的外观类似静态控件类CStatic 产生的对象。(参见图一)

 
  图一

  2、当鼠标的光标移到按钮上,但并未按下时,光标改变形状,字体改变形状;按钮类似应用在工具条和菜单上的扁平钮效果。(参见图二)

 
  图二

  3、当按钮按下的情形:(参见图三)

 
  图三

  二、下面具体描述这种按钮的实现方法和步骤:

  在VC6的IDE环境中,生成一个基于对话框的PROJECT。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  将对话框资源中按钮的属性页打开,在“Style”标签页中选取按钮的“Owner Draw”(自绘)属性。

  将光标引入到应用程序的资源中。

  利用CLASSWIZARD,用CButton为基类,派生一个新类:CLinkButton。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  在派生类中重载基类CButton的虚函数: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

  之所以要重载这个函数是因为选择了按钮的 “Owner Draw”属性后,当按钮的可视行为发生变化时,应用程序的框架要调用这个函数来重新绘制按钮。

  定制以下的消息处理:afx_msg void OnMouseMove(UINT nFlags, CPoint point);
   afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
   afx_msg void OnTimer(UINT nIDEvent);
   afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
   afx_msg BOOL OnEraseBkgnd(CDC* pDC);
声明类成员变量定义: //定义字体变量
   CFont fUnderline;
   //定义光标变量
   HCURSOR hHand;
   //决定按钮是否按下
   bool bLBtnDown;
   //决定鼠标是否在按钮上
   bool bHighlight;

  三、 派生类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);
}   当按钮的背景需要重画时,应用程序框架调用此函数。

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

来源:https://www.tulaoshi.com/n/20160219/1627002.html

延伸阅读
最终效果图 1.新建文件,使用矩形选区工具绘制一个矩形按钮,前景色设置为#990000 ,背景色设置为#660000,选择反射渐变工具,填充,并使用自由变换工具对按钮进行扭曲。效果如下: 2.选择按钮底层,调出选区,将选区缩进5个像素(选择-修改-缩小)。新建层,命名为按钮皮肤。按下X键将前景色和背景色进行调换。依旧选...
标签: CorelDRAW
4. 用右键(注意是右键)拖动按钮主体到高光部分,从弹出菜单中选“Copy Fill Here”(复制到此),这样就快速将按钮主体的填充属性复制到高光部分了,很显然,还要进一步调整:选“交互式填充”工具,再选高光部分,在属性栏上将其线性填充角度由-90度改为90度,结果如图5。 5. 为了做出更逼真的效果,还要求...
标签: CorelDRAW
浏览过苹果公司主页的人,想必对其晶莹剔透,流光溢彩的网页按钮有深刻的印象(图0)。记得看过介绍制作苹果风格按钮的文章,不过那是用PHOTOSHOP做出来的,在Coreldraw中又是如何制作呢?请看我的制作方法: 虽然心动不如行动,但是在行动之前还要“运筹帷幄”,仔细观察一下,我们会发现按钮主要分为以下几部分: ...
最终效果图 www.Tulaoshi.com 最终效果图
最终效果图   1、新建画布,大小随意,然后新建圆角矩形图形,如图所示:   2、圆角矩形属性。   3、画一个吧,高 宽自定。   4、接下来要出玻璃效果就是靠图层属性设置,选择蒙板图层右键混合属性,描边设置:   5、渐变叠加设置:   6、渐变值:   7、...

经验教程

606

收藏

82
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部