C语言实例教程(PDF格式)-第71部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
// 将字体输出方向更改为水平方向
lf。lfEscapement=0;
dc。SelectObject(pOldFont);
font2。DeleteObject();
font2。CreateFontIndirect(&lf);
dc。SelectObject(&font2);
// 对称于直线 x=150 输出字符串 〃lfEscapement=0〃
sz=dc。GetTextExtent(〃lfEscapement=0〃);
dc。TextOut(150…sz。cx/2; 110; 〃lfEscapement=0〃);
// 更改当前字体为最细的 50 象素大小的宋体
lf。lfCharSet=134;
strcpy(lf。lfFaceName; 〃宋体〃);
lf。lfEscapement=0;
…………………………………………………………Page 558……………………………………………………………
lf。lfWeight=0;
lf。lfHeight=…50;
dc。SelectObject(pOldFont);
font2。DeleteObject();
font2。CreateFontIndirect(&lf);
dc。SelectObject(&font2);
// 输出一个 〃细〃 字
dc。TextOut(330; 10; 〃细〃);
// 在旁边使用 12 象素大小的宋体字给出当前字体的重量
dc。SelectObject(&font1);
dc。TextOut(395; 29; 〃lfWeight=0〃);
// 更改当前字体为最粗的 50 象素大小的字体
lf。lfWeight=1000;
dc。SelectObject(pOldFont);
font2。DeleteObject();
font2。CreateFontIndirect(&lf);
dc。SelectObject(&font2);
// 输出一个 〃粗〃 字
dc。TextOut(330; 80; 〃粗〃);
dc。SelectObject(&font1);
// 在旁边使用 12 象素大小的宋体字给出当前字体和重量
dc。TextOut(395; 99; 〃lfWeight=1000〃);
// 恢复设备上下文原有的 GDI 绘图对象
dc。SelectObject(pOldFont);
}
// 主窗口的 WM_CREATE 消息的处理函数
…………………………………………………………Page 559……………………………………………………………
int CMyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// 调用基类的默认消息处理函数
int iResult=CWnd::OnCreate(lpCreateStruct);
// 创建一个列表框,该列表框中给出了当前系统中安装的所有可用字体
lst。Create(LBS_STANDARD | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE;
CRect(10; 150; 480; 350); this; 1001);
// 更改列表框所用的字体为 9 磅 (12 象素) 大小的宋体
static CFont font;
font。CreatePointFont(90; 〃宋体〃);
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,我们将在下面定义该
回调函数;第四个参数为指向列表框的指针,这个参数将被传递给回
调函数,由于我们需要将可用的字体添加到列表框中,因此我们可以
很自然的将指向该列表框指针当前应用程序提供的参数传递给枚举字
体回调函数。
枚举字体回调函数的原型在程序中被声明为
int WINAPI EnumFontFamProc(const LOGFONTA *lplf;
const TEXTMETRICA *lptm; unsigned long FontType; LPARAM lParam);
…………………………………………………………Page 563……………………………………………………………
l 注意:
l 在随Visual C++ 5。0提供的Platform SDK (即Win32 SDK)中所给
出的EnumFontFamProc的原型为
l int CALLBACK EnumFontFamProc( ENUMLOGFONT FAR *lpelf; // pointer to logical
font data
l NEWTEXTMETRIC FAR *lpntm; // pointer to physical…font data
l int FontType; // type of font
l LPARAM lParam // address of application…defined data
l );
然而在本程序中使用上面所给的原型将会在编译时导致类型
不匹配。正确的回调函数的原型应该如代码清单中所给的那
样。
图9。 7 示例程序FontDemo的运行结果
在本程序中,传递给回调函数的第一个参数lplf为该字体对应的
LOGFONTA结构,最后一个参数为指向列表框的CListBox指针。第二个
参数和第三个参数在本程序中没有使用。在本程序中,枚举字体回调
函数的结构很简单,它只是将字体的字体名和相应的字符集格式化之
后添加到列表框中。为了使枚举继续进行,回调函数应该返回真值,
如果回调函数返回了FALSE,则枚举的过程将被终止。
示例程序FontDemo的运行结果如图9。7所示。
…………………………………………………………Page 564……………………………………………………………
在类CDC中定义的字体和文本函数如表所示。
表9。 5 在类CDC中定义的字体和文本函数
成员函数 描述
TextOut 在指定位置以当前选定字体绘制字符串
ExtTextOut 在指定的矩形区域内使用当前选定字体
绘制字符串
TabbedTextOu