Windows程序设计(三)

本文介绍了Windows图形基础,重点讲解了设备描述表(Device Context,DC)作为应用程序、设备驱动程序和输出设备间桥梁的角色,以及显示缓冲区的概念和作用。设备描述表描述了绘图工具、字体、颜色等属性,而显示缓冲区用于窗口用户区的输出,是图形设备接口(GDI)的一部分。文章还详细讨论了如何获取和释放设备描述表句柄,以及处理WM_PAINT消息时使用显示缓冲区的方法。
摘要由CSDN通过智能技术生成
 

第三章:Windows图形基础

一:设备描述表

设备描述表是Windows应用程序、设备驱动程序和输出设备之间的桥梁,它与一个特定的设备相关联。例如,对显示器来说,设备描述表通常指显示器上的某个窗口。设备描述表描述了所选定的绘图工具、字体、字体颜色、工具在设备上绘制(或者说是映射)的方式及设备上可使用的输出区域等属性。WindowsGDI函数实际上是在设备描述表里显示正文及绘图的。 当程序显示文字或绘图时,首先必须获得一个设备描述表句柄,完成输出文字或绘图之后,还必须及时释放该句柄,否则会大大减少Windows的存储单元。释放之后的句柄就不会再有效了。一般说来,在处理某条消息时,获取和释放设备描述表句柄必须成对出现,而且不同设备描述表的获取与释放的方法也不同。而这只是所使用的函数不同而已。

 

二:显示缓冲区

Windows环境是基于图形操作的,图形设备接口(GDI)是一个在Windows应用程序中执行与设备无关的函数库。这些函数在不同的输出设备上产生图形及文字输出。

显示缓冲区是一种“设备缓冲区”,特别用于窗口用户区的输出。设备缓冲区定义设备,绘图工具及有关设备的完整信息。显示缓冲区只定义与窗口用户区有关的内容,包括输出设备、当前绘图工具、颜色,以及其它一些GDI输出函数产生输出所需的信息。在窗口中绘图,需要使用窗口的句柄,根据窗口句柄,可以得到窗口用户区的显示缓冲区句柄,所有GDI输出函数都需要一个显示缓冲区句柄,没有它就无法完成输出。

可以根据输出的需要选择获得显示缓冲区句柄的方法。画和写操作可以存在于应用程序中的任何地方(包括WinMain函数中),大多数应用程序把它们放在窗口函数中。每当对窗口的操作可能影响用户区内容时,Windows发送WM_PAINT消息给窗口函数。应用程序通常在响应WM_PAINT消息时,完成画和写。Windows发送WM_PAINT消息给窗口函数,并由它刷新用户区,因为只有应用程序才知道用户区的内容。

通常用BeginPaint函数来响应WM_PAINT消息。如果要在没有WM_PAINT消息的时刻画用户区,必须使用GetDC函数得到显示缓冲区的句柄。

当应用程序需要得到窗口的显示缓冲区时,Windows把它暂时借给应用程序。显示缓冲区是一种共享资源,一个应用程序占有它之后,其它应用程序就无法得到它。因此,应用程序在利用显示缓冲区画完窗口内容之后,就必须使用ReleaseDC函数释放它。同理,要求用EndPaint函数释放由BeginPaint函数获得的显示缓冲区。

显示缓冲区中有缺省的画笔、画刷和缺省字体。

 

1:GetDC函数

在处理非WM_PAINT消息时,应用程序获取窗口用户区设备描述表句柄使用GetDC函数,它常常用来对用户的某些动作提供反馈。例如,当用户移动鼠标光标穿越窗口时,在屏幕上画一条线。GetDC函数返回一个显示缓冲区句柄,它可以用于任何GDI输出函数。

请看下面这个程序段:

case WM_PAINT:

hDC=GetDC(hWnd);

TextOut(hDC,10,10, "Hello",5);

ReleaseDC(hWnd,hDC);

Break;

