Visual-C++面向对象与可视化程序设计-windows-API-text-font_第1页
Visual-C++面向对象与可视化程序设计-windows-API-text-font_第2页
Visual-C++面向对象与可视化程序设计-windows-API-text-font_第3页
Visual-C++面向对象与可视化程序设计-windows-API-text-font_第4页
Visual-C++面向对象与可视化程序设计-windows-API-text-font_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

VisualC++面向对象与可视化程序设计--------WINDOWSAPI编程之textandfont第4讲文本与字体使用定义好的与设备无关的字体集,

Windows就能维护它的设备无关性,提供“所见即所得”的好处,即屏幕所见与设备输出的文本是一样的

Windows经常使用GDI进行文本输出。在一定意义上,任何内容都可以看成图形实体图形和文本并没有明显的界限文本操作先要获得文本句柄设置字体、字符大小、字符颜色等有关属性将这些属性选入设备环境5.1设置文本的设备环境字体逻辑字体定义的字符集是设备无关的,它可以精确标度,因此得到广泛应用描述所要显示的文本的大小、类型和外形物理字体是为特殊设备设计的,因而是设备相关的Win系统提供了七种基本字体字体 说明 ANSI_FIXED ANSI标准的固定宽度的字体ANSI_VAR ANSI标准的可变宽度的字体

DEFAULT_GUI

当前GUI的缺省字体

OEM_FIXED

由标准原设备制造商(OEM)提供 DEVICE_DEFAULT 当前图形设备的字体 SYSTEM_FIXED Windows的标准固定宽度的字体SYSTEM Windows提供的可变宽度的字体

常作为缺省字体

Win用它作为系统界面字体在内定的DC中选择的字体称为系统字体,能够由GetStockObject的SYSTEM_FONT参数识别。这是固定的ANSI字符集字体。在GetStockObject中指定SYSTEM_FIXED_FONT,可以获得等宽字体的句柄。在希望所有的字体都具有相同宽度时,这是很方便的。备用字体OEM_FIXED_FONT也称为终端机字体,是Windows在MS-DOS命令提示窗口中使用的字体,它包括与原始IBM-PC扩展字符集兼容的字符集。Windows在窗口标题列、菜单和对话框的文字中使用DEFULT_GUI_FONT。当将新字体选入DC时,必须使用GetTextMetrics计算字符的高度和平均宽度。如果选择了固定字体,那么一定要注意,字符的平均宽度只是个平均值,某些字符会比它宽或比它窄。

字体型态Windows支持两大类字体,即所谓的「GDI字体」和「设备字体」。GDI字体储存在硬盘的文件中,而设备字体是输出设备本来就有的。GDI字体有三种样式:点阵字体,笔划字体和TrueType字体。点阵字体的每个字符都以位图像素图案的形式储存,每种点阵字体都有特定的纵横比和字符大小。Windows通过简单地复制图素的行或列就可以由GDI点阵字体产生更大的字符。点阵字体的主要优点是显示性能(显示速度很快)和可读性(因为是手工设计的,所以尽可能清晰)。笔划字体是以「连结点」的方式定义的一系列线段,笔划字体可以连续地缩放,这意味着同样的字体可以用于具有任何分辨率的图形输出设备,并且字体可以放大或缩小到任意尺寸。不过,它的性能不好,小字体的可读性也很糟,而大字体由于笔划是单根直线而显得很单薄。笔划字体有时也称为绘图机字体,因为它们特别适合于绘图机,但是不适合于别的场合。TrueType字体的单个字符是通过填充的直线和曲线的轮廓来定义的。Windows可以通过改变定义轮廓的坐标对TrueType字体进行缩放。当程序开始使用特定大小的TrueType字体时,Windows「点阵化」字体。这就是说Windows使用TrueType字体文件中包括的「提示」对每个字符的连结直线和曲线的坐标进行缩放。这些提示可以补偿误差,避免合成的字符变得很难看。然后,每个字符的合成轮廓用于建立字符的位图,这些位图储存在内存以备将来使用。(1)定义字体句柄变量:

HFONThF;//hF为字体的句柄(2)调函数GetStockObject获得系统字体句柄它返回的是系统的缺省字体

hF=GetStockObject():(3)调用函数SelectObject将字体选入设备环境

