自定义控件

引言

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

一、功能简介

新增的功能主要有:

1、设置背景图片SetBGBitmap();设置鼠标经过时的背景图片SetMouseOverBGBitmap();设置鼠标单击后的背景图片SetClickedBGBitmap();

2、设置标签图片,SetLabelBitmap();设置鼠标经过时的标签图片SetMouseOverLabelBitmap();设置鼠标单击时的标签图片

3、文字功能

(1)设置字体颜色,下划线等就不说了.

(2)感应鼠标经过时自动加上下划线,自动把文字变蓝(就像一个超链接一样)

4、边框和背景

可以设置/取消边框,指定边框颜色;设置背景色,并填充整个标签

二、实现原理

1、其实就是在OnPaint()里画出各种效果:

001. void CLabelEx::OnPaint()
002. {
003. CPaintDC dc(this); // device context for painting
004. dc.SetTextColor(m_crText);
005. dc.SetBkMode(TRANSPARENT);
006. dc.SelectObject(this->GetFont());
007. ///准备工作
008. CRect rect;
009. CDC MemDC;
010. CPen BorderPen,*pOldPen,UnderLinePen;
011. CBrush BGBrush,*pOldBrush;
012. BITMAP bm;
013. int nTextLeft=0,nTextTop=0; //文字输出的位置
014.  
015. this->GetClientRect(&rect);
016.  
017. MemDC.CreateCompatibleDC(&dc);
018. MemDC.SetMapMode(dc.GetMapMode());
019.  
020. ///画边框
021. if(m_bBorder)
022. {
023. BorderPen.CreatePen(PS_SOLID,1,m_crBorder);
024. BGBrush.CreateSolidBrush(m_crBG);
025.  
026. pOldPen=dc.SelectObject(&BorderPen);
027. pOldBrush=dc.SelectObject(&BGBrush);
028.  
029. dc.Rectangle(&rect);
030.  
031. dc.SelectObject(pOldPen);
032. dc.SelectObject(pOldBrush);
033.  
034. rect.DeflateRect(1,1);
035. }
036. ///贴背景图
037. if(m_bClicked && m_ClickedBGBm.GetSafeHandle()!=NULL)
038. {
039. MemDC.SelectObject(m_ClickedBGBm);
040. dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
041. &MemDC,0,0,SRCCOPY);
042. }
043. else if(m_bOver && m_MouseOverBGBm.GetSafeHandle()!=NULL)//鼠标经过的时候
044. {
045. MemDC.SelectObject(m_MouseOverBGBm);
046. dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
047. &MemDC,0,0,SRCCOPY);
048. }
049. else if(m_BGBm.GetSafeHandle()!=NULL)
050. {
051. MemDC.SelectObject(m_BGBm);
052. dc.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),
053. &MemDC,0,0,SRCCOPY);
054. }
055. ///贴标签图片
056. if(m_bClicked && m_ClickedLabelBm.GetSafeHandle()!=NULL)
057. {
058. m_ClickedLabelBm.GetBitmap(&bm);
059. double fScal=bm.bmWidth*1.0/bm.bmHeight;
060. nTextLeft=int(rect.Height()*fScal)+4;
061. MemDC.SelectObject(m_ClickedLabelBm);
062. dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
063. &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
064. }
065. else if(m_bOver && m_MouseOverLabelBm.GetSafeHandle()!=NULL)
066. {
067. m_MouseOverLabelBm.GetBitmap(&bm);
068. double fScal=bm.bmWidth*1.0/bm.bmHeight;
069. nTextLeft=int(rect.Height()*fScal)+4;
070. MemDC.SelectObject(m_MouseOverLabelBm);
071. dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
072. &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
073. }
074. else if(m_LabelBm.GetSafeHandle()!=NULL)
075. {
076. m_LabelBm.GetBitmap(&bm);
077. double fScal=bm.bmWidth*1.0/bm.bmHeight;
078. nTextLeft=int(rect.Height()*fScal)+4;
079. MemDC.SelectObject(m_LabelBm);
080. dc.StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(),
081. &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
082. }
083. else
084. {
085. nTextLeft=4;
086. }
087. ///输出文字
088. TEXTMETRIC tm;
089. dc.GetTextMetrics(&tm);
090. CString strText;
091. this->GetWindowText(strText);
092. nTextTop=rect.top+(rect.Height()-tm.tmHeight)/2;
093. if(strText.GetLength()>0)
094. {
095. dc.TextOut(nTextLeft,nTextTop,strText);
096. }
097.  
098. ///画下划线
099. if(m_bUnderLine)
100. {
101. nTextLeft-=2;
102. nTextTop=nTextTop+tm.tmHeight+1;
103. UnderLinePen.CreatePen(PS_SOLID,1,m_crUnderLine);
104. pOldPen=dc.SelectObject(&UnderLinePen);
105. dc.MoveTo(nTextLeft,nTextTop);
106. dc.LineTo(nTextLeft+tm.tmAveCharWidth*strText.GetLength(),nTextTop);
107. }
108. }

注:对字体加下划线我没有使用直接设置字体下划线的方法,因为我觉得那样不好看,呵呵

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

在MouseMove里SetCapture()和ReleaseCapture();

01. void CLabelEx::OnMouseMove(UINT nFlags, CPoint point)
02. {
03. // TODO: Add your message handler code here and/or call default
04. if (m_bOver)        // Cursor is currently over control
05. {
06. CRect rect;
07. GetClientRect(rect);
08.  
09. if (!rect.PtInRect(point))
10. {
11. m_bOver = FALSE;
12. if(m_bAutoUnderLine)  ///自动下划线
13. {
14. this->SetUnderLine(FALSE,RGB(0,0,0));
15. }
16. if(m_bHighLight)   //自动高亮
17. {
18. ///恢复原来的字体颜色
19. this->SetTextColor(m_crBackText);
20. }
21. RedrawWindow();
22. ReleaseCapture();
23. return;
24. }
25. }
26. else                      // Cursor has just moved over control
27. {
28. m_bOver = TRUE;
29. if(m_bAutoUnderLine)
30. {
31. this->SetUnderLine(TRUE,RGB(0,0,255));
32. }
33. if(m_bHighLight)
34. {
35. m_crBackText=m_crText;
36. this->SetTextColor(RGB(0,0,255));
37. }
38. RedrawWindow();
39. SetCapture();
40. ::SetCursor(m_hHandCur);
41. }
42.  
43. CStatic::OnMouseMove(nFlags, point);
44. }

:这种方法简单方便,但是有一个问题,看附带的工程,单击Label1弹出一个对话框后Label1无法恢复原状。我一直没解决这个问题.若谁知道请告知我 querw@sina.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值