在这里,我们用设备环境句柄hDC定义了一个设备描述表句柄hDC,然后利用函数GetDC取得hWnd参数所标识窗口的显示缓冲区的显示描述表赋给hDC,再通过TextOut函数在窗口用户区(10,10)位置显示包含5个字符的字符串,使用完之后,及时用函数RealeaseDC释放这个显示描述句柄hDC。

使用GetDC函数获得显示缓冲区句柄,在窗口函数中处理WM_PAINT消息。当窗口函数接收到影响用户区内容的WM_PAINT消息时,用户区中先前已画的内容可能被擦掉。这是因为在处理WM_PAINT消息的过程中,Windows发送WM_ERASEBKGND消息给窗口函数,如果把WM_ERASEBKGND消息交给DefWindowProc函数处理,DefWindowProc函数使用这种窗口类的背景色填满受影响的区域,并擦掉原先已经画的内容。

 

2: WM_PAINT消息

在前面我们已经认识了WM_PAINT,让我们再来看一下。由于Windows是一个多任务环境,某个应用程序的窗口上面可能被对话框或窗口覆盖,当撤消这些对话框或窗口时,这个应用程序窗口中就有一个”空洞”,这个”空洞”就是一块无效的用户区域。为重新显示无效用户区域,Windows发送WM_PAINT消息实现。要求Windows发送WM_PAINT的情况有:改变窗口大小,覆盖用户区的菜单或对话框关闭,使用UpdateWindow和ScrollWindow函数等。

Windows发送WM_PAINT消息时,把它放到应用程序队列的最后,使得其它的输入能够先于WM_PAINT消息被处理。GetMessage函数也得到队列中WM_PAINT消息之后的其它消息,即只有没有其它消息的情况下,才从队列中取出WM_PAINT消息进行处理。这样做是为了让应用程序首先完成影响窗口显示结果的其它操作,不致因为频繁地执行输出操作而引起显示器的闪烁。Windows把WM_PAINT消息放在队列最后就是这个原因。

Windows并非WM_PAINT消息的唯一来源,使用InvalidateRect或InvalidateRgn函数也可以产生绘图窗口的WM_PAINT消息。这两个函数把用户区全部或部分标记成无效用户区而要求重新显示。下面的函数调用是把整个用户区标记成无效:

InvalidateRect(hWnd,NULL,TRUE);

这个例子把hWnd句柄参数指定的窗口用户区标记成无效。作为矩形结构的NULL参数指定整个用户区。TRUE参数表示擦除背景。

InvalidateRect和InvalidateRgn函数并不实际产生WM_PAINT消息。当用户区无效时,Windows就发送一个WM_PAINT消息,如果用户区的其它部分也被标记成无效,Windows就不再发送另一条WM_PAINT消息,而是把已有的无效区域合并,以便根据同一条WM_PAINT消息处理所有这些区域。

如果想改变重新显示的用户区,可以调用ValidateRect和ValidateRgn函数使相应的用户区有效,这两个函数取消原有的无效区,并在没有无效区的情况下取消队列中的WM_PAINT消息。

如果不想等待应用程序队列中的WM_PAINT消息,使用UpdateWindow函数直接发送WM_PAINT消息给指定窗口的窗口函数。如果还存在无效的用户区,UpdateWindow函数从队列中取出WM_PAINT消息,并把它直接发送给指定窗口的窗口函数。UpdateWindow函数通常用在窗口需要立即更新它的用户区,如在窗口刚被创建时使用。

用BeginPaint函数获得输出文字等的显示缓冲区句柄:

PAINTSTRUCT ps;

case WM_PAINT:

hdc=BeginPaint(hWnd,&ps);

    /* 输出操作 */

EndPaint(hWnd,&ps);

Break;

结构PAINTSTRUCT函数原型如下:

typedef struct tagPAINTSTRUCT

{

HANDLE  hDC;           //设备描述表句柄

BOOL     rErase;       //确定背景是否已被重画

RECT     rePaint;      //给出无效矩形的边界

BOOL     fRestore;     //内部使用的保留字段

BOOL     fIncUpdate;  //保留字段

BYTE     rgbReserved; //保留字段

}PAINTSTRUCT;

