MFC下自绘CStatic控件

发布于:2022-12-07 ⋅ 阅读:(907) ⋅ 点赞:(0)

最近一段时间系统的整理了下关于MFC框架的知识点,想给大家分享下关于MFC框架下控件的自绘知识。也是我刚刚参加工作实现的一整套控件自绘,这里,我会逐一进行讲解的

首先,我们来拿MFC下最简单的静态文本控件来讲解吧!

很多时候,我们在使用静态控件只是用于显示文本,但是也有显示图片的时候。

当前自绘的静态文本控件可以实现哪些功能:

1:文本字体颜色值设置

2:背景色以及背景图片设置

3:是否填充背景色

4:文本的对齐方式

根据以上上述功能,我来具体讲解该控件的自绘功能吧!

一般情况下,自绘控件的父类都是基于框架原始类实现的。

class UIStatic:public CStatic
{
}

这种方式我们才使用控件时,直接将CStatic类替换成UIStatic就可以啦!

在MFC框架下自绘的方式也会有所不同,例如当前所有的控件,需要在OnPaint消息中进行重新绘制。

OnPaint自绘

既然是要自绘,那么系统控件CStatic类风格显示的内容都会被覆盖的,我们需要在OnPaint中重新定义字体显示风格、文本风格以及背景风格

设置字体风格

CFont *font = GetFont();
CFont *oldFont = dc.SelectObject(font);


//OnPaint最后,一定要写的哦~
dc.SelectObject(oldFont);

这里很多人都会疑问,为什么不直接在OnPaint中随时设置字体的风格呢?

首先,我们不确定使用该控件的程序员是否会设置字体风格,采用GetFont的方式如果不进行设置自定义的字体风格时,可以默认使用系统的风格。

设置字体颜色值

这里的字体颜色是需要用户设置的,所以在这里设置的颜色值不是能写成固定值的哦~

dc.SetTextColor(m_crText);
dc.SetBkMode(TRANSPARENT);

那么,如何设置字体的颜色值呢?有两种方式,大家可以拿小本本记录下来哟~

方法1:DWORD方式传入

RGB(GetBValue(color),GetGValue(color),GetRValue(color));

方法2:COLORREF方式传入

void SetTextColor(COLORREF color)
{
   m_crText = color;
}

设置背景色以及背景图片

处于简单实现,这里加载图片的方式采用了CImage,但是这个类有一个弊端,就是图片偏大或者偏小时,会失真,必须按照图片的大小进行设置。

如果存在了背景图片,那么就将该控件的背景显示成图片信息;

if (! m_ImgBackground.IsNull())
{
	m_ImgBackground.Draw((*pDC).GetSafeHdc(),rect);
}

如果不存在图片信息,就是用设定的背景颜色值。当前的背景颜色值设置也可以用上面文本颜色值的设置方法哦~

else
{
    pDC->FillSolidRect(rect , m_crBackground);
}

设置文本对齐方式

文本的对齐方式有:左、右、靠上、靠下、水平居中、垂直居中,那么来看看是如何显示的吧!

定义一个UINT类型的成员变量,用来接收用户传入的字体显示风格

UINT m_uFormat;

我们会根据实际的风格来设置文本的显示位置

当用户设置了垂直风格时?

if(m_uFormat & DT_VCENTER)
{
	int   nTextHeight = csText.cy ;
	if (csText.cx > rectItem.Width())//多行
	{
		int  row_num = csText.cx / rect.Width() +1 ;	//计算有多少行
		nTextHeight = csText.cy * row_num ; //计算总共的行高
	}
	rectItem.top   = rect.top+(rect.Height()-nTextHeight)/2;
}

我们不知道传入的文本具体长度是多少,想要在控件的垂直居中位置显示文本时,需要知道应该显示几行文本,以及传入的字符串的总体像素单位长度是多少。

这里,会用到一个叫做GetTextExtent函数,获取传入文本的大小,也就是长度和宽度。

CSize   csText = pDC->GetTextExtent(strText);

需要注意的是:该函数只有在OnPaint绘制操作时有效,或者是你可以GetDC时也会生效,其他地方获取得CSize是不准确的哦~

当字符串的显示长度超过控件本身宽度时,肯定是需要显示多行信息,也就意味着上述代码的多行显示了。

那么,剩下的无论是靠左风格、靠右风格以及水平居中风格,直接设置就可以。

dc.DrawText(strText , rectItem , DT_LEFT|DT_WORDBREAK); //靠左设置

dc.DrawText(strText , rectItem , DT_LRIGHT|DT_WORDBREAK); //靠右设置

 字体设置

接下来,这也算是贯穿整个自绘控件中的通用设置了,无论是哪个控件都是可以适用的~小本本准备好了吗?

定义一个叫做SetTextFont()的函数用于设置控件的字体风格

完整的函数声明,如下:

void SetTextFont(int ftSize , CStringW ftType , int fontmode= PointFont_Mode, DWORD  nStyle = FontStyle_Normal);

参数1:字体的大小

参数2:字体的风格,例如:微软雅黑,宋体、黑体

参数3:创建字体模式,默认是模式1,这里有两种字体创建模式

参数4:设置字体风格

默认是FontStyle_Normal,没有任何风格

FontStyle_Bold = 2 , //粗体
FontStyle_Italics = 4, //斜体

FontStyle_Underline = 8 , //下划线

当前的风格值是根据系统的参数值进行依依对应的。

注意:

当我们在设置字体风格时,一定要先销毁上一次使用的字体风格,再重新设置!

m_font.DeleteObject();

方法1设置:

当前方法采用了CreatePointFont方式。

对于这种方式来说,设置很简单

m_font.CreatePointFont( ftSize*10 , ftType);

为什么要*10设置呢?那是因为使用该方法设置字体时,设置的字体很小,一般做乘10处理。

方法2设置:

当前方法采用了CreateFontIndirect方式。

使用该方法需要设置的参数比较多

GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&logFont);  
	
logFont.lfHeight=ftSize;//字体高度为16PX  
//根据 用户 设定风格 判定,是否需要设置?
if (nStyle & FontStyle_Underline)
{
	logFont.lfUnderline = TRUE;			//文字底部加下划线
}
else
	logFont.lfUnderline = FALSE;
if (nStyle & FontStyle_Bold)
{
	logFont.lfWeight = 650    ;			//文字加粗
}
else
	logFont.lfWeight = 0;
if (nStyle & FontStyle_Italics)
{
	logFont.lfItalic = TRUE;		//斜体文本
}
else
	logFont.lfItalic = FALSE;
logFont.lfWidth = 0;//字体宽度为20PX  
logFont.lfCharSet=GB2312_CHARSET;//国标2312  
wsprintf(logFont.lfFaceName,TEXT("%s"),strFtType);  

今天的更新就到这里喽~

我是糯诺诺米团,一名C++开发程序媛~

本文含有隐藏内容,请 开通VIP 后查看