SelectObject(hdc,hF);选择系统字体的步骤逻辑字体逻辑字体是一个GDI对象,它的句柄储存在HFONT型态的变量中,逻辑字体是字体的描述。和逻辑画笔及逻辑画刷一样,它是抽象的对象,只有当应用程序调用SelectObject将它选入DC时,它才成为真实的对象。逻辑字体的建立和选择:可以透过调用CreateFont或CreateFontIndirect来建立逻辑字体。CreateFontIndirect函数接受一个指向LOGFONT结构的指针,该结构有14个字段。CreateFont函数接受14个参数,它们与LOGFONT结构的14个字段形式相同。它们是仅有的两个建立逻辑字体的函数。因为很难记住14个字段,所以很少使用CreateFont。5.1.2创建自定义字体若需要定义系统以外的字体,可以调用函数GreateFont自行创建HFont=CreateFont(intifHeight, //字体高度,0采用系统缺省值,使用逻辑单位

intifWidth, //字体宽度,取0则由系统根据高宽比取最佳值

intifEscapement, //每行文字相对于页底的角度,单位为0.1度

intifOrienation, //每个文字相对于页底的角度,单位为0.1度

DWORDifWeight, //字体粗细度,范围为0~1000DWORDifltalic, //如果要求字体倾斜,则取非零

DWORDifUnderline, //如果要求下划线,则取非零

DWORDifStrikeout, //如果要求中划线,则取非零

DWORDifCharset, //字体所属字符集

DWORDifOutputPrecision,//输出精度,一般取缺省值OUT_DEFAULT_PRECISDWORDifClipPrecision,//剪裁精度,常取缺省值CLIP_DEFAULT_PRECISDWORDifQuality, //输出质量,一般取缺省值DEFAULT_QUALITYDWORDifPitchAndFamily,//字体间距及系列缺省值DEFAULT_PITCH

DWORDifFaceName//字体名)可选的系统字符集:ANSI_CHARSETOEM_CHARSETSYMBOL_CHARSETDEFAULT_CHARSETSHIFTJIS_CHARSETifHeight,如果为正,就是设置单元高度;如果为负,就是设置字符高度。ifEScapement使字符串能够以一定的角度书写(但每个字符的基准线仍与水平轴平行),而ifOrientation使单个字符倾斜。要注意单位是十分之一度,逆时针方向旋转。它很容易输入一个值使范例字符串消失!因此,请使用0到-600或3000到3600之间的值。

lfWeight这个字段能够指定粗体。WINGDI.H表头文件定义了可用于这个字段的一组值.可以对标准字使用0或400,对粗体使用700。注意lfCharSet字段是唯一不用零表示默认值的字段。零值相当于ANSI_CHARSET,ANSI字符在美国和西欧使用。DEFAULT_CHARSET代码等于1,表示程序执行的机器上内定的字符集。ifFaceName这是关于字样的实际文字名称。这个字段是宽度为LF_FACESIZE(或32个字符)的字节数组。如果要得到TrueType的斜体或粗体字体,有两种方法。在lfFaceName字段中使用完整的字体名称(如TimesNewRomanItalic),或者可以使用基本名称(即TimesNewRoman),并设定lfItalic字段。例:lf.lfFaceName=“黑体”逻辑字体结构可以调用CreateFont来建立逻辑字体,它是具有14个参数的函数。一般,定义一个LOGFONT型态的结构LOGFONTlf;然后再定义该结构的字段会更容易一些。完成后,可以使用指向该结构的指针调用CreateFontIndirect: hFont=CreatFontIndirect(&lf);不必设定LOGFONT结构的每个字段。如果逻辑字体结构定义为静态变量,那么所有的字段都会初始化为0,0一般是默认值。然后,可以不用更改而直接使用这个结构,CreateFontIndirect会传回字体的句柄。LOGFONTlf;lf.lfHeight=-(int)(fabs(pt.y)/10.0+0.5);lf.lfWidth=0;lf.lfEscapement=0;lf.lfOrientation=0;lf.lfWeight=iAttributes&EZ_ATTR_BOLD?700:0;lf.lfItalic=iAttributes&EZ_ATTR_ITALIC?1:0;lf.lfUnderline=iAttributes&EZ_ATTR_UNDERLINE?1:0;lf.lfStrikeOut=iAttributes&EZ_ATTR_STRIKEOUT?1:0;lf.lfCharSet=DEFAULT_CHARSET;lf.lfOutPrecision=0;lf.lfClipPrecision=0;lf.lfQuality=0;lf.lfPitchAndFamily=0;lstrcpy(lf.lfFaceName,szFaceName);hFont=CreateFontIndirect(&lf);建立、选择和删除逻辑字体1.通过调用CreateFont或CreateFontIndirect建立逻辑字体,这些函数传回HFONT型态的逻辑字体句柄。2.使用SelectObject将逻辑字体选入设备内容,Windows会选择与逻辑字体最匹配的真实字体。3.使用GetTextMetrics(及可能用到的其它函数)确定真实字体的大小和特征。在该字体选入设备内容后,可以使用这些信息来适当地设定文字的间距。4.在使用完逻辑字体后,调用DeleteObject删除逻辑字体,当字体选入有效的设备内容时,不要删除字体,也不要删除备用字体。5.1.3设置字体和背景颜色设置字体颜色:SetTextColor(hdc,crColor);设置背景颜色:SetBkColor(hdc,crColor);crColor为设置的颜色字体及背景颜色的设置在开发过程中非常重要设置背景模式

:SetBkMode(hdc,iMode);SetBkMode(hdc,iMode);更改背景模式,其中iMode的值为OPAQUE或TRANSPARENT。内定的背景模式为OPAQUE,它表示Windows使用背景颜色来填充矩形的背景。SetBkColor(hdc,rgbColor);来改变背景颜色。rgbColor的值是转换为纯色的值。内定背景色是白色。如果两行文字靠得太近,其中一个的背景矩形就会遮盖另一个的文字。由于这种原因,通常希望内定的背景模式是TRANSPARENT。在背景模式为TRANSPARENT的情况下,Windows会忽略背景色,也不对矩形背景区域着色。Windows也使用背景模式和背景色对点和虚线之间的空隙及阴影刷中阴影间的区域着色。

5.2文本的输出过程确定后续文本坐标确定换行时文本坐标文本输出过程获取字体信息格式化文本调用函数输出文本获取字体信息输出文本之前要获取字体的信息,如字符高度等,以确定输出格式和下一行字符的位置

GetTextMetrics(hdc,&tm);//tm为TEXTMETRICS结构获取当前使用字体信息调用该函数时,系统将当前字体的信息拷贝到tm标识的TEXTMETRICS结构中系统定义的TEXTMETRICS的结构如下:typedefstructtagTEXTMETRIC{

//tmLONGtmHeight;

//字符高度LONGtmAscent;

//字符基线以上高度LONGtmDescent; //字符基线以下高度LONGtmInternalLeading; //tmHeight制订的字符高度顶部的控件LONGtmExternalLeading; //行与行之间的间隔LONGtmAveCharWidth; //平均字符宽度LONGtmMaxCharWidth; //最大字符宽度LONGtmWeight; //字符的粗细度LONGtmOverhang; //合成字体间附加的宽度LONGtmDigitizedAspectX; //为输出设备设计的X轴尺寸LONGtmDigitizedAspectY; //为输出设备设计的Y轴尺寸BCHARtmFirstChar; //字体中第一个字符值BCHARtmLastChar; //字体中最后一个字符值BCHARtmDefaultChar; //代替不在字体中字符的字符BCHARtmBreakChar; //作为分割符的字符BYTEtmItalic; //非0则表示字体为斜体BYTEtmUnderlined; //非0则表示字体有下划线BYTEtmStruckOut; //非0则表示字符为删除字体BYTEtmPitchAndFamily; //字体间距和字体族BYTEtmCharSet; //字符集}TEXTMETRICReturn字体选入DC后从GetTextMetrics函数中获得的信息。除了数值化的纵横比以外,Windows复制到TEXTMETRIC结构的所有大小值都以逻辑单位表示。tmInternalLeading

用于显示重音符号;基线上的高度为tmAscent;基线下的高度为tmDescent;tmHeight=tmAscent+tmDescent被称为单元高度(cellheight);tmHeight-tmInternalLeading被称为字符高度(characterheight)CreateFont的第1个参数ifHeight,如果为正,就是设置单元高度;如果为负,就是设置字符高度。tmWeight范围从0到999。实际上,这个字段为400时是标准字体,700时是粗体。tmOverhang:Windows在合成斜体或粗体时添加到点阵字体字符的额外宽度量(逻辑单位)tmBreakChar:在调整文字时,Windows和程序用于确定单字断开的字符。如果不用一些奇怪的东西(例如EBCDIC字体),它就是32-空格符tmPitchAndFamily:低四位是表示字体某些特征的旗标,例如是否定宽、是否矢量字体、是否设备字体等。由在WINGDI.H中定义的标识符指出格式化文本(1)确定后续文本坐标换行时确定下一行文本的坐标需要格式化处理的情况在文本行中确定后续文本的坐标确定后续文本的坐标,应先获取当前的字符串的宽度,

该工作由GetTextExtentPoint32函数完成,并把它存储于一个SIZE结构中。BooLGetTextExtentPoint32(

HDChdc,

LPCTSTRlpszString,//指定的字符串

intnLength, //字符串中的字符数

LPSIZElpSize

//返回字符串宽度及高度的SIZE数据结构的地址)SIZE数据结构的定义typedefstructtagSIZE{LONGcx;

LONGcy;

}SIZE;例如,X轴起始坐标为cx0,后续文本起始坐标cx1为:

cx1=cx0+size.cx;Return(2)确定换行时文本坐标字符的高度与行间隔均存储在tm指向的TEXTMETRICS结构中,换行时Y轴上文本的起始坐标cy为:

cy=tm.tmHeight+tm.tmExternalLeading;Return通过计算当前行文本字符的高度与行间隔之和,即可得到换行时文本的起始坐标文本输出

常用的文本输出函数TextOut原型如下:BOOLTextOut(

HDChdc,

intX,intY, //X,Y为用户区中字符串的起始坐标

LPCTSTRlpstring,//lpstring为显示的字符串

intnCount //nCount为字符串中的字节数

);TextOut

以坐标X,Y为起点,输出字节数为nCount、名为lpstring中的字符串例如:把一种字体选入DC,现在要写入文字:TCHAR*szText[]=TEXT("Hello,howareyou?");希望文字从垂直坐标yStart开始,页边距由坐标xLeft和xRight设定。任务是计算文字开始处的水平坐标的xStart值。如果文字以定宽字体显示,那么这项任务就相当容易,但通常不是这样的。首先得到字符要串的文字宽度:GetTextExtentPoint32(hdc,szText,lstrlen(szText),&size);如果size.cx比(xRight-xLeft)大,这一行就太长了,不能放在页边距内。假定它能放进去。要向左对齐文字,只要把xStart设定为与xLeft相等,然后写入文字:TextOut(hdc,xStart,yStart,szText,lstrlen(szText));现在可以把size.cy加到yStart中写下一行文字了。要向右对齐文字,用以下公式计算xStart:xStart=xRight-size.cx;

居中文字用以下公式:xStart=(xLeft+xRight-size.cx)/2;在左右页边距内分散对齐文字。页边距之间的距离是(xRight-xLeft)。如不调整,文字宽度就是size.cx。两者之差xRight-xLeft-size.cx,必须在字符串的三个空格字符处平均配置。可以调用SetTextJustification(hdc,xRight-xLeft-size.cx,3)第二个参数是字符串内空格字符中需要分配的空间量。第三个参数是空格字符的数量,这里为3。现在把xStart设定与xLeft相等,用TextOut写入文字:TextOut(hdc,xStart,yStart,szText,lstrlen(szText));文字会在xLeft和xRight页边距之间分散对齐。无论何时调用SetTextJustification,如果空间量不能在空格字符中平均分配,它就会累积一个错误值。这将影响后面的GetTextExtentPoint32调用。每次开始新的一行,都必须通过调用SetTextJustification(hdc,0,0);来清除错误值。SetTextAlign函数用于对指定DC设置文本排列方式,其原型如下:UINTSetTextAlign(HDChdc,UINTfMode);TA_LEFT、TA_RIGHT和TA_CENTER旗标影响使用xStart在水平方向上定位字符串的方式。默认值是TA_LEFT。如果在SetTextAlign函数中指定了TA_RIGHT,则后面的TextOut调用会将字符串的最后一个字符定位于xStart,如果指定了TA_CENTER,则字符串的中心位于xStart。类似地,TA_TOP、TA_BOTTOM和TA_BASELINE旗标影响字符串的垂直位置。TA_TOP是默认值,它意味着字符串的字母顶端位于yStart,使用TA_BOTTOM意味着字符串位于yStart之上。可以使用TA_BASELINE定位字符串,使基准线位于yStart。基准线是如小写字母p、q、y等字母下部的线。DrawText,不指定坐标的起始位置,而是通过RECT结构型态定义希望显示文字的区域,其原型如下:

intDrawText(HDChDC,LPCTSTRlpString,intnCount,LPRECTlpRect,UINTuFormat);

DrawText需要指向字符串的指针和字符串的长度。在DrawText中使用以NULL结尾的字符串,可以将iCount设定为-1,Windows会自动计算字符串的长度。当uFormat设定为0时,Windows会将文字解释为一系列由carriagereturn字符(‘\r’或0x0D)或linefeed字符(‘\n’或0x0A)分隔的行。文字从矩形的左上角开始,carriagereturn字符或linefeed字符被解释为换行字符,因此Windows会结束目前行而开始新的一行。新的一行从矩形的左侧开始,在上一行的下面空开一个字符的高度(没有外部间隔)。可以使用uFormat参数更改DrawText的缺省操作,uFormat由一个或多个旗标组成。DT_LEFT(默认值)指定了左对齐的行,DT_RIGHT指定了向右对齐的行,而DT_CENTER指定了位于矩形左边和右边中间的行。因为DT_LEFT的值是0,所以如果只需要左对齐,就不需要包含标识符。在显示多行文字时,Windows通常只在carriagereturn字符或linefeed字符处换行。然而,如果行的长度超出了矩形的宽度,则可以使用DT_WORDBREAK旗标,它使Windows在行内字的末尾换行。对于单行或多行文字的显示,Windows会把超出矩形的文字部分截去。段落具有选择并建立逻辑字体的能力后,就可以处理文字格式了。这个程序包括以四种方式之一来把文字的每一行放在页边距内:左对齐、向右对齐、居中或分散对齐-即从页边距的一端到另一端,文字间距相等。如果处理整个段落,就必须从头开始并扫描字符串来寻找空格字符。每当碰到一个空格(或其它能用于断开一行的字符),需调用GetTextExtentPoint32来确定文字是否能放入左右页边距之间。当文字超出允许的空间时,就要退回上一个空白。现在,已经能够确定一行的字符串了。如果想要分散对齐该行,调用SetTextJustification和TextOut,清除错误值,并继续下一行。5.3文本操作实例【例4-1】在用户窗口上输出几行字符串,当窗口接收到WM_PAINT消息后,显示的文本每次都被重新刷新。#include<windows.h>#include<stdlib.h>#include<string.h>longWINAPIWndProc(

HWNDhWnd,

UINTiMessage,

UINTwParam,

LONGlParam

);BOOLInitWindowsClass(HINSTANCEhInstance);BOOLInitWindows(HINSTANCEhInstance,intnCmdShow);HWNDhWndMain;//主函数intWINAPIWinMain(