无效区域是一个矩形区域,它是一个RECT结构,其在window.h定义为

typedef struct tagRECT

{

int left;        //矩形左上角的X坐标

int top;    //矩形左上角的Y坐标

int right;      //矩形右下角的X坐标

int bottow;     //矩形右下角的Y坐标

}RECT

例中BeginPaint函数返回一个显示缓冲区句柄,它可用于其它的GDI输出函数中。

EndPaint函数通知Windows所有输出操作均已处理完毕,并释放显示缓冲区。

 

三:坐标系统

为了准备显示缓冲区,Windows调整设备的原点,使它位于用户区而不是显示器的左上角,并且还设置了一个剪辑区,使显示缓冲区的输出被”剪辑”到用户区。也就是说,用户区范围之外的输出并不送到显示器上。

显示缓冲区默认的坐标系统很简单,用户区的左上角是原点,即点(0,0)。向右的每个像素表示X轴方向的一个单位,向下的每个像素表示Y轴方向的一个单位。

通过修改映射模式和显示原点,可以改变坐标系统。映射模式定义坐标系统单位。Windows应用程序可通过调用SetMapMode函数来设定映射模式,其中参数定义了所采取的坐标系统单位,即将一个逻辑单位映射为设备单位的比例。设备单位可为任意个像素,英寸或毫米,还定义了设备的X轴和Y轴方向。默认的映射模式为MM_TEXT,即默认的坐标系统。当前设备描述表的映射方式可通过调用GetMapMode函数得到。通过调用SetViewPortOrg函数,可以把坐标系统原点移到任何位置。

 

1:SetMapMode函数

语法: int SetMapMode(HDC hdc,int nMapMode);

说明: 参数hDC是设备描述表,参数nMapMode是映射模式。映射共有8种映射模式,取值及含义如下:

含     义

MM_ANISOTROPIC

逻辑单位被映射成任意的物理单位,X轴和Y轴成任意比例

MM_HIENGLISH

一个逻辑单位被映射成0.001英寸,正X向右,正Y向上

MM_HIMETRIC

一个逻辑单位被映射成0.01英寸,正X向上,正Y向上

MM_ISOTROPIC

逻辑单位被映射成任意的物理单位,X轴和Y轴的变换比例相同

MM_LOENGLISH

一个逻辑单位被映射成0.01英寸,正X向右,正Y向上

MM_LOMETRIC

一个逻辑单位被映射成0.1毫米,正X向右,正Y向上

MM_TEXT

一个逻辑单位被映射成一个设备像素,正X向右,正Y向下

MM_TWIPS

一个逻辑单位被映射成打印机点的二十分之一,正X向右,正Y向上

本例用MM_ANISOTROPIC模式。这种模式把逻辑单位映射成任意的物理单位,X轴和Y轴成任意比例。

 

2:GetMapMode函数

语法: DWORD SetViewPortOrg(HDC hDC)

说明: 该函数取得当前设备描述表的映射模式。

 

3:SetViewPortOrg函数

语法: DWORD SetViewPortOrg(HDC hDC,int x,int y)

说明: 该函数为hDC设置视口原点。返回低字节是原点X坐标,高字节为原点Y坐标。

 

四:画图函数

GDI提供各种各样的输出操作,从画线到写字应有尽有。为了画线、矩形、圆、扇形和写字,可相应地调用一些函数。这些函数使用已选择的笔和刷画边框,并填写图形内部区,以及使用已选择的字体写字。

 

1:画点函数SetPixel

原型为: COLORREF SetPixel(HDC hDC,int x,int y,COLORREF cclrref);

该函数把X和Y指定的点置为clrref指定的颜色。

 

2: 画线函数LineTo与MoveTo

LineTo函数用来画线,并且通常与MoveTo函数配合使用,

