windows程序设计(C语言版)第4章-输出文字

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

ProgrammingWindows程式开发设计指南(Windows95程序设计第五版)第64页第四章输出文字在前一章,您看到了一个简单的Windows98程式,它在视窗中央,或者更准确地说,在显示区域中央显示一行文字。正如我们学到的,显示区域是整个应用程式视窗中未被标题列、视窗边框,以及可选的功能表列、工具列、状态列和卷动列占据的部分。简而言之,显示区域是视窗中可以由程式任意书写和传递视觉资讯的部分。对於程式的显示区域,您几乎可以为所欲为,只不过您不能假定视窗大小是某一特定尺寸,或者在程式执行时其大小会保持不变。如果您不熟悉图形视窗环境的程式设计,这些限制可能会使您感到惊讶:不能再假设萤幕上的一行文字一定有80个字元了。您的程式必须与其他Windows程式共用视讯显示器。Windows使用者控制程式视窗在萤幕上显示的方式。尽管可以建立固定大小的视窗(这对於计算器之类的应用是合理的),但在大多数情况下,使用者应该能够改变应用程式视窗的大小。您的程式必须能够接受指定给它的大小,并且合理地利用这一空间。这有两种可能的情况。一种可能是,程式只有仅能显示「hello」的显示区域;还有另一种可能,即程式在一个大萤幕、高解析度的系统上执行,其显示区域大得足以显示两整页文字。灵活地处理这两种极端是Windows程式设计的要点之一。这一章,我们将讲述程式在显示区域显示资讯的方式,但比上一章说明的显示方式更加复杂。当程式在显示区域显示文字或图形时,它经常要「绘制」它的显示区域。本章著重讲述绘制的方法。尽管Windows为显示图形提供了强大的图形装置介面(GDI)函式,但在这一章中,我只介绍简单文字行的显示。我也将忽略Windows能够使用的不同字体外形及字体大小,仅使用Windows的内定系统字体。这看起来似乎是一种限制,其实不然,本章涉及和解决的问题适用於所有Windows程式设计。在混合显示文字和图形时,Windows内定字体的字元大小通常决定了图形的尺寸。本章表面上是讨论绘图的方法,实际上是讨论与装置无关的程式设计基础。Windows程式只能对显示区域大小甚至字元的大小做很少的假定,相反地,必须使用Windows提供的功能来取得关於程式执行环境的资讯。绘制和更新在文字模式环境下,程式可以在显示器的任意部分输出,程式输出到萤幕ProgrammingWindows程式开发设计指南(Windows95程序设计第五版)第65页上的内容会停留在原处,不会神秘地消失。因此,程式可以丢掉重新生成萤幕显示时所需的资讯。在Windows中,只能在视窗的显示区域绘制文字和图形,而且不能确保在显示区域内显示的内容会一直保留到程式下一次有意地改写它时还保留在那里。例如,使用者可能会在萤幕上移动另一个程式的视窗,这样就可能覆盖您的应用程式视窗的一部分。Windows不会保存您的视窗中被其他程式覆盖的区域,当程式移开後,Windows会要求您的程式更新显示区域的这个部分。Windows是一个讯息驱动系统。它通过把讯息投入应用程式讯息伫列中或者把讯息发送给合适的视窗讯息处理程式,将发生的各种事件通知给应用程式。Windows通过发送WM_PAINT讯息通知视窗讯息处理程式,视窗的部分显示区域需要绘制。WM_PAINT讯息大多数Windows程式在WinMain中进入讯息回圈之前的初始化期间都要呼叫函式UpdateWindow。Windows利用这个机会给视窗讯息处理程式发送第一个WM_PAINT讯息。这个讯息通知视窗讯息处理程式:必须绘制显示区域。此後,视窗讯息处理程式应在任何时刻都准备好处理其他WM_PAINT讯息,必要的话,甚至重新绘制视窗的整个显示区域。在发生下面几种事件之一时,视窗讯息处理程式会接收到一个WM_PAINT讯息:在使用者移动视窗或显示视窗时,视窗中先前被隐藏的区域重新可见。使用者改变视窗的大小(如果视窗类别样式有著CS_HREDRAW和CS_VREDRAW位元旗标的设定)。程式使用ScrollWindow或ScrollDC函式滚动显示区域的一部分。程式使用InvalidateRect或InvalidateRgn函式刻意产生WM_PAINT讯息。在某些情况下,显示区域的一部分被临时覆盖,Windows试图保存一个显示区域,并在以後恢复它,但这不一定能成功。在以下情况下,Windows可能发送WM_PAINT讯息:Windows擦除覆盖了部分视窗的对话方块或讯息方块。功能表下拉出来,然後被释放。显示工具提示讯息。在某些情况下,Windows总是保存它所覆盖的显示区域,然後恢复它。这些情况是:滑鼠游标穿越显示区域。图示拖过显示区域。ProgrammingWindows程式开发设计指南(Windows95程序设计第五版)第66页处理WM_PAINT讯息要求程式写作者改变自己向显示器输出的思维方式。程式应该组织成可以保留绘制显示区域需要的所有资讯,并且仅当「回应要求」——即Windows给视窗讯息处理程式发送WM_PAINT讯息时才进行绘制。如果程式在其他时间需要更新其显示区域,它可以强制Windows产生一个WM_PAINT讯息。这看来似乎是在萤幕上显示内容的一种舍近求远的方法。但您的程式结构可以从中受益。有效矩形和无效矩形尽管视窗讯息处理程式一旦接收到WM_PAINT讯息之後,就准备更新整个显示区域,但它经常只需要更新一个较小的区域(最常见的是显示区域中的矩形区域)。显然,当对话方块覆盖了部分显示区域时,情况即是如此。在擦除对话方块之後,需要重画的只是先前被对话方块遮住的矩形区域。这个区域称为「无效区域」或「更新区域」。正是显示区域内无效区域的存在,才会让Windows将一个WM_PAINT讯息放在应用程式的讯息伫列中。只有在显示区域的某一部分失效时,视窗才会接受WM_PAINT讯息。Windows内部为每个视窗保存一个「绘图资讯结构」,这个结构包含了包围无效区域的最小矩形的座标以及其他资讯,这个矩形就叫做「无效矩形」,有时也称为「无效区域」。如果在视窗讯息处理程式处理WM_PAINT讯息之前显示区域中的另一个区域变为无效,则Windows计算出一个包围两个区域的新的无效区域(以及一个新的无效矩形),并将这种变化後的资讯放在绘制资讯结构中。Windows不会将多个WM_PAINT讯息都放在讯息伫列中。视窗讯息处理程式可以通过呼叫InvalidateRect使显示区域内的矩形无效。如果讯息伫列中已经包含一个WM_PAINT讯息,Windows将计算出新的无效矩形。否则,它将一个新的WM_PAINT讯息放入讯息伫列中。在接收到WM_PAINT讯息时,视窗讯息处理程式可以取得无效矩形的座标(我们马上就会看到这一点)。通过呼叫GetUpdateRect,可以在任何时候取得这些座标。在处理WM_PAINT讯息处理期间,视窗讯息处理程式在呼叫了BeginPaint之後,整个显示区域即变为有效。程式也可以通过呼叫ValidateRect函式使显示区域内的任意矩形区域变为有效。如果这呼叫具有令整个无效区域变为有效的效果,则目前伫列中的任何WM_PAINT讯息都将被删除。GDI简介要在视窗的显示区域绘图,可以使用Windows的图形装置介面(GDI)函式。Windows提供了几个GDI函式,用於将字串输出到视窗的显示区域内。我们已经ProgrammingWindows程式开发设计指南(Windows95程序设计第五版)第67页在上一章看过DrawText函式,但是目前使用最为普遍的文字输出函式是TextOut。该函式的格式如下:TextOut(hdc,x,y,psText,iLength);TextOut向视窗的显示区域写入字串。psText参数是指向字串的指标,iLength是字串的长度。x和y参数定义了字串在显示区域的开始位置(不久会讲述关於它们的详细情况)。hdc参数是「装置内容代号」,它是GDI的重要部分。实际上,每个GDI函式都需要将这个代号作为函式的第一个参数。装置内容读者可能还记得,代号只不过是一个数值,Windows以它在内部使用物件。程式写作者从Windows取得代号,然後在其他函式中使用该代号。装置内容代号是GDI函式的视窗「通行证」,有了这种装置内容代号,程式写作者就能自如地在显示区域上绘图,使图形如自己所愿地变得好看或者难看。装置内容(简称为「DC」)实际上是GDI内部保存的资料结构。装置内容与特定的显示设备(如视讯显示器或印表机)相关。对於视讯显示器,装置内容总是与显示器上的特定视窗相关。装置内容中的有些值是图形「属性」,这些属性定义了GDI绘图函式工作的细节。例如,对於TextOut,装置内容的属性确定了文字的颜色、文字的背景色、x座标和y座标映射到视窗的显示区域的方式,以及显示文字时Windows使用的字体。当程式需要绘图时,它必须先取得装置内容代号。在取得了该代号後,Windows用内定的属性值填入内部装置内容结构。在後面的章节中您会看到,可以通过呼叫不同的GDI函式改变这些预设值。利用其他的GDI函式可以取得这些属性的目前值。当然,还有其他的GDI函式能够在视窗的显示区域真正地绘图。当程式在显示区域绘图完毕後,它必须释放装置内容代号。代号被程式释放後就不再有效,且不能再被使用。程式必须在处理单个讯息处理期间取得和释放代号。除了呼叫CreateDC(函式,在本章暂不讲述)建立的装置内容之外,程式不能在两个讯息之间保存其他装置内容代号。Windows应用程式一般使用两种方法来取得装置内容代号,以备在萤幕上绘图。取得装置内容代号:方法一在处理WM_PAINT讯息时,使用这种方法。它涉及BeginPaint和EndPaintProgrammingWindows程式开发设计指南(Windows95程序设计第五版)第68页两个函式,这两个函式需要视窗代号(作为参数传给视窗讯息处理程式)和PAINTSTRUCT结构的变数(在WINUSER.H表头档案中定义)的地址为参数。Windows程式写作者通常把这一结构变数命名为ps并且在视窗讯息处理程式中定义它:PAINTSTRUCTps;在处理WM_PAINT讯息时,视窗讯息处理程式首先呼叫BeginPaint。BeginPaint函式一般在准备绘制时导致无效区域的背景被擦除。该函式也填入ps结构的栏位。BeginPaint传回的值是装置内容代号,这一传回值通常被保存在叫做hdc的变数中。它在视窗讯息处理程式中的定义如下:HDChdc;HDC资料型态定义为32位元的无正负号整数。然後,程式就可以使用需要装置内容代号的TextOut等GDI函式。呼叫EndPaint即可释放装置内容代号。一般地,处理WM_PAINT讯息的形式如下:caseWM_PAINT:hdc=BeginPaint(hwnd,&ps);使用GDI函式EndPaint(hwnd,&ps);return0;在处理WM_PAINT讯息时,必须成对地呼叫BeginPaint和EndPaint。如果视窗讯息处理程式不处理WM_PAINT讯息,则它必须将WM_PAINT讯息传递给Windows中DefWindowProc(内定视窗讯息处理程式)。DefWindowProc以下列代码处理WM_PAINT讯息:caseWM_PAINT:BeginPaint(hwnd,&ps);EndPaint(hwnd,&ps);return0;这两个BeginPaint和EndPaint呼叫之间中没有任何叙述,仅仅使先前无效区域变为有效。但以下方法是错误的:caseWM_PAINT:return0;//WRONG!!!Windows将一个WM_PAINT讯息放到讯息伫列中,是因为显示区域的一部分无效。如果不呼叫BeginPaint和EndPaint(或者ValidateRect),则Windows不会使该区域变为有效。相反,Windows将发送另一个WM_PAINT讯息,且一直发送下去。绘图资讯结构前面提到过,Windows为每个视窗保存一个「绘图资讯

1 / 43
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功