VC多功能标签CLabelEx

Gd啦不啦

Gd啦不啦

2016-02-19 21:42

下面是个超简单的VC多功能标签CLabelEx教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

  引言

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

  做用户界面的时候经常要用到一些静态文本控件,显示一些文字信息,但是 MFC 提供的 CStatic类的功能过于简单,无法满足高级需求。为此我从 CStatic 派生了一个类 CLabelEx,扩展了CStatic。第一次投稿,水平不足请大家见谅。我从 vckbase.com 学到了很多很多东西 ,该是我回报的时候了。

  一、功能简介

  新增的功能主要有:

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

  1、设置背景图片SetBGBitmap();设置鼠标经过时的背景图片SetMouseOverBGBitmap();设置鼠标单击后的背景图片SetClickedBGBitmap();
  2、设置标签图片,SetLabelBitmap();设置鼠标经过时的标签图片SetMouseOverLabelBitmap();设置鼠标单击时的标签图片
  3、文字功能
  (1)设置字体颜色,下划线等就不说了.
  (2)感应鼠标经过时自动加上下划线,自动把文字变蓝(就像一个超链接一样)
  4、边框和背景
  可以设置/取消边框,指定边框颜色;设置背景色,并填充整个标签

  二、实现原理

  1、其实就是在OnPaint()里画出各种效果:本文发表于http://bianceng.cn(编程入门网)

void CLabelEx::OnPaint()
{
   CPaintDC dc(this); // device context for painting
   dc.SetTextColor(m_crText);
   dc.SetBkMode(TRANSPARENT);
   dc.SelectObject(this-GetFont());
   ///准备工作
   CRect rect;
   CDC MemDC;
   CPen BorderPen,*pOldPen,UnderLinePen;
   CBrush BGBrush,*pOldBrush;
   BITMAP bm;
   int nTextLeft=0,nTextTop=0; //文字输出的位置
  
   this-GetClientRect(&rect);
  
   MemDC.CreateCompatibleDC(&dc);
   MemDC.SetMapMode(dc.GetMapMode());
  
   ///画边框
   if(m_bBorder)
   {
     BorderPen.CreatePen(PS_SOLID,1,m_crBorder);
     BGBrush.CreateSolidBrush(m_crBG);
    
     pOldPen=dc.SelectObject(&BorderPen);
     pOldBrush=dc.SelectObject(&BGBrush);
    
     dc.Rectangle(&rect);
    
     dc.SelectObject(pOldPen);
     dc.SelectObject(pOldBrush);
    
     rect.DeflateRect(1,1);
   }
   ///贴背景图
   if(m_bClicked && m_ClickedBGBm.GetSafeHandle()!=NULL)
   {
     MemDC.SelectObject(m_ClickedBGBm);
     dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
       &MemDC,0,0,SRCCOPY);
   }
   else if(m_bOver && m_MouseOverBGBm.GetSafeHandle()!=NULL)//鼠标经过的时候
   {
     MemDC.SelectObject(m_MouseOverBGBm);
     dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
       &MemDC,0,0,SRCCOPY);
   }
   else if(m_BGBm.GetSafeHandle()!=NULL)
   {
     MemDC.SelectObject(m_BGBm);
     dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
       &MemDC,0,0,SRCCOPY);
   }
   ///贴标签图片
   if(m_bClicked && m_ClickedLabelBm.GetSafeHandle()!=NULL)
   {
     m_ClickedLabelBm.GetBitmap(&bm);
     double fScal=bm.bmWidth*1.0/bm.bmHeight;
     nTextLeft=int(rect.Height()*fScal)+4;
     MemDC.SelectObject(m_ClickedLabelBm);
     dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
       &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
   }
   else if(m_bOver && m_MouseOverLabelBm.GetSafeHandle()!=NULL)
   {
     m_MouseOverLabelBm.GetBitmap(&bm);
     double fScal=bm.bmWidth*1.0/bm.bmHeight;
     nTextLeft=int(rect.Height()*fScal)+4;
     MemDC.SelectObject(m_MouseOverLabelBm);
     dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
       &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
   }
   else if(m_LabelBm.GetSafeHandle()!=NULL)
   {
     m_LabelBm.GetBitmap(&bm);
     double fScal=bm.bmWidth*1.0/bm.bmHeight;
     nTextLeft=int(rect.Height()*fScal)+4;
     MemDC.SelectObject(m_LabelBm);
     dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
       &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
   }
   else
   {
     nTextLeft=4;
   }
   ///输出文字
   TEXTMETRIC tm;
   dc.GetTextMetrics(&tm);
   CString strText;
   this-GetWindowText(strText);
   nTextTop=rect.top+(rect.Height()-tm.tmHeight)/2;
   if(strText.GetLength()0)
   {
     dc.TextOut(nTextLeft,nTextTop,strText);
   }
  
   ///画下划线
   if(m_bUnderLine)
   {
     nTextLeft-=2;
     nTextTop=nTextTop+tm.tmHeight+1;
     UnderLinePen.CreatePen(PS_SOLID,1,m_crUnderLine);
     pOldPen=dc.SelectObject(&UnderLinePen);
     dc.MoveTo(nTextLeft,nTextTop);
     dc.LineTo(nTextLeft+tm.tmAveCharWidth*strText.GetLength(),nTextTop);
   }
}   
  注:对字体加下划线我没有使用直接设置字体下划线的方法,因为我觉得那样不好看,呵呵

  2、感应鼠标用的方法如下所示:

  在MouseMove里SetCapture()和ReleaseCapture();