如画一条从点(10,70)到点(250,100)的线:

MoveTo(hDC,10,70);

LineTo(hDC,250,100);

 

3: 矩形函数Rectangle

Rectangle函数用来画矩形。它使用已选择的笔画边框,使用已选择的刷子填满矩形内部。下面的例子画一个左上角位于点(10,20),右下角位于点(40,100)的矩形:

Rectangle(hDC,10,20,40,100);

 

4: 画圆或椭圆函数Ellipse

Ellipse函数用来画圆或椭圆。它使用已选择的笔画框,使用已选择的刷填满圆或椭圆的内部。下面的例子画一个用点(10,20)和点(40,100)构成矩形框中的椭圆:

Ellipse(hDC,10,20,40,100);

 

5: 画圆弧函数Arc

Arc函数用来画一段弧,这段弧由包围它的矩形和弧的开始点和结束点共同定义。下面的例子在点(10,90)和点(360,120)所指定的矩形中画一段弧,它的起点和终点分别是点(15,90)和点(360,90):

Arc(hDC,10,90,360,120,15,90,360,110);

弧的起点坐标和终点坐标精确地位于弧上。

 

6: 画扇形函数Pie

Pie函数用来画扇形。扇形由一段弧和两条从弧焦点到弧端点的半径组成。Pie函数使用已选择的笔画框,使已选择的刷子填满扇形内部。下面的例子画一个用点(310,30)和点(360,80)构成的矩形围成的扇形。其起点和终点分别为点(360,30)和点(360,80):

Pie(hDC,310,30,360,80,310,30,360,80);

弧的起点和终点不必精确地位于弧线上

 

五: 创建、选择和删除绘图工具

GDI提供了种类丰富的绘图工具,包括画线的笔、填满空区的刷子和写字用的字体。可以用CreatePen和CreateSolidBrush之类的函数创建这些工具,并用SelectObject函数把它们选择到显示缓冲区。用过一种绘图工具之后,应及时通过DeleteObject函数把它们删除。

 

1: 画 笔

画笔决定了线条的颜色、宽度和线型(实线、点线或点划线等)。Windows使用当前在设备描述表中已选择的画笔来画线。程序中可以选择Windows的预定义画笔,也可以选择自定义的画笔。

预定义画笔有三种:BLACK_PEN(黑色笔) 、WHITE_PEN(白色笔)和NULL_PEN(空笔),这些都在windows.h中已经定义好了,程序员可使用GetStockObject函数来选择其中的一种,系统缺省的画笔为黑色笔。Windows.h包含了HPEN的数据类型定义,使用该类型可以定义画笔句柄的变量。

仅靠系统提供的预定义画笔远远不能满足需求,应用程序可根据实际需要创建一种自定义的逻辑画笔。其步骤一般为:首先用CreatePen或CreatePenIndirect函数建立一支画笔,再调用SelectObject函数将其选入设备描述表,此后就可使用该画笔在选定的设备描述表中进行绘图操作。任何时候某一设备描述表只能有一支画笔被选入作为当前画笔,当一支画笔被选入时,原先已选入的画笔便不再有效。完成绘图操作后,可以通过调用DeleteObject来释放已建立的画笔。

 

①: 函数CreatePen()

语法:HPEN CreatePen(int fnPenStyle,int nWidth,COLORREF clrref);

说明:该函数创建一个逻辑画笔。其中fnPenStyle参数指定画笔的线型,该参数可取由windows.h定义的七个标识符之一,其含义为:

PS_SOLID

实线

PS_DASH

虚线

PS_DOT

点线

PS_DASHDOT

夹一点虚线

PS_DASHDOTDOT

夹二点虚线

PS_NULL

PS_INSIDEFRAME

线画在所有构件框架内

nWidth参数是用逻辑单位表示的画笔的宽度;clrref参数是一个COLORREF类型的颜色值,指定画笔的颜色,可用宏指令RGB构造这个值,如:

Clrref=RGB(byRed,byGreen,byBlue);