HINSTANCEhInstance,

HINSTANCEhPrevInstance,

LPSTRlpCmdLine,

intnCmdShow){

MSGMessage;

if(!InitWindowsClass(hInstance)) returnFALSE;

if(!InitWindows(hInstance,nCmdShow))returnFALSE;

while(GetMessage(&Message,0,0,0))//消息循环

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}

returnMessage.wParam;}//消息处理函数longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam){

staticlongnXChar,nCaps,nYChar;

HDChDC;//定义指向设备上下文的句柄

shortx;

TEXTMETRICtm;

shortLnCount=6;

PAINTSTRUCTPtStr;//定义指向包含绘图信息的结构体变量

staticchar*textbuf[]= {

"ThisistheFirstline",

"Thisisthesecondline",

"Thisisthethirdline",

"Thisisthefourthline",

"Thisisthefifthline",

"Thisisthesixthline"

};输出的文本内容switch(iMessage)//处理消息

{caseWM_CREATE:

//处理窗口创建消息

hDC=GetDC(hWnd);

//获取当前设备表句柄

GetTextMetrics(hDC,&tm); //获取字体信息

nXChar=tm.tmAveCharWidth; //获取字符宽度

nYChar=tm.tmHeight+tm.tmExternalLeading;

nCaps=(tm.tmPitchAndFamily&1?3:2)*nXChar/2;

ReleaseDC(hWnd,hDC); //释放当前设备句柄

return0;

caseWM_PAINT: //处理重画消息

hDC=BeginPaint(hWnd,&PtStr); //开始绘画

for(x=0;x<LnCount;x=x+1) //输出文本

TextOut(hDC,nXChar,nYChar*(1+x),textbuf[x],lstrlen(textbuf[x]));

EndPaint(hWnd,&PtStr); return0;

caseWM_DESTROY: //结束应用程序

PostQuitMessage(0); return0;default: //其他消息处理程序

return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}}BOOLInitWindowsClass(HINSTANCEhInstance) //初始化窗口类{