void CLabelEx::OnMouseMove(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   if (m_bOver)    // Cursor is currently over control
   {
     CRect rect;
     GetClientRect(rect);
    
     if (!rect.PtInRect(point))
     {
       m_bOver = FALSE;
       if(m_bAutoUnderLine) ///自动下划线
       {
         this-SetUnderLine(FALSE,RGB(0,0,0));
       }
       if(m_bHighLight)  //自动高亮
       {
         ///恢复原来的字体颜色
         this-SetTextColor(m_crBackText);
       }
       RedrawWindow();
       ReleaseCapture();
       return;
     }
   }
   else           // Cursor has just moved over control
   {
     m_bOver = TRUE;
     if(m_bAutoUnderLine)
     {
       this-SetUnderLine(TRUE,RGB(0,0,255));
     }
     if(m_bHighLight)
     {
       m_crBackText=m_crText;
       this-SetTextColor(RGB(0,0,255));
     }
     RedrawWindow();
     SetCapture();
     ::SetCursor(m_hHandCur);
   }
   CStatic::OnMouseMove(nFlags, point);
}   
  注:这种方法简单方便,但是有一个问题,看附带的工程,单击Label1弹出一个对话框后Label1无法恢复原状。我一直没解决这个问题.若谁知道请告知我 querw@sina.com

展开更多 50%)
分享

猜你喜欢

VC多功能标签CLabelEx

编程语言 网络编程
VC多功能标签CLabelEx

多功能标签CLabelEx

C语言教程 C语言函数
多功能标签CLabelEx

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

什么是多功能护理床?多功能护理床的功能

收纳技巧 生活常识
什么是多功能护理床?多功能护理床的功能

多功能概念长椅

平面设计 海报设计 广告设计 画报设计 签名设计 服装设计 名片设计 画册设计 版式设计 商标设计
多功能概念长椅

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

多功能懒人小沙发

创意手工
多功能懒人小沙发

多功能书桌的需求

电脑网络
多功能书桌的需求

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

VC中锁定ListView的栏目头宽度

VC中锁定ListView的栏目头宽度

不能切回到aero模式的解决方法

不能切回到aero模式的解决方法
下拉加载更多内容 ↓