在使用CreatPen函数时,要检查其返回值,确保它是一个有效的句柄。

下面给出一段程序,说明建立、选择和释放画笔的一般方法,假定程序要用一支宽度为3的黑色笔作图,则程序如下:

HPEN hPen,hOldPen:

HPen=CreatePen(PS_SOLD,3,RGB(0,0,0));

if(hPen)

{

hOldPen=SelectObject(hDC,hPen);   //将hPen作为当前画笔

… …                             //这里进行绘图操作

SelectObject(hDC,hOldPen);        //恢复原画笔

}

DelectObject(hPen);                   //删除hPen画笔,释放空间

 

②: 函数CreatePenIndirect()

语法:HPEN CreatePenIndirect(LOGPEN FAR* lpLogPen);

说明:该函数用lpLogPen所指的LOGPEN结构中的信息创建一个逻辑画笔。LOGPEN的结构如下:

typedef struct tagLOGPEN

(

WORD         lopnStyle;

POINT        lopnWidth;

COLORREF     lopnColor;

)LOGPEN;

其中lopnStyle指定画笔线型,该参数可取下列值之一:

PS_SOLID

0

PS_DASH

1

PS_DOT

2

PS_DASHDOT

3

PS_DASHDOTDOT

4

PS_NULL

5

PS_INSIDEFRAME

6

nWidth参数是用逻辑单位表示的画笔的宽度;clrref参数是一个COLORREF类型的颜色值,指定画笔的颜色,可用宏指令RGB构造这个值。

 

2: 刷 子

当我们在绘制一些区域图形时,其内部往往需要以某种图案进行填充,这就需要选定”刷子”作为绘图工具。Windows系统不仅为用户提供了预定义刷子,而且还允许应用程序自定义刷子。

Windows系统中预定义的刷子有如下七种:

BLACK_BRUSH

黑色刷子

DKGRAY_BRUSH

深灰色刷子

GRAY_BRUSH

灰色刷子

HOLLOW_BRUSH

中空刷子,画边界而不填充

LTGRAY_BRUSH

浅灰色刷子

NULL_BRUSH

空刷子

WHITE_BRUSH

白色刷子

应用程序可以调用GetStockObject函数选用其中一个,系统缺省的刷子是白色刷子。Window.h包含了HBRUSH数据类型的定义,使用该类型就可定义刷子句柄的变量。

仅靠这七种刷子往往不能满足要求,应用程序通过调用如下几种函数创建逻辑刷子,这些函数返回值均为刷子句柄。

 

①: 函数CreateHatchBrush()

语法:HBRUSH CreateHatchBrush(int fnStyle,COLORREF clrref);

说明: 该创建一个带阴影的逻辑刷子。

FnStyle指定的阴影格式如下:

HS_BDLAGONAL

45度向上斜线组成的阴影图案(自左到右)

HS_CROSS

水平和垂直交叉组成的阴影图案

HS_DIAGCROSS

45度斜线交叉组成的阴影图案

HS_FDIAGONAL

45度向下斜线组成的阴影图案(自左到右)

HS_HORZONAL

水平线组成的阴影图案

HS_VERTICAL

垂直线组成的阴影图案

Clrref是具有COLORREF类型定义的刷子颜色值,可用宏指令RGB构造这个值。

 

②: 函数CreateSolidBrush()

语法:HBRUSH CreateSolidBrush(COLORREF,clrre);

说明:该函数创建的是一种实颜色的逻辑刷子。Clrref是具有COLORREF类型定义的刷子颜色值,可用宏指令RGB构造这个值。

同样,使用创建刷子的函数时,要检查其返回,确保它是一个有效的句柄。

一旦创建了绘图工具之后,可以SelectObject函数把它选择到显示缓冲区里。在使用显示缓冲区之前,并不一定非要创建和选择绘图工具,Windows为每个显示缓冲区提供默认的绘图工具。例如:黑色笔,白色刷子和系统字体。

