C语言实例教程(PDF格式)-第70部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
dc。SelectObject(pOldFont);
}
图9。 6 示例程序BrushDemo的运行结果
以前几节讲述的方法编译并链接上面的应用程序,运行结果如图9。6
所示。
第四节 字体对象
MFC类CFont封装了Windows图形设备接口中的字体对象。字体对象决
定的设备上下文中进行文本输出的字符样式。在使用字体对象的时
候,我们一般先创建一个CFont对象,然后调用CreateFont、
CreateFontIndirect、CreatePointFont及CreatePointFontIndirect
之一的成员函数来对该字体对象进行初始化。
9。4。1 创建字体对象
创建字体对象的最方便的方法是使用CreatePointFont函数,
CreatePointFont函数仅需三个参数,其原型如下:
BOOL CreatePointFont( int nPointSize; LPCTSTR lpszFaceName; CDC* pDC = NULL );
第一个参数nPointSize以十分之一磅为单位设置字体的大小,磅是印
刷行业中的常用度是单位,1磅=1/72英寸≈0。03528厘米。磅这个单
位在涉及图形和文本输出的Windows应用程序中被大量的使用,因此
我们应该熟知它和其它常用度量单位之间的换算关系。在后面的部分
中我们还会讨论到在Windows编程中还会使用到的其它度量单位以及
…………………………………………………………Page 550……………………………………………………………
它们之间的换算关系。
参数lpszFaceName指定了创建字体对象所使用的字体名,pDC指向一
个设备上下文对象,函数CreatePointFont将以磅表示的字体大小转
换为pDC所指向的设备上下文中相应的逻辑单位。如果指针pDC为空,
函数CreatePointFont将字体大小以设备单位表示。
9。4。2 LOGFONT结构
在Windows内部,字体是以一个名为LOGFONT的结构来表示的。结构
LOGFONT的定义如下:
typedef struct tagLOGFONT { // lf
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName'LF_FACESIZE';
} LOGFONT;
各成员的含义如下:
lfHeight: 以逻辑单位指定字体字符元
(character cell)或字符的高
…………………………………………………………Page 551……………………………………………………………
度。字符高度值为字符元高度值
减去内部行距 (internal
leading)值。当lfHeight大于0
时,字体映射程序将该值转换为
设备单位,并将它与可用字体的
字符元高度进行匹配;当该参数
为0时,字体映射程度将使用一个
匹配的默认高度值;如果参数的
值小于0,则将其转换为设备单
位,并将其绝对值与可用字体的
字符高度进行匹配。
对于任何一种情况,字体映射程
度最终得到的字体高度值不会超
过所指定的值。以MM_TEXT映射模
式下,字体高度值和磅值有如下
的换算公式:
lfHeight=…MulDiv(PointSize;
GetDeviceCaps(hDC; LOGPIXELSY); 72);
lfWidth: 以逻辑单位指定字体字符的平均
宽度。如果lfWidth的值为0,则
根据设备的纵横比从可用字体的
数字转换纵横中选取最接近的匹
配值,该值通过比较两者之间的
差异的绝对值得出。
lfEscapement: 以十分之一度为单位指定每一行
文本输出时相对于页面底端的角
度。
ifOrientation: 以十分之一度为单位指定字符基
线相对于页面底端的角度。
lfWeight: 指定字体重量。在Windows中,字
体重量这个术语用来指代字体的
粗细程度。lfWeight的范围为0到
1000,正常情况下的字体重量为
400,粗体为700。如果lfWeight
为0,则使用默认的字体重量。
…………………………………………………………Page 552……………………………………………………………
lfItalic: 当lfItalic为TRUE时使用斜体
lfUnderline: 当lfUnderline为TRUE时给字体添
加下划线
lfStrikeOut: 当lfStrikeOut为TRUE时给字体添
加删除线
lfCharSet: 指定字符集。可以使用下面的预
定义值:
ANSI_CHARSET
OEM_CHARSET
SYMBOL_CHARSET
UNICODE_CHARSET
其中OEM字符集是与操作系统相关
的。
lfOutPrecision: 指定输出精度。输出精度定义了
输出与所要求的字体高度、宽
度、字符方向等的接近程度。它
可以为下面的值之一:
OUT_CHARACTER_PRECIS
OUT_DEFAULT_PRECIS
OUT_STRING_PRECIS
OUT_STROKE_PRECIS
lfClipPrecision: 指定剪辑精度。剪辑精度定义了
当字符的一部分超过剪辑区域时
对字符的剪辑方式,它可以为下
列值之一:
CLIP_CHARACTER_PRECIS
CLIP_DEFAULT_PRECIS
…………………………………………………………Page 553……………………………………………………………
CLIP_STROKE_PRECIS
lfQuality: 定义输出质量。输出质量定义了
图形设备接口在匹配逻辑字体属
性到实际的物理字体的所使用的
方式,它可以为下列值之一:
DEFAULT_QUALITY (默认质量)
DRAFT_QUALITY (草稿质量)
PROOF_QUALITY (正稿质量)
lfPitchAndFamily: 指定字体的字符间距和族。最低
两位指定字体的字符间距为以下
值之一:
DEFAULT_PITCH
FIXED_PITCH
VARIABLE_PITCH
第4到7位指定字体族为以下值之
一:
FF_DECORATIVE
FF_DONTCARE
FF_MODERN
FF_ROMAN
FF_SCRIPT
FF_SWISS
这些值的具体含义可以参考
Visual C++中关于结构LOGFONT的
文档。
字符间距和字体族可以使用逻辑
…………………………………………………………Page 554……………………………………………………………
或(OR)运算符来进行组合。
lfFaceName: 一个指定以NULL结尾的字符串的
指针,它指定的所用的字体名。
该字符串的长度不得超过32个字
符,如果lfFaceName为NULL,图
形设备接口将使用默认的字体
名。
9。4。3 使用字体对象和枚举系统中的所有字体
示例程序FontDemo演示了LOGFONT结构和CFont对象的使用。此外,在
该示例程序中,我们还演示了如何获得当前系统中已安装的所有可用
字体,这些信息是通过API函数EnumFontFamilies和自定义的字体枚
举回调函数EnumFontFamProc来得到,并放入程序主窗口内的列表框
中的。
#include
#include
#include
#define DegToRnd(x) (x/180。*3。14159)
int WINAPI EnumFontFamProc(const LOGFONTA *lplf;
const TEXTMETRICA *lptm; unsigned long FontType; LPARAM lParam);
// 派生应用程序类
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// 派生窗口类
class CMyWnd : public CFrameWnd
{
…………………………………………………………Page 555……………………………………………………………
public:
CListBox lst;
protected:
// 声明消息处理函数
afx_msg void OnPaint();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP();
};
// 初始化应用程序实例
BOOL CMyApp::InitInstance()
{
// 创建应用程序的主窗口
CMyWnd *pWnd=new CMyWnd;
pWnd…》Create(NULL; 〃字体示例〃);
// 显示应用程序主窗口并刷新其客户区
pWnd…》ShowWindow(SW_SHOW);
pWnd…》UpdateWindow();
// 在主窗口关闭时终止应用程序的执行线程
m_pMainWnd=pWnd;
return TRUE;
}
// 声明唯一的应用程序对象
CMyApp MyApp;
// 应用程序主窗口的消息映射
BEGIN_MESSAGE_MAP(CMyWnd; CWnd)
ON_WM_CREATE()
…………………………………………………………Page 556……………………………………………………………
ON_WM_PAINT()
END_MESSAGE_MAP()
// 应用程序主窗口的重绘函数
void CMyWnd::OnPaint()
{
// 获得窗口的客户区设备上下文句柄
CPaintDC dc(this);
// 设置字体输出背景为透明
dc。SetBkMode(TRANSPARENT);
// 获得设备上下文所使用的当前字体
LOGFONT lf;
dc。GetCurrentFont()…》GetLogFont(&lf);
CFont font1; font2;
CFont *pOldFont; // 保存设备上下文最初使用的字体对象
// 创建 font1 为 12 象素宋体
lf。lfCharSet=134;
lf。lfHeight=…12;
lf。lfWidth=0;
strcpy(lf。lfFaceName; 〃宋体〃);
font1。CreateFontIndirect(&lf);
// 更改当前字体为 20 象素的 Times New Roman,并且向上倾斜 40 度
lf。lfCharSet=0;
strcpy(lf。lfFaceName; 〃Times New Roman〃);
lf。lfEscapement=400;
lf。lfHeight=…20;
font2。CreateFontIndirect(&lf);
…………………………………………………………Page 557……………………………………………………………
pOldFont=dc。SelectObject(&font2);
// 获得字符串 〃lfEscapement= 400〃 在输出时的宽度和高度
CSize sz=dc。GetTextExtent(〃lfEscapement= 400〃);
// 计算字符串合适的输出位置
dc。TextOut(10; 10+int(sz。cx*sin(DegToRnd(40))); 〃lfEscapement= 400〃);
// 将字体输出方向更改为向下倾斜 40 度
lf。lfEscapement=…400;
dc。SelectObject(pOldFont);
font2。DeleteObject();
font2。CreateFontIndirect(&lf);
dc。SelectObject(&font2);
// 计算字符串合适的输出位置
dc。TextOut(290…int(sz。cx*cos(DegToRnd(40))); 10; 〃lfEscapement=…400〃);
// 将字体输出方向更改为水平方向
lf。lfEscapement=0;
dc。SelectObject(pOldFont);
font2。DeleteObject();