WNDCLASSWndClass; …………;

WndClass.style=CS_HREDRAW|CS_VREDRAW;

returnRegisterClass(&WndClass);}BOOLInitWindows(HINSTANCEhInstance,intnCmdShow)//初始化窗口{

HWNDhWnd;

hWnd=CreateWindow("WinText",//生成窗口

"文本显示示例程序",

WS_OVERLAPPEDWINDOW, …….; NULL);

if(!hWnd) returnFALSE;

hWndMain=hWnd;

ShowWindow(hWnd,nCmdShow); //显示窗口

UpdateWindow(hWnd);

returnTRUE;}【例4-2】本程序通过在窗口中分五行分别显示五行文本,以说明在窗口的用户区中输出文本的方法。本例题的源代码如下:#include<windows.h>#include<string.h>#include<stdlib.h>#include<stdio.h>LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,

HINSTANCEhPrevInst,LPSTRlpszCmdLine,intnCmdShow){

HWNDhwnd;

MSGMsg;

WNDCLASSwndclass;

charlpszClassName[]="文本输出";

charlpszTitle[]="EXAMPLEFORTHETEXTOUTPUT";

wndclass.style=0;

…………;

wndclass.lpszClassName=lpszClassName;if(!RegisterClass(&wndclass)) {MessageBeep(0);returnFALSE; }hwnd=CreateWindow( lpszClassName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL);ShowWindow(hwnd,nCmdShow);UpdateWindow(hwnd);while(GetMessage(&Msg,NULL,0,0)) {

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}returnMsg.wParam;}LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage, WPARAMwParam,LPARAMlParam){

HDChdc;HFONThF_black,hF_big; //定义两种字体句柄PAINTSTRUCTps;TEXTMETRICtm; //定义一个TEXTMETRIC结构,用以记录字体信息charlpsz_1[]=这是一行红色的、字体为SYSTEM_FONT的文字,红色代表未来。";charlpsz_2[]=现在显示的是自定义字体,颜色为绿色,绿色代表生机勃勃。";charlpsz_3[]=现在展现在您面前的是蓝色的粗体字,蓝色代表广阔的海洋和天空。";charlpsz_4[]="当前字体为大号、斜体并带有下划线的文字。";charlpsz_5[]="现在您掌握了字体的操作了吗?";charlpsz_6[]="祝您成功!";intX=0,Y=0;SIZEsize; //定义一个SIZE类型的结构switch(message){

caseWM_PAINT: hdc=BeginPaint(hwnd,&ps); SetTextColor(hdc,RGB(255,0,0)); //设置文本颜色为红色

GetTextMetrics(hdc,&tm);//获取缺省字体,写入tm结构中

TextOut(hdc,X,Y,lpsz_1,strlen(lpsz_1));//用当前字体输出文本

Y=Y+tm.tmHeight+100*tm.tmExternalLeading; //计算换行时下一行文本的输出坐标

hF_black=CreateFont( //创建自定义字体

20, //字体的高度

0, //由系统根据高宽比选取字体最佳宽度值

0, //文本的倾斜度为0,表示水平

0, //字体的倾斜度为0

FW_HEAVY, //字体的粗度,FW_HEAVY为最粗

0, //非斜体字

0, //无下划线

0, //无删除线

ANSI_CHARSET, //表示所用的字符集为ANSI_CHARSET OUT_DEFAULT_PRECIS, //输出精度为缺省精度

CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度

DEFAULT_QUALITY, //输出质量为缺省值

DEFAULT_PITCH|FF_DONTCARE,//字间距和字体系列使用缺省值

"粗体字"); //字体名称

SetTextColor(hdc,RGB(0,255,0)); //设置文本颜色为绿色

SelectObject(hdc,hF_black); //将自定义字体选入设备环境

GetTextMetrics(hdc,&tm);//获取字体的信息,写入tm结构中

TextOut(hdc,X,Y,lpsz_2,strlen(lpsz_2));//用当前字体输出文本

//换行继续输出文本,计算新行的起始Y坐标位置

Y=Y+tm.tmHeight+10*tm.tmExternalLeading; GetTextExtentPoint32(hdc,lpsz_2,strlen(lpsz_2),&size); //获取字符串/的宽度

SetTextColor(hdc,RGB(0,0,255)); //设置文本颜色为蓝色

TextOut(hdc,X,Y,lpsz_3,strlen(lpsz_3));//当前字体输出文本

X=0; //计算下一行文本的输出起始坐标

Y=Y+tm.tmHeight+20*tm.tmExternalLeading;hF_big=CreateFont //引入新字体

(30, //字体高度

0, 0, 0,

FW_NORMAL, 1, //定义斜体

1, //定义输出时带下划线

0,

ANSI_CHARSET, //所使用的字符集

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "大号字"

);

SelectObject(hdc,hF_big);//将自定义字体选入设备环境

SetTextColor(hdc,RGB(155,155,155)); //设置文本颜色

Y=Y+tm.tmHeight+20*tm.tmExternalLeading;

TextOut(hdc,X,Y,lpsz_4,strlen(lpsz_4));//输出文本

SetTextColor(hdc,RGB(255,0,0));//设置文本颜色为红色

X=0; //设定输出文本的X坐标位置

Y=Y+tm.tmHeight+30*tm.tmExternalLeading;

TextOut(hdc,X,Y,lpsz_5,strlen(lpsz_5)); //输出文本

//在该行继续输出文本

GetTextExtentPoint32(hdc,lpsz_5,strlen(lpsz_5),&size); //获取字符串的宽度

X=X+size.cx; //获取起始坐标

TextOut(hdc,X,Y,lpsz_6,strlen(lpsz_6)); //输出文本

EndPaint(hwnd,&ps); break;caseWM_DESTROY: DeleteObject(hF_black); //退出窗口时删除自定义字体

DeleteObject(hF_big); PostQuitMessage(0); break;

default: returnDefWindowProc(hwnd,message,wParam,lParam);

}