DeleteObject函数用来删除不再需要的绘图工具,但不能删除一个已选进显示缓冲区的绘图工具,而是应该使用SelectObject函数恢复原有的绘图工具,然后再删除需要删除的工具。

 

3: 填 充 图 形

绘制一些需要以某种图案进行填充的区域图形时,需要选定”刷子”作为绘图工具Windows系统中预定义的刷子有七种,应用程序可以调用GetStockObject函数选用其中一个,系统缺省的刷子是白色刷子。

当靠这七种刷子不能满足要求时,应用程序通过调用Windows函数创建逻辑刷子,这些函数返回值均为刷子句柄.

 

六: 文字与字体

Windows是使用定义好的与设备无关的字符集,它没有DOS的文本方式与图形方式之分。Windows的”文本”字符也是图形,所以屏幕上所显示的用打印机或绘图仪等输出品的文本完全一样,做到”所见即所得”.

 

1: 文本绘图函数

文本绘制函数见下表:

函  数

含      义

DrawText

在一个特定矩形区中绘制某一格式的文本

ExtTextOut

在一个特定矩形区中,以当前字体写一字符串

GrayString

用灰色文本写一字符串

TabbedTextOut

写一带扩展字符的字符串

TextOut

以当前的字体写一字符串

要输出文本就离不开字体。描述一个字体的值叫做字体的文本度量(Text Metric)。TEXTMETRIC定义了结构变量tm供文本度量用。

函数GetTextMetrics可以获取一个字体文本度量并将它放入一个类型为TEXTMETRIC的数据结构中,该结构如下所示:

typedef struct tagTEXTMETRIC

{

    LONG tmHeight;               //字符高度
    LONG tmAscent;               //字符上部高度(基线以上)
    LONG tmDescent;              //字符下部高度(基线以下)
    LONG tmInternalLeading;      //由tmHeight定义的字符高度的顶部空间数目
    LONG tmExternalLeading;      //加在两行之间的空间数目
    LONG tmAveCharWidth;         //平均字符宽度
    LONG tmMaxCharWidth;         //最宽字符的宽度
    LONG tmWeight;               //字体的粗细轻重程度
    LONG tmOverhang;             //加入某些拼接字体上的附加高度
    LONG tmDigitizedAspectX;     //字体设计所针对的设备水平方向
    LONG tmDigitizedAspectY;     //字体设计所针对的设备垂直方向
    BCHAR tmFirstChar;           //为字体定义的第一个字符
    BCHAR tmLastChar;            //为字体定义的最后一个字符
    BCHAR tmDefaultChar;         //字体中所没有字符的替代字符
    BCHAR tmBreakChar;           //用于拆字的字符
    BYTE tmItalic;                //字体为斜体时非零
    BYTE tmUnderlined;            //字体为下划线时非零
    BYTE tmStruckOut;             //字体被删去时非零
    BYTE tmPitchAndFamily;        //字体间距(低4位)和族(高4位)
    BYTE tmCharSet;               //字体的字符集
     } TEXTMETRIC;
 
2: GDI字体族和字样

GDI字体族和字样表如下表所示:

字体族

字体族常量

字样

说明

Dontcare

FF_DONTCARE

System

当不能提供字体信息或字体并不重要时使用

Decorative

FF_DECORATIVE

Symbol

新奇字体

Modern

 FF_MODERN

Courer,ModernIerminal

笔画大小固定的字体,但衬线可有可无

Roman

FF_ROMAN

Roman,TimeRoman

有衬线的、笔画大小可变的罗马字体

Script

FF_SCRIPT

Script

仿手写体

Swiss

FF_SWISS

Helvetical,System

无衬线的、笔画大小可变的字体

 
①: CreateFontIndirect函数

语法:HFONT CreateFontIndirect

(

            CONST LOGFONT *lplf         // pointer to logical font structure

);

说明:参数lplf是LOGFONT结构的指针。结构中含有逻辑字体的特征信息。该函数用lplf所指的LOGFONT结构中的信息创建一种逻辑字体。

