《送给初学者的礼物C++游戏编程起源连载三.pdf》由会员分享,可在线阅读,更多相关《送给初学者的礼物C++游戏编程起源连载三.pdf(50页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 上学吧()第 1 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 送给初学者的礼物:送给初学者的礼物:C+游戏编程起源连载三游戏编程起源连载三 第三章跟踪你的窗口和使用 GDI 简介 如果你看过了头两篇连载,这次我们将学习 WINDOWS GDI(图形设备接口)和其它一些相关的东西,象响应用户输入和处理 Windows产生的一些消息。至于显示图形,我们将接触三个课题:文本显示,绘制象素,显示位图。我们先来研究一下几个 Windows 消息的细节。重复的话:你需要 C 语言的基础知识,最好看过上两章。由于本章将使你能做一个具体的图形 DEMO,有一个源代码例程附在
2、本章后面。是用 Visual C写的和编译的。在连载一里,我们创建和注册了一个窗口类,其中有一行定义了窗口的风格(功能),是这个样子:sampleClass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;/standard settings 其中三个属性是很一般的,但这个CS_OWNDC,需要解释一下。设备上下文是一个结构,是一个表现一组图形对象和属性的结构,还有一些输出设备的设置和属性。使用设备上下文允许你直接操纵图形,上学吧()第 2 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 不用考虑低级细节。Windo
3、ws GDI 是一个图形翻译系统,是介于应用程序和图形硬件之间的一层。GDI 可以输出到任意的兼容设备,不过最常使用的设备是视频监视器、图形硬拷贝设备(如打印机或绘图仪),或者是内存中的图元文本。GDI 函数能够绘制直线、曲线、封闭的图形和文本。所有访问 GDI 的 Windows 函数都需要一个设备上下文句柄作为参数。这是非常容易做到的。你若想得到一个窗口的设备上下文句柄,你可以用这个函数:HDC GetDC(HWND hWnd /handle to a window);很简单,所有你做的是,把要操作的窗口的句柄传递给它,然后返回一个设备上下文句柄。如果你传递的是 NULL,将返回整个屏幕的
4、设备上下文(DC,以后都用 DC 表示)句柄。如果函数调用失败,将返回 NULL。处理显示图形的 DC 类型,称作显示 DC,处理打印的,称作打印 DC;处理位图数据的,称作内存 DC,还有其它一些设备 DC。感觉有点复杂吧,不要紧,这是 Windows,它的主要功能就是迷惑群众。一旦 上学吧()第 3 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 我们接触一些代码,就不会觉得难了。当你结束使用DC时,一定要释放它,也就是释放它占用的内存空间。要把这种思想贯穿到以后的编程中去,占用了内存,不用时要释放,切记!释放 DC 是一个很简单的函数:int Release
5、DC(HWND hWnd,/handle to window HDC hDC /handle to device context);若成功释放,返回值是 1,否则是 0。参数有注释,我还是说一下:HWND hWnd:你所要控制的那个窗口的句柄。如果你开始传递的是 NULL,现在还要传递 NULL。HDC hDC:DC 的句柄。在用 DC 和 GDI 进行图形显示前,我们先看看创建窗口实例时要遇到的几条重要的消息。我将要提到的四条消息是:WM_MOVE、上学吧()第 4 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ WM_SIZE、WM_ACTIVATE、WM_P
6、AINT。追踪窗口状态 头两个是很简单的。当窗口被用户移动时将发送 WM_MOVE 消息,窗口新位置的坐标储存在 lparam 中。(还记得吗,消息在 lparam 和wparam 中被进一步描述,它们是消息控制函数的参数)lparam 的低端字中存储窗口客户区左上角的坐标 x,高端字中存储坐标 y。当窗口的大小被改变时,将发送 WM_SIZE 消息。同 WM_MOVE 消息差不多,lparam 的低端字中存储客户区的宽度,高端字存储高度。同WM_MOVE 不同的是,wparam 参数也控制了一些重要的东西。它可以是下列中任意一个值:SIZE_MAXHIDE:其它的窗口被最大化了。SIZE_M
7、AXIMIZED:本窗口被最大化了。SIZE_MAXSHOW:其它的窗口被还原了。SIZE_MINIMIZED:本窗口被最小化了。上学吧()第 5 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ SIZE_RESTORED:窗口被改变了尺寸,但既没最大化,也没有最小化。当我编写窗口实例时,我通常喜欢把窗口的当前位置和大小保留在几个全局变量里。假设我们命名这些全局变量为 xPos,yPos,xSize 和ySize,你最好这样控制 WM_SIZE 和 WM_MOVE 这两个消息:if(msg=WM_SIZE)xSize=LOWORD(lparam);ySize=HI
8、WORD(lparam);if(msg=WM_MOVE)xPos=LOWORD(lparam);yPos=HIWORD(lparam);现在轮到 WM_ACTIVATE 消息了。它告诉你一个新窗口被激活。这是很有用的,因为如果出现优先的申请,你就不可能处理程序里的所 上学吧()第 6 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 有逻辑。有时,例如写一个全屏的 DIRECTX 程序,忽略WM_ACTIVATE 消息将导致你的程序出现致命的错误,可能它做了一些你不希望它做的事情。在任何情况下,守候 WM_ACTIVATE 消息从而采取行动,是一个好主意。窗口被激活
9、和被解除激活都会发出 WM_ACTIVATE 消息,我们可以通过检测 wparam 的低端字来得知是被激活还是被取消。这将有三种可能的值:WA_CLICKACTIVE:窗口被鼠标激活。WA_ACTIVE:窗口被其它东西激活。(键盘、函数调用、等等)WA_INACTIVE:窗口被解除激活。为了处理这个消息,我保留了另一个全局变量 bFocus,当接收到WM_ACTIVATE 消息,它的值将改变。示例如下:if(msg=WM_ACTIVATE)if(LOWORD(wparam)=WA_INACTIVE)focus=FALSE;上学吧()第 7 页,共 50 页 上学吧为您提供“计算机等级考试”复习
10、资料下载:http:/ else focus=TRUE;/tell Windows we handled it return(0);有两个相关联的消息 WM_KILLFOCUS 和 WM_SETFOCUS,在窗口接收到输入焦点的时候,Windows消息WM_SETFOCUS被发送给它,在失去焦点的时候则发送 WM_KILLFOCUS 消息。应用程序可以截取这些消息以得知输入焦点的任何改变情况。什么是输入焦点呢?存有输入焦点的应用程序(窗口)就是被激活的那个窗口。你就认为被激活的窗口就是输入焦点就行了。因为可能出现没有窗口具有输入焦点,所以我建议用 WM_ACTIVATE 消息跟踪你的窗口状态。
11、往下进行。WM_PAINT 消息 WN_PAINT 消息通知程序,全部或部分客户窗口需要重新绘制。当用户在最小化、重叠或调整客户窗口区域的时候,就会产生这条消息。重新绘制,你需要做两件事,首先是要用到 WM_PAINT 消息专用的一对函数,第一个是 BeginPaint()函数,这是它的原形:上学吧()第 8 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ HDC BeginPaint(HWND hwnd,/handle to window LPPAINTSTRUCT lpPaint /pointer to structure for paint informat
12、ion);在我告诉你返回值是什么之前,让我们先看看参数:HWND hwnd:需要重绘的窗口的句柄。你应该已经对于这种参数比较熟悉了。LPPAINTSTRUCT lpPaint:这是很重要的一个。是指向PAINTSTRUCT 结构的指针,该结构包含所有的要被重绘区域的信息。继续之前,我应该给你看看 PAINTSTRUCT 结构:typedef struct tagPAINTSTRUCT /ps HDC hdc;BOOL fErase;上学吧()第 9 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ RECT rcPaint;BOOL fRestore;BOOL fI
13、ncUpdate;BYTE rgbReserved32;PAINTSTRUCT;结构内的成员如下:HDC hdc BOOL fErase:指明应用程序是否应该抹去背景。如果是 FALSE,说明系统已经删除了背景。还记得在 Windows 类中我们曾经用黑色画刷定义了一个背景吗?这就意味着系统将用这个画刷抹去无效的区域。RECT rcPaint:这是最重要的一个成员。它将告诉你需要被重绘的无效区域的矩形。我将稍后告诉你 RECT 结构。BOOL fRestore,BOOL fIncUpdate,BYTE rgbReserved32:好消息,这些是保留成员,为老 Windows 服务的,所有你我都
14、不必管它 上学吧()第 10 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 们。:)现在我已经给你看了这么多,这就是 BeginPaint()函数的全部。它做了三件事儿。首先,它使窗口再次有效,直到下一次被改变,WM_PAINT 消息发出前,这个窗口都是有效的。第二,如果在窗口类(Windows class)里定义了背景画刷,就像我们做过的那样,就用这个画刷重绘无效的区域。(所谓无效,就是被改变的)第三,返回了被重绘区域的 DC 句柄。重绘的区域,是由 RECT 结构定义的:typedef struct _RECT LONG left;LONG top;LONG
15、 right;LONG bottom;RECT;我们已经指出这个结构描绘了一个矩形,但是有一件事情需要说说。RECT 包含左上角,但不包含右下角。什么意思呢?让我们先定义一个 RECT 对象:上学吧()第 11 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ RECT myRect=0,0,5,5;这个 RECT 包含象素(0,0),但是没有达到(5,5),所以矩形的右下角实际是(4,4)。看起来没有什么意义,但是你得习惯它。现在,还记得我所说的关于使用 DC 的事儿吗?一旦你用完了,你就必须释放它。用 EndPaint()函数释放。回应 WM_PAINT 消息,
16、每次调用完 BeginPaint()函数,必须匹配一个 EndPaint()函数释放 DC。这是函数的原形:BOOL EndPaint(HWND hWnd,/handle to window CONST PAINTSTRUCT*lpPaint/pointer to structure for paint data);函数通过返回 TRUE 或 FALSE 分别表明成功还是失败。有两个简单的参数:上学吧()第 12 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ HWND hWnd:就是窗口的句柄。CONST PAINSTRUCT*lpPaint:指向 PAINTS
17、TRUCT 类型的结构变量地址。同 BeginPaint()的第二个参数是一回事。不要被 CONST迷惑了,它只是保证和确认函数没有改变结构的内容。你还可以通过调用 ValidateRect()函数代替 BeginPaint()函数使得窗口再次有效。但你得手工操作一切。可能我们真的什么时候就要用到它。所以给你它的原形:BOOL ValidateRect(HWND hWnd,/handle of window CONST RECT*lpRect/address of validation rectangle coordinates);通过返回 TRUE 或 FALSE 来确定函数调用成功还是失败
18、。参数很简单:HWND hWnd 上学吧()第 13 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ CONST RECT*lpRect:是指向 RECT 结构是否有效的指针。如果你传递 NULL,则整个客户区域都是有效的。现在把以上讲到的做个样子给你看吧,假设我们已经定义了一个全局的变量 hMainWindow 作为我们的窗口句柄。if(msg=WM_PAINT)PAINTSTRUCT ps;/declare a PAINTSTRUCT for use with this message HDC hdc;/display device context for g
19、raphics calls hdc=BeginPaint(hMainWindow,&ps);/validate the window /your painting goes here!EndPaint(hMainWindow,&ps);/release the DC /tell Windows we took care of it 上学吧()第 14 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ return(0);这段代码很简单。有三个消息看起来差不多,都是处理关闭的事情的。它们是WM_DESTROY,WM_CLOSE,和 WM_QUIT。它们的确很相似,但你
20、需要知道它们之间的不同!一个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出。你知道让用户作确认或有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框。消息框的制作是很容易的,由于它用途广泛,我们还是介绍一下:int MessageBox(HWND hWnd,/handle of owner window LPCTSTR lpText,/address of text in message box LPCTSTR lpCaption,/address of title of message box 上学吧()第
21、15 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ UINT uType /style of message box);这些参数,尤其是最后一个,需要一些解释:HWND hWnd:过一会儿我将向你介绍一个不含有它的函数,我保证。LPCTSTR lpText:这是将要显示在消息框里的文本。你可以用n等调整一下格式。LPCCTSTR lpCaption:这是显示在消息框标题栏里的文本。UINT uType:这个参数可以联合使用几个不同的标记。这些标记可以根据你的目的选择,有好多 MB_打头的标记供你选择,联合使用时要用“|”分隔开。下面列出了一些常用的:按钮类 上学
22、吧()第 16 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ MB_ABORTRETRYIGNORE:建立有“Abort”、“Retry”、“Ignore”按钮的消息框。MB_OK:建立有“OK”按钮的消息框。MB_OKCANCEL:建立有“OK”和“Cancel”按钮的消息框。MB_RETRYCANCEL:建立有“Retry”、和“Cancel”按钮的消息框。MB_YESNO:建立有“Yes”和“NO”按钮的消息框。MB_YESNOCANCEL:建立有“Yes”、“No”和“Cancel”按钮的消息框。图标类 MB_ICONEXCLAMATION:加个惊叹号图
23、标。MB_ICONINFORMATION:加个消息图标。(好像是个问号)MB_ICONQUESTION:加个问号图标 上学吧()第 17 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ MB_ICONSTOP:加个停止图标。默认按钮标志 MB_DEFBUTTON1:设置第一个按钮为默认按钮。(默认按钮即消息框弹出后,直接敲回车就被按下的那个按钮)MB_DEFBUTTON2:第二个为默认按钮。MB_DEFBUTTON3:第三个为默认按钮。MB_DEFBUTTON4:第四个为默认按钮。其它的标志 MB_HELP:添加一个帮助按钮。通常按下该按钮或者敲 F1 键都将产生
24、 WM_HELP 消息。MB_RIGHT:文本右对齐。上学吧()第 18 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ MB_TOPMOST:设置消息框总在窗口的最上面。如果消息框建立失败,返回值为 0,否则是下列任一个值:IDABORT:“Abort”按钮被选择。IDCANCEL:“Cancel”按钮被选择。IDIGNORE:“Ignore”按钮被选择。IDNO:“No”按钮被选择。IDOK:“OK”按钮被选择。IDRETRY:“Retry”按钮被选择。IDYES:“Yes”按钮被选择。总之,当收到 WM_CLOSE 消息,你可以做两件事儿。一件是你接受默认的
25、处理返回一个值,你若这样做了,应用程序或窗口按照计划关闭;再者,你返回 0,应用程序或窗口将保持原样。以下是代码的基本部分:上学吧()第 19 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ if(msg=WM_CLOSE)if(MessageBox(hMainWindow,Are you sure want to quit?,Notice,MB_YESNO|MB_ICONEXCLAMATION)=IDNO)return(0);/otherwise,let the default handler take care of it WM_DESTROY 消息有点儿不同
26、。它是窗口正在关闭时发出的。当得到 WM_DESTROY 消息的时候,窗口已经从视觉上被删除。一个主窗口被关闭,并不意味着应用程序结束了,它将在没有窗口的条件下继续运行。然而,当一个用户关闭了主窗口,也就意味着他要结束应用程序,所以如果你希望应用程序结束,在收到 WM_DESTROY消息的时候,你必须发出一个 WM_QUIT 消息。你可以使用PostMessage()函数,但由于这是一个特殊的情况,就为它准备了一个特殊的函数:上学吧()第 20 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ VOID PostQuitMessage(int nExitCode);
27、参数 nExitCode 是你的应用程序返回给 Windows 的一个退出代码(通常是 0)。记住,WinMain()返回的是一个 int(实数),不是 void(空的)。nExitCode 参数的值被赋值给 wparam。WM_QUIT 消息表示要关闭应用程序,所以得到这个消息后,你应跳出循环,把 wparam 返回给 Windows。下面是一个简单的 WinMain()函数实例:int WinMain(HINSTANCE hinstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)/initialization stuff
28、goes here /main loop-infinite!while(TRUE)/check the message queue if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)上学吧()第 21 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ if(msg.message=WM_QUIT)/exit main loop on WM_QUIT break;TranslateMessage(&msg);DispatchMessage(&msg);/main program logic goes here /perform any sh
29、utdown functions here-releasing objects and such return(msg.wparam);/return exit code to Windows 绘制象素 只要你取得了显示设备上下文的句柄,就可以用 GDI 绘制象素了。上学吧()第 22 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 记住,要调用 GetDC()取得句柄。绘制单个的象素,不出意外的话,你就用 SetPixel()函数:COLORREF SetPixel(HDC hdc,/handle to device context int X,/x-coord
30、inate of pixel int Y,/y-coordinate of pixel COLORREF crColor /pixel color);返回类型 COLORREF 是我们没有讲过的。它不是一个结构,但是在表格 0 x00bbggrr 里是一个 32 位的值。Bb 是蓝色成分的 8 位值,gg是绿色,rr 是红色。高字节 00 没有用,总是 00。让我们看看函数里面的参数:HDC hdc:你将要 GetDC()得到的 DC 句柄。(DC 就是设备上下文)你只能调用 GetDC()一次,然后其它的函数也可以用这个 上学吧()第 23 页,共 50 页 上学吧为您提供“计算机等级考试”
31、复习资料下载:http:/ DC 句柄了。你每次绘制单个象素不用再取得新的 DC 句柄了。int X,Y:是象素的 x 和 y 坐标。是在客户区的坐标,(0,0)即是窗口客户区左上角的坐标,不是屏幕左上角的坐标。COLORREF crColor:象素的颜色。设置象素的颜色,用 RGB()宏最简单。RGB()括号中的三个值分别是红色、绿色和蓝色,各个颜色的值可从 0255 间取,不同的值组合成不同的颜色。如果函数调用成功,将返回一个颜色,就是你要绘制的象素的颜色。由于视频硬件的限制,返回的颜色可能与调用函数时要求的颜色并不一致。如果调用失败,返回-1。如果你要设置窗口客户区的左上角为红色,函数将
32、是这样:SetPixel(hdc,0,0,RGB(255,0,0);是在假设你已经取得了 DC 句柄 hdc 后,调用这个函数。这个函数的更快的版本是 SetPixelV():BOOL SetPixelV(上学吧()第 24 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ HDC hdc,/handle to device context int X,/x-coordinate of pixel int Y,/y-coordinate of pixel COLORREF crColor /new pixel color);参数相同,但返回类型不同。SetPixel
33、V()返回的是布尔类型,成功,TRUE;失败,FALSE。如果你没有必要使用 SetPixel()提供的额外信息,那我们当然是选择使用 SetPixelV()了。(我们总是希望快一些)还有一件事情,我们需要得到绘制好的象素的值(颜色)。没问题,使用 GetPixel()函数就解决了:COLORREF GetPixel(HDC hdc,/handle to device context int XPos,/x-coordinate of pixel int nYPos/y-coordinate of pixel 上学吧()第 25 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:
34、http:/ DC 句柄控制的区域,返回值是 CLR_INVALID。参数同 SetPixel()差不多:DC 句柄,象素的 x,y 坐标。绘制象素就说到这吧,下面看看 GDI 的文本输出。GDI 的文本输出函数 有两个关于绘制文本的函数,其中简单一点儿的是 TextOut()函数,原形是:BOOL TextOut(HDC hdc,/handle to device context int nXStart,/x-coordinate of starting position int nYStart,/y-coordinate of starting position LPCTSTR lpStr
35、ing,/pointer to string 上学吧()第 26 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ int cbString /number of characters in string);我们已经看过很多返回类型是布尔类型的函数了,意思都一样:成功TRUE,失败 FALSE。函数的参数如下:HDC hdc:DC 句柄。它既可以使 GetDC 的返回值,也可以是在处理 WM_PAINT 消息时 BeginPaint 的返回值。int nXStart,nYStart:定义客户区内字符串开始的位置。字符串中第一个字符的左上角位于坐标(xXStart,n
36、YStart)。在默认 DC 中,客户区的左上角为(0,0)。LPCTSTR lpString:要显示的字符串。由于下一个参数给出字符串的长度,所有字符串不需要空的中止符。int cbString:串中字符的个数。(字符串的长度)上学吧()第 27 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ TextOut()函数使用当前的文本颜色,背景颜色和背景类型。你若想自己改变这些,就得用如下的函数:COLORREF SetTextColor(HDC hdc,/handle to device context COLORREF crColor/text color);C
37、OLORREF SetBkColor(HDC hdc,/handle of device context COLORREF crColor/background color value);SetTextColor()函数设置当前文本颜色,SetBkColor()函数设置当前背景颜色。参数的解释是显而易见的。第一个是 DC 句柄。第二个是颜色,你当然记得可以用 RGB()宏来设置颜色。例如设置文本为蓝色:SetTextColor(hdc,RGB(0,0,255)。设置背景为白色:上学吧()第 28 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ SetBkColor
38、(hdc,RGB(255,255,255)。最后,设置背景类型用SetBkMode()函数:int SetBkMode(HDC hdc,/handle of device context int iBkMode /flag specifying background mode);第一个参数就不讲了。第二个参数 iBkMode 可以分别取两个值:TRANSPARENT 或 OPAQUE。如果取 TRANSPARENT,文本不会对背景造成影响。如选择 OPAQUE,则相反。函数的返回值是背景的模式。关于 TextOut()函数还有一点要说,你可以控制文本的排列方式,用 SetTextAlign()
39、实现:UINT SetTextAlign(HDC hdc,/handle to device context UINT fMode /text-alignment flag 上学吧()第 29 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ hdc:DC 句柄。没有什么特别的。UINT fMode:一个标志或一组标志(用“|”分开)将决定 TextOut()输出文本的对齐模式。你不可以随便组合,要合理组合。这些标志如下:TA_BASELINE:参考点将在文本的基线。TA_BOTTOM:参考点将在矩形范围的底边。TA_TOP:参考点将在矩形范围的顶部。TA_CENT
40、ER:参考点将在矩形范围的中心。TA_LEFT:参考点将在矩形范围的左边。上学吧()第 30 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ TA_RIGHT:参考点将在矩形范围的右边。TA_NOUPDATECP:当前的位置没有被文本输出函数调用,参考点被每次调用传递。TA_UPDATECP:当前的位置被每次文本函数输出调用,当前的位置作为参考点。默认的设置是 TA_LEFT|TA_TOP|TA_NOUPDATECP。如果你设置成TA_UPDATECP,后来调用的 TextOut()函数将忽略 nXStart 和 nYStart这两个参数,把文本放置在。OK,告一
41、段落,我们来看看 TextOut()函数的兄弟 DrawText():int DrawText(HDC hDC,/handle to device context LPCTSTR lpString,/pointer to string to draw int nCount,/string length,in characters LPRECT lpRect,/pointer to struct with formatting dimensions 上学吧()第 31 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ UINT uFormat /text-drawin
42、g flags);DrawText()函数能格式化文本,多种排列方式。返回值是文本象素的高度。返回 0,说明调用失败。让我们看看它的参数:HDC hDC:一样的东东。我们的好朋友 DC 句柄。LPCTSTR lpString:要显示的字符串。用双引号引起来。int nCount:字符串中字符的数量。(字符串长度)LPRECT lpRect:是 RECT 类型结构的地址,该结构包含了将要显示字符串的区域的逻辑坐标。UINT uFormat:文本格式选项,你可以用“|”符号组合。下面列出最常用到的标志:DT_BOTTOM:指定底部对齐文本。必须与 DT_SINGLELINE 组合使用。上学吧()第
43、 32 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ DT_CALCRECT:返回矩形的宽度和高度。在多文本行的情况下,DrawText()将使用 lpRect 所指向的矩形的宽度,并扩展矩形的底部直到包含文本的最后一行。在单文本行的情况中,DrawText()将改变矩形的右边界,使它包含最后一个字符。不管在那种情况下,DrawText()都返回格式化后的文本高度,但是不重新绘制文本。DT_CENTER:文本水平居中。DT_EXPANDATABS:扩充 Tab 键跳跃的字符数,默认情况下,每按一次 Tab 键跳跃 8 个字符。DT_LEFT:指定文本左对齐。DT
44、_NOCLIP:绘制屏幕时无需剪切。当使用 DT_NOCLIP 后,程序性能提高。DT_RIGHT:指定文本右对齐。DT_SINGLELINE:指定单行文本,忽略回车和换行。上学吧()第 33 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ DT_TABSTOP:设置 Tab 键停止。在 uFormat 的低端字的高阶字节(158)中存放 Tab 键每按一次跳跃的字符数。默认是 8。DT_TOP:顶部对齐文本(仅用于单行文本)。DT_VCENTER:指定垂直居中(仅对单行文本)。还有一些其它的标志,但你看到的已经足够了。有了这些,你就可以轻松驾驭文本了,但记住,是
45、以牺牲函数速度为代价的。你可以选择比较常用的 TextOut()函数。用 GDI 显示位图 位图是很容易操纵的,因为 Windows 本身就是位图。现在让我们看看到底有多容易吧!用 GDI 显示位图需要四个基本的步骤:1、得到你要操作的窗口的 DC 句柄。2、获得位图的句柄。3、为位图创建设备上下文。上学吧()第 34 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 4、传送位图。你已经知道第一步怎么做了,以前我也间接提到过第二步的做法,但没有具体说。我说过通过函数 LoadBitmap()可以得到位图资源的句柄,但它有些过时了,有一个更灵活的函数 LoadIma
46、ge()取代了它,现在让我们看看怎么使用这个新函数。原形如下:HANDLE LoadImage(HINSTANCE hinst,/handle of the instance containing the image LPCTSTR lpszName,/name or identifier of image UINT uType,/type of image int cxDesired,/desired width int cyDesired,/desired height UINT fuLoad /load flags);如果函数调用失败,返回 NULL。成功,你得到位图的句柄,意味着 上学
47、吧()第 35 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 你就可以从资源或外部文件调用位图了。注意,这个函数还可以取得光标、图标的句柄,所以返回类型只是简单的 HANDLE。在 Visual C6.0 中,你需要用 HBITMAP 类型定义位图的句柄变量,否则编译器会生气的。例如:HBITMAP hBitmap;hBitmap LoadImage();下面是 LoadImage()函数的参数说明:HINSTANCE hinst:如果你从资源调用位图,这应该是你的应用程序的实例。如果你要从外部文件调用位图,就把它设置为 NULL。LPCTSTR lpszNam
48、e:这个要么是资源标识符,记住用MAKEINTRESOURCE()宏转变数字常量;要么就是你要调用的图象的完整文件名称。UINT uType:根据你的调用对象来决定。应该是 IMAGE_BITMAP、IMAGE_CURSOR 和 IMAGE_ICON 中的一种。上学吧()第 36 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ int cxDesired,cyDesired:这是你希望的图象的尺寸。如果你都设置为 0,将是图象的真实尺寸。UINT fuLoad:这是可以组合用的标志,当然是用“|”来连接。以下是一些常用的标志:LR_CREATEDIBSECTION
49、:如果 uType 是 IMAGE_BITMAP,将导致函数返回一个 DIB(DIB,设备无关的位图)。基本的意思就是返回一个不依赖于显示设备的位图。LR_DEFAULTSIZE:对于光标和图标,如果 cxDesired 和 cyDesired都设置为 0,这个标志将启用 Windows 的默认尺寸,而不是图形的实际尺寸。LR_LOADFROMFILE:如果你要从外部文件中调入图象,你就必须用这个标志。条件允许的话,你应当尽量使用LR_CREATEDIBSECTION 和 LR_LOADFROMFILE 这两个标志。现在,你已经得到了图象(过去我们总说位图,好像不太准确,毕竟有时我们不从资源里
50、调用)的句柄,下一步你必须建立设备上下文把图象放进去。位图的应该独有的特点是:它只能被选入到内存设备上下文中。内存设备上下文被定义为一个具有显示表面的设备上下文。它 上学吧()第 37 页,共 50 页 上学吧为您提供“计算机等级考试”复习资料下载:http:/ 只存在于内存中,并且与特定的设备上下文相关。使用内存设备上下文,你必须首先创建它。CreateCompatibleDC()函数正是用于这个目的。它的一般形式如下:函数唯一的参数是与内存设备上下文相兼容的设备上下文句柄。如果内存设备上下文与视频屏幕兼容,则这个参数可以为 NULL。我们就用 NULL。如果函数失败,返回 NULL。现在,