《C语言实例教程(PDF格式)》第118章


lst。SetFont(&font);
// 设置列表框的制表符位置为 200 个对话框单位
lst。SetTabStops(200);
// 枚举当前系统的所有可用字体,将指向列表框的 CListBox 对象的指针作为应用程序提供 

// 参数传递给枚举字体回调函数 EnumFontFamProc
EnumFontFamilies(::GetDC(GetSafeHwnd()); NULL; EnumFontFamProc; (LPARAM)(&lst));
return iResult;

// 枚举字体时的回调函数,该函数将系统的所有可用字体及其字符集添加到列表框中,
// 由应用程序提供的参数 lParam 提供了指向该列表框的 CListBox 对象的指针
int WINAPI EnumFontFamProc(const LOGFONTA * lplf;
const TEXTMETRICA *lptm; unsigned long FontType; LPARAM lParam)

CListBox *pList=(CListBox*)lParam;
CString str;
// 将当前字体的字体名 (FaceName) 和字符集 (CharSet) 添加到列表框中
…………………………………………………………Page 560……………………………………………………………
str。Format(〃FACENAME: %s tCHARSET: %d〃; lplf…》lfFaceName; lplf…》lfCharSet);
pList…》AddString(str);
return TRUE; // 返回 TRUE 以继续字体枚举的过程,返回 FALSE 将终止字体枚举的过程

我们先来看重绘消息处理函数OnPaint,一开始时,我们调用了CDC类 
的成员函数GetCurrentFont,该成员函数返回当前设备上下文所使用 
的字体,其返回值是一个指向CFont对象的指针,然后,我们通过该 
指针调用CFont类的成员函数GetLogFont,该成员函数将字体的信息 
填入到一个LOGFONT结构中。在下面的步骤中,我们通过修改该结构 
的成员来创建新的字体对象。首先,我们创建一个CFont对象font1, 
font1使用了12个象素大小的宋体字,在程序中它主要用来输出一些 
标识文本。这里,我们先在LOGFONT结构对象lf在相关成员中填入新 
的值,再以该结构对象为参数来调用CFont类的成员函数 
CreateFontIndirect创建相应的GDI字体对象。这里我们将lfCharSet 
成员修改为134 ,这个值可以通过本程序的运行结果得出,lfWidth 
成员修改为0,这样将使用默认的字符纵横比得到字符的宽度。
在下面过程中,我们按照类似的方法创建一大小为20个象素的Times
New Roman字体,与刚才不同的是,我们将结构对象lf的 
lfEscapement成员的值设置为400,这样,文本将以向上倾斜40度 
(lfEscapement的值的单位为1/10度)的角度进行输出。接着,我们将 
该字体对象通过CDC的成员函数SelectObject选入设备上下文中作为 
设备上下文的当前字体。CDC类的成员函数GetTextExtent可以在输出 
一个字符串之前得到该输出字符串的大小,以便于我们可以恰当的安 
排字符串的输出位置。需要注意的是,通过该成员函数得到的度量值 
不会受到我们在lfEscapement中设置的值的影响。在程序示例中,我 
们通过成员函数GetTextExtent得到字符串〃lfEscapement= 400〃在输 
出时的长度和宽度,然后根据所得的结果计算得出以40度角输出文本 
串的合适的起始位置,最后调用CDC类的成员函数TextOut以当前字体 
输出字符串〃lfEscapement= 400〃。
l 注意:
l 不管当前的lfEscapement值如何,函数TextOut总是以输出字符串 
的第一个字符的起始位置的坐标作为其前两个参数。
l 在Windows 95中,lfEscapement和lfOrientation总是具有相同的 
值,而在Windows NT中,两者在某些情况下可以不相同。
…………………………………………………………Page 561……………………………………………………………
l 设置lfFaceName时应该使用库函数strcpy,不要犯这样的错误:
l lfFaceName=〃宋体〃;
此外,如果为lfFaceName设置了新值,同时也应该将 
lfCharSet的值设置为相匹配的字符集。如果字符集与字体名 
不相匹配,将会导致设置不起作用。
要使文本向下倾斜输出,我们只需简单的将lfEscapement设置为负 
值。如下面的代码所示:
// 将字体输出方向更改为向下倾斜 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〃);
上面的代码摘自应用程序FontDemo 。
l 注意:
l 在调用font2的CreateFontIndirect成员函数创建新的字体对象之 
前,应该先调用其成员函数DeleteObject删除该字体对象,而当 
一个GDI图形对象正为设备上下文所使用时,我们不能删除该图形 
对象,因此在前面的代码 中,我们在删除在font2原有的字体对象 
之前先将设备上下文的字体对象进行复原。
接着在消息处理函数CMyWnd::OnPaint中,我们又将lfEscapement成 
员的值设置为0,输出字符串〃lfEscapement=0〃以示对比。
在随后的代码中,我们演示了lfWeight成员的不同值对字体的笔划粗 
细的影响。我们先将lfWeight值设置为0,以50象素的宋体字绘制了 
一个 “细”字,然后再将lfWeight值设置为1000,以同样大小和同种 
字体绘制了一个 “粗”字。通过如图9。7的输出结果,我们看到字体 
笔划的粗细发生的明显的变化。
…………………………………………………………Page 562……………………………………………………………
在OnPaint函数返回之前,不要忘记恢复设备上下文的原有字体对 
象,指向该对象的CFont指针在前面被保存到了名为pOldFont的指针 
变量中。我们仍然使用SelectObject将其选入当前设备上下文。
上面我们来看示例程序FontDemo的另一个主要的功能板块,即枚举当 
前系统中所安装的所有字符并将它添加到一个列表框中。
首先我们在窗口CMyWnd的WM_CREATE消息的处理函数OnCreate中调用 
CListBox对象lst (该对象被定义为类CMyWnd的成员变量)的Create成 
员函数。在Create成员函数中,我们指定了列表框的样式包括了 
LBS_USETABSTOPS,该样式允许在列表项中使用制表符,这些制表符 
在显示时会被扩展到指定的位置。
接着,我们将列表框所使用的字体设置为9磅大小的宋体字。这里我 
们调用的是CFont对象的CreatePointFont成员函数来创建字体。当需 
要创建的指定磅值大小的某种字体时,使用CreatePointFont成员函 
数要方便得多,因此该函数仅需要三个参数,并且,第三个参数在很 
多情况下可以省略。这样,我们就可以避开填写复杂的LOGFONT结 
构。
在改变列表框字体的同时,我们将列表框中的当前制表位设置为200 
个对话框单位,对话框单位是一种在控件和对话框使用的度量单位。 
每4个水平对话框单位等于以系统字体显示的字符的平均宽度,我们 
还将这个宽度称作对话框基本单位。对话框基本单位的具体量值可以 
通过API函数GetDialogBaseUnits得到,该函数返回值的低位字代表 
对话框水平基本单位,高位字代表对话框垂直基本单位。
紧接着我们调用了API函数EnumFontFamilies来枚举系统中的所有可 
用字体,该函数使用4个参数,第一个参数为枚举所使用设备上下文 
句柄,我们使用API函数GetDC来得到代表当前窗口的客户区;为了枚 
举系统中的所有字体,我们将第二个参数设置为NULL;第三个参数为 
枚举字体回调函数,这里为EnumFontFamProc,我们将在下面定义该
小说推荐
返回首页返回目录