引言 做用户界面的时候经常要用到一些静态文本控件,显示一些文字信息,但是 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 |
自定义控件
最新推荐文章于 2023-08-31 21:00:50 发布