LOGFONT结构的定义如下:

typedef struct tagLOGFONT

{

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;

下面的例子用函数GreatFontIndirect来产生TimesRoman和Helevtrica逻辑字体。

case WM_PAINT:

LOGFONT LogFont;

HFONT   hHelv,hTmsRmn;

memset(&LogFont,0,sizeof(LOGFONT));

LogFont.lfHeight = 25;

LogFont.lfWidth  = 15;

LogFont.lfUnderline = 1;

LogFont.lfItalic = 1;      

lstrcpy(LogFont.lfFaceName,"Helv");

hHelv=CreateFontIndirect(&LogFont);

memset(&LogFont,0,sizeof(LOGFONT));

LogFont.lfHeight = 25;

LogFont.lfWidth  = 15;

LogFont.lfUnderline = 1;

LogFont.lfItalic = 1;

lstrcpy(LogFont.lfFaceName,"TmsRmn");

hTmsRmn=CreateFontIndirect(&LogFont);

hdc = BeginPaint(hWnd, &ps);

SelectObject(hdc,hHelv);

TextOut(hdc,20,20,"Hello",5);

SelectObject(hdc,hTmsRmn);

TextOut(hdc,5,100,"Times Roman_Underlined and Itatics",34);

EndPaint(hWnd, &ps);

break;

 

: 函数SetTextAlign

    大多数文本函数传递的参数表都要求有一个点坐标参数以定义写文本的参考点。当前文本对齐属性规定了字符串如何相对于所传递的坐标进行写。SetTextAlign函数用以设置当前文本对齐属性。

语法: UINT  SetTextAlign(

HDC hdc,             // handle to device context

UINT fMode          // text-alignment flag

);

说明: 该函数设置文本对齐方式。Hdc是参数描述表,fuAlign是文本对齐方式,下表给出该函数的水平、垂直及更新标志。

TA_LEFT(水平)TA_TOP(垂直)、及TA_NOUPDATECP(不更新)是文本对齐标志的缺省设置

返回值:低字节是原水平对齐方式,高字节是原垂直对齐方式。

文本对齐标志

          
含      义
 
水平标志
TA_CENTER
Y轴及约束矩形的中心对齐
TA_LEFT
Y轴及约束矩形的左边对齐
TA_RIGHT
Y轴及约束矩形的右边对齐
 
垂直标志
TA_BASELINE
约束矩形内字体基线及X轴对齐
TA_BOTTOM
约束矩形的底部及X轴对齐
TA_TOP
约束矩形的顶部及X轴对齐
 
更新标志
TA_NOUPDATECP
当前位置不更新
TA_UPDATECP
当前位置更新
 

: GetClientRect函数

语法: BOOL GetClientRect(

                HWND hWnd,      // handle to window

                LPRECT lpRect   // address of structure for client coordinates

);

说明: hWnd是与用户区域相关的窗口,lpRect是指向RECT结构的指针。该函数把hWnd指定的用户区域坐标(以用户坐标表示)放到lpRect指向的结构中。用户坐标是以用户区域的左上角为原点定义的。

RECT数据结构定义如下:

typedef struct _RECT

{

    LONG left;           // 矩形左上角的X坐标

    LONG top;            // 矩形左上角的Y坐标

    LONG right;          // 矩形右下角的X坐标

    LONG bottom;         // 矩形右下角的Y坐标

} RECT;

[例]在窗口屏幕的中心显示文本.

    char sname[]="Welcome you!";

    int strsize=strlen(sname);

。。。。。。

switch (message)

{

        。。。。。。

        case WM_PAINT:

            RECT rect;

            hdc = BeginPaint(hWnd, &ps);

            SetTextAlign(hdc,TA_CENTER);

            GetClientRect(hWnd,(LPRECT)&rect);

            TextOut(hdc,rect.right/2,rect.bottom/2,sname,strsize);

            EndPaint(hWnd, &ps);

            break;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值