return0;}【4-3】在窗口中显示出26个英文字母,从左向右字母依次位置提高10个象素单位,并且颜色变为红色,然后回到正常位置;当到达最右端后改变方向从右向左依次变成红色并位置提高10个象素单位。在窗口的第二行显示26个字母,字体从正常到斜体,颜色从黑色到天蓝色不断变换。如图所示。用nChar标志红色跳起字母在26个字母的位置用bRight,bLeft标志当前移动方向,初始化bRight=TRUE,bLeft=FALSE本例题要解决动态显示问题:首先处理第一行字符:在WM_PAINT消息处理程序中,在得到了设备环境句柄hDC后,调用用户自定义的函数CreateFont(hDC,nHeight,bItalic),第一个参数hDC是设备环境句柄,第2个参数nHeight是字体高度,第3个参数bItalic是斜字体的标志变量WM_CREATE消息处理程序定时器调用SetTimer(…)创建WM_TIMER消息处理程序调用InvalidateRect(…)刷新用户区发送WM_PAINT消息实现动态显示下面这段程序按照黑色的字体输出从字符串开头到当前位置的字符串:

Y=tm.tmExternalLeading+10; //设置输出字符的Y坐标

for(i=0;i<nChar;i++){SetTextColor(hDC,RGB(0,0,0)); //设置字体的颜色为黑色

X=X+tm.tmAveCharWidth*2; //设置输出字符的X坐标

TextOut(hDC,X,Y,&lpsz_1[i],1);//输出从第0个到第nChar-1个字符

}下面输出当前位置上的字符,当前位置的字符位置提高10个象素单位,字体颜色为红色:

SetTextColor(hDC,RGB(255,0,0));//设置字体的颜色为红色

X=X+tm.tmAveCharWidth*2; //设置输出字符的X,Y坐标

Y=tm.tmExternalLeading; //提高10个像素

hF=CreateFont(hDC,40,0); //创建字体

SelectObject(hDC,hF); //选入字体

TextOut(hDC,X,Y,&lpsz_1[nChar],1);//输出第nChar个字符

Y=tm.tmExternalLeading+10; for(i=nChar+1;i<nCharlen;i++) {SetTextColor(hDC,RGB(0,0,0));//设置字体的颜色为黑色

X=X+tm.tmAveCharWidth*2;//设置输出字符的X坐标

TextOut(hDC,X,Y,&lpsz_1[i],1); //输出后面的字符

}下面设置bRight和bLeft的值。

if(nChar==nCharlen) //当输出到最后的一个字符时

{

bRight=FALSE; //改变红色字移动的方向为向左

bLeft=TRUE; } else(nChar==0) //当输出到第一个字时

{

bRight=TRUE; //改变红色字移动的方向为向右

bLeft=FALSE; } if(bRight==TRUE)nChar++; elsenChar--;如果nChar==等于字符串长度=〉已到了字符串末尾,将bRight置为True字符长度==0时,已到了最左端,将bLeft置为True;当bRight=True时字符位置标志nChar加1,当bLeft=True时,字符位置标志变量减1。下面输出第2行字符:在WM_PAINT处理程序中,加入下列代码:

