MFC界面美化
MFC写的界面看上去还是傻傻的,想着美化一下。调研了一些MFC界面美化的方法,大概总结了以下几种方式:
一、给按钮Button贴图,应用CBitmapButton
1.在控件的属性框内设置OwnerDraw为True。
2.准备四张在不同状态下按钮呈现的BMP图片。在资源管理界面添加资源,选择准备好的四张图片,这时会在资源下新建一个Bitmap的目录,存放这四张图片。
3.重新定义这四张图片的ID分别为Caption+U/D/F/S.如:Button1 U/D/F/S.分别对应正常状态,按下状态,点击过后状态以及失效后状态。
4.如果是dialog类直接在OnInitDialog()函数下写相关代码,如果是View类,须添加afx_msg voidOnInitialUpdate()函数
5.在.h文件中声明一个变量CBitmapButtonm_bitmapButton,调用以下函数:
m_bitmapButton.LoadBitmaps(BITMAP_BUTTONU,BITMAP_BUTTOND,BITMAP_BUTTONS,BITMAP_BUTTONF);
m_bitmapButton.SizeToContent();
二、给界面贴背景图,防止闪屏,设计双缓冲机制。
1.为View类或者是Dialog类添加OnPaint函数以及消息ON_WM_PAINT()。
2.用同上的办法添加一个BMP资源。
3.在OnPaint函数内写相关代码如下
CPaintDC dc(this);
CRect Rect;
GetClientRect(&Rect);
CDC dcMem;
CBitmap bmpbkground;
dcMem.CreateCompatibleDC(&dc);
bmpbkground.LoadBitmap(IDB_BITMAP1); //添加的BMP资源ID
BITMAP bitMap;
bmpbkground.GetBitmap(&bitMap); //绑定BMP
CBitmap *pOldbmp= dcMem.SelectObject(&bmpbkground);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0,0,Rect.Width(),Rect.Height(),&dcMem,0,0,bitMap.bmWidth,bitMap.bmHeight,SRCCOPY);
dcMem.SelectObject(pOldbmp);
bmpbkground.DeleteObject();
dcMem.DeleteDC();
4.发现有些控件不透明不好看,于是添加afx_msg HBRUSHOnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)函数进行颜色设置。
HBRUSH CViewConfig::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFormView::OnCtlColor(pDC,pWnd,nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255,255,255));
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}
return hbr;
}
三、应用CFont设置字体
1.在.h文件中添加CFont对象:CFont m_Font;
2.在初始化函数下添加代码:
m_Font.CreateFont(14,0,0,0,FW_BOLD,FALSE,FALSE,0,1,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,_T("新宋体"));
(也可以m_Font.CreatePointFont(120,_T("新宋体"),NULL);)
m_edit_freqnums.SetFont(&m_Font,true);
m_edit_radarb.SetFont(&m_Font,true);
g_listbox_status.SetFont(&m_Font,true);
关于CFont的初始化:
BOOL CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename
);
通过指定的一些特征初始化CFont对象。下面分别介绍每个参数:
nHeight:指定字体高度(逻辑单位)。有三种取值:>0,字体映射器将高度值转换为设备单位,并与可用字体的字符元高度进行匹配;=0,字体映射器使用默认的高度值;<0,字体映射器将高度值转换为设备单位,用其绝对值与可用字体的字符高度进行匹配。nHeight转换后的绝对值不应超过16384个设备单位。
nWidth:指定字体中字符的平均宽度(逻辑单位)。
nEscapement:指定偏离垂线和显示界面X轴之间的角度,以十分之一度为单位。偏离垂线是穿过一行文本中第一个字符和最后一个字符的直线。
nOrientation:指定每个字符的基线和设备X轴之间的角度,以十分之一度为单位。
nWeight:指定字体磅数(每1000点中墨点像素数)。可取0到1000之间的任意整数值。
bItalic:指定字体是否为斜体。
bUnderline:指定字体是否带有下划线。
bStrikeOut:指定字体是否带有删除线。
nCharSet:指定字体的字符集。预定义的字符集:
ANSI_CHARSET;BALTIC_CHARSET;CHINESEBIG5_CHARSET;DEFAULT_CHARSET;EASTEUROPE_CHARSET;GB2312_CHARSET; GREEK_CHARSET;HANGUL_CHARSET; MAC_CHARSET; OEM_CHARSET;RUSSIAN_CHARSET; SHIFTJIS_CHARSET;SYMBOL_CHARSET; TURKISH_CHARSET。韩国Windows:JOHAB_CHARSET;中东地区Windows:HEBREW_CHARSSET,ARABIC_CHARSET;泰国Windows:THAI_CHARSET。应用程序可以使用DEFAULT_CHARSET以允许字体名和大小完全指定逻辑字体,如果指定的字体名不存在则可能会用任意字符集的字体来代替,所以为避免不可预料的结果,应谨慎使用DEFAULT_CHARSET。
nOutPrecision:指定输出精度。输出精度定义了输出与要求的字体高度、宽度、字符方向、移位和间距等的接近程度。它的取值及含义如下(只能取其一):
OUT_CHARACTER_PRECIS;未用。
OUT_DEFAULT_PRECIS:指定缺省的字体映射器状态。
OUT_DEVICE_PRECIS:在当系统里有多种字体使用同一个名字时指示字体映射器选择一种设备字体。
OUT_OUTLINE_PRCIS:在WindowsNT中此值指示字体映射器从TrueType和其他基于边框的字体中选择。
OUT_RASTER_PRECIS:在当系统里有多种字体使用同一个名字时指示字体映射器选择一种光栅字体。
OUT_STRING_PRECIS:此值没有被字体映射器使用,但是当列举光栅字体时它会被返回。
OUT_STROKE_PRECIS:没有被字体映射器使用,但是当列举TrueType字体、其他基于边框的字体和向量字体时它会被返回。
OUT_TT_ONLY_PRECIS:指示字体映射器仅从TrueType字体中选择,如果系统中没有安装TrueType字体,则字体映射返回缺省状态。
OUT_TT_PRECIS:在当系统里有多种同名的字体时指示字体映射器选择一种TrueType字体。当操作系统含有多种与指定名字同名的字体时,应用程序可以使用OUT_DEVICE_PRECIS,OUT_RASTER_PRECIS和OUT_TT_PRECIS值来控制字体映射器如何选择一种字体,例如,如果操作系统含有名字Symbol的光栅和TrueType两种字体,指定OUT_TT_PRECIS使字体映射器选择TrueType方式(指定OUT_TT_ONLY_PRECIS强制字体映射器选择一种TrueType字体,尽管这会给TrueType字体换一个名字)。
nClipPrecision:指定裁剪精度。裁剪精度定义了怎样裁剪部分超出裁剪区域的字符。它的取值及含义如下(可取一个或多个值):
CLIP_DEFAULT_PRECIS:指定缺省裁剪状态。
CLIP_CHARACTER_PRECIS:未用。
CLIP_STROKE_PRECIS:未被字体映射器使用,但是当列举光栅字体、向量字体或TrueType字体时它会被返回。在Windows环境下,为保证兼容性,当列举字体时这个值总被返回。
CLIP_MASK:未用。
CLIP_EMBEDDED:要使用嵌入式只读字体必须使用此标志。
CLIP_LH_ANGLES:当此值被使用时,所有字体的旋转依赖于坐标系统的定位是朝左的还是朝右的。如果未使用此值,设备字体总是逆时针方向旋转,但其他字体的旋转依赖于坐标系统的定向。
CLIP_TT_ALWAYS:未用。
nQuality:指定字体的输出质量。输出质量定义了GDI将逻辑字体属性匹配到实际物理字体的细致程度。它的各个取值及含义如下(取其一):
DEFAULT_QUALITY:字体的外观不重要。
DRAFT_QUALITY:字体外观的重要性次于使用PROOF_QUALITY时,对GDI光栅字体,缩放比例是活动的,这意味着多种字体大小可供选择,但质量可能不高,如果有必要,粗体、斜体、下划线、strikeout字体可被综合起来使用。
PROOF_QUALITY:字符质量比精确匹配逻辑字体字体属性更重要。对GDI扫描字体,缩放比例是活动的,并选择最接近的大小。尽管当使用PROOF_QUALITY时,选择字体大小并不完全匹配,但字体的质量很高,并没有外观上的变形。如果有必要,粗体、斜体、下划线、strikeout字体可被综合起来使用。
nPitchAndFamily:指定字体间距和字体族。低2位用来指定字体的间距,可取下列值中的一个:DEFAULT_PITCH,FIXED_PITCH,VARIABLE_PITCH。高4位指定字体族,取值及含义如下(取其一):
FF_DECORATIVE:新奇的字体,如老式英语(Old English)。
FF_DONTCARE:不关心或不知道。
FF_MDERN:笔划宽度固定的字体,有或者无衬线。如Pica、Elite和CourierNew。
FF_ROMAN:笔划宽度变动的字体,有衬线。如MS Serif。
FF_SCRIPT:设计成看上去象手写体的字体。如Script和Cursive。
FF_SWISS:笔划宽度变动的字体,无斜线。如MS Sans Serif。
应用程序可以用运算符OR将字符间距和字体族组合起来给nPitchAndFamily赋值。
字体族描述一种字体的普通外观,当所有的精确字样都不能使用时,可用它们来指定字体。
lpszFacename:指定字体的字样名的字符串。此字符串的长度不应超过30个字符。Windows函数EnumFontFamilies可以枚举出当前所有可用字体的字样名。如果lpszFacename为NULL,则GDI使用一种与设备无关的字体。
返回值:此函数成功则返回TRUE,否则返回FALSE。
CreateFont函数初始化CFont对象后,此字体就能够被选作任何设备上下文的字体了。此函数并不会创建一个新的Windows GDI字体,只是从GDI的物理字体中选择了一个最匹配的字体。在创建一个逻辑字体时,大部分参数可以使用默认值,但一般情况下都会给出参数nHeight和lpszFacename的指定值,如果没有给nHeight和lpszFacename参数设定取值,则创建的逻辑字体与设备相关。当使用CreateFont函数初始化一个CFont对象完成后,就能够使用CDC::SelectObject函数来为设备上下文选择字体了,并且还能够在不再使用此CFont对象时删除它。
四、应用Skin++工具美化。
1.在网上下载了一个Skin++的动态库,将SkinPPWTL.h 文件添加进工程,并在程序中#include"SkinPPWTL.h"。
2.将.lib静态链接到工程里,将dll放在debug和Release文件夹下。
3.将皮肤文件.ssk文件放入res文件夹下。
4.打开工程名.cpp文件,在InitInstance函数下第一句添加skinppLoadSkin("./res/Steel.ssk");
5.在对应的.h文件下添加virtual int ExitInstance();并在.cpp文件下实现
int CMyApp::ExitInstance()
{
skinppExitSkin();
return CWinApp::ExitInstance();
}
皮肤文件有很多,试了一遍发现都很一般,所以最好的美化方法我觉得还是美工做好图,一点点贴图比较好。