hF=CreateFont(hDC,40,bItalic); //创建字体.大小为40

SelectObject(hDC,hF); //选入字体

X=tm.tmAveCharWidth*2; //设置输出位置

Y=tm.tmHeight*2; if(bItalic==TRUE)

SetTextColor(hDC,RGB(0,0,0)); else SetTextColor(hDC,RGB(0,255,255)); TextOut(hDC,X,Y,lpsz_1,strlen(lpsz_1)); //输出

if(bItalic==TRUE)

bItalic=FALSE; else bItalic=TRUE;调用用户自定义函数CreateFont(…)创建斜体字,确定输出位置根据bItalic的状态设置字体的颜色。当bItalic为真时,输出斜体天蓝色字符;为假时,输出正常黑色字体最后对bItalic取反,在下一次显示与此次不同的另一种效果。【例4-4】将一首四句的古诗从右到左竖排输出。要求窗口每次接收到WM_PAINT消息时都刷新显示的文本。

#include<windows.h>#include<stdlib.h>#include<string.h>longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam);BOOLInitWindowsClass(HINSTANCEhInstance);BOOLInitWindows(HINSTANCEhInstance,intnCmdShow);HWNDhWndMain;

//主函数intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance, LPSTRlpCmdLine,intnCmdShow){ MSGMessage; if(!InitWindowsClass(hInstance))

returnFALSE; if(!InitWindows(hInstance,nCmdShow)) returnFALSE; while(GetMessage(&Message,0,0,0)) //消息循环

{TranslateMessage(&Message);

DispatchMessage(&Message); } returnMessage.wParam;}longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam)1.{staticlongnXChar,nCaps,nYChar;2.

intpointx,pointy,inti,j;3.HDChDC;

//定义指向设备环境的句柄 4.TEXTMETRICtm;

//存放字体各种属性的结构体变量5.PAINTSTRUCTPtStr;

//指向包含绘图信息的结构体变量6.staticchar*textbuf[4]={{"故人西辞黄鹤楼"},{"烟花三月下扬州"}, {"孤帆远影碧空尽"},{"唯见长江天际流"}};7.switch(iMessage)

//处理消息8.{ caseWM_CREATE:

//处理窗口创建消息9.

hDC=GetDC(hWnd);

//获取当前设备表句柄10.

GetTextMetrics(hDC,&tm);

//获取字体信息11.

nXChar=tm.tmAveCharWidth;

//获取字符宽度12.

nYChar=tm.tmHeight+tm.tmExternalLeading; //字符

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论