您的位置:首页 > 其它

《Windows程序设计》读书笔记------------->>设备内容之一<<

2007-07-15 16:03 417 查看
设备内容概述

当您想在一个图形输出设备(诸如屏幕或者打印机)上绘图时,您首先必须获得一个设备内容(或者DC)的句柄。将句柄传回给程序时,Windows就给了您使用设备的权限。然后您在GDI函数中将这个句柄作为一个参数,向Windows标识您想在其上进行绘图的设备。

设备内容中包含许多确定GDI函数如何在设备上工作的目前「属性」,这些属性允许传递给GDI函数的参数只包含起始坐标或者尺寸信息,而不必包含Windows在设备上显示对象时需要的所有其它信息。例如,呼叫TextOut时,您只需要在函数中给出设备内容句柄、起始坐标、文字和文字的长度。您不必指定字体、文字颜色、文字后面的背景色彩以及字符间距,因为这些属性都是设备内容的一部分。当您想改变这些属性之一时,您呼叫一个可以改变设备内容中属性的函数,以后针对该设备内容的TextOut呼叫来使用改变后的属性。

设备内容的取得

以前有说过有很多取得设备句柄的方法,但是无论是什么方法,在最后这些设备句柄都是要释放的。
每次调用都需要在最后释放它,而且不能在使用的时候释放。

最常用的取得并释放设备内容句柄的方法是,在处理WM_PAINT消息时,使用BeginPaint和EndPaint呼叫:

hdc = BeginPaint (hwnd, &ps) ;

//其它行程序

EndPaint (hwnd, &ps) ;

变量ps是型态为PAINTSTRUCT的结构,该结构的hdc字段是BeginPaint传回的设备内容句柄。 PAINTSTRUCT结构又包含一个名为rcPaint的RECT(矩形)结构,rcPaint定义一个包围窗口显示区域无效范围的矩形。使用从BeginPaint获得的设备内容句柄,只能在这个区域内绘图。BeginPaint呼叫使该区域有效。

Windows程序还可以在处理非WM_PAINT消息时取得设备内容句柄:

hdc = GetDC (hwnd) ;

//其它行程序

ReleaseDC (hwnd, hdc) ;

这个设备内容适用于窗口句柄为hwnd的显示区域。这些呼叫与BeginPaint和EndPaint的组合之间的基本区别是,利用从GetDC传回的句柄可以在整个显示区域上绘图。当然, GetDC和ReleaseDC不使显示区域中任何可能的无效区域变成有效。

Windows程序还可以取得适用于整个窗口(而不仅限于窗口的显示区域)的设备内容句柄:

hdc = GetWindowDC (hwnd) ;

//其它行程序

ReleaseDC (hwnd, hdc) ;

这个设备内容除了显示区域之外,还包括窗口的标题列、菜单、滚动条和框架(frame)。GetWindowDC函数很少使用,如果想尝试用一用它,则必须拦截处理WM_NCPAINT消息,Windows使用该消息在窗口的非显示区域上绘图。

BeginPaint、GetDC和GetWindowDC获得的设备内容都与视讯显示器上的某个特定窗口相关。取得设备内容句柄的另一个更通用的函数是CreateDC:

hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData) ;

其它行程序

DeleteDC (hdc) ;

例如,您可以通过下面的呼叫来取得整个屏幕的设备内容句柄:

hdc = CreateDC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

有时您只是需要取得关于某设备内容的一些信息而并不进行任何绘画,在这种情况下,您可以使用CreateIC来取得一个「信息内容」的句柄,其参数与CreateDC函数相同,例如:

hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

您不能用这个信息内容句柄往设备上写东西。

使用位图时,取得一个「内存设备内容」有时是有用的:


hdcMem = CreateCompatibleDC (hdc) ;




//其它行程序




DeleteDC (hdcMem) ;

您可以将位图选进内存设备内容,然后使用GDI函数在位图上绘画。

前面已经提到过,metafile是一些GDI呼叫的集合,以二进制形式编码。您可以通过取得metafile设备内容来建立metafile:


hdcMeta = CreateMetaFile (pszFilename) ;




//其它行程序




hmf = CloseMetaFile (hdcMeta) ;



在metafile设备内容有效期间,任何用hdcMeta所做的GDI呼叫都变成metafile的一部分而不会显示。在呼叫CloseMetaFile之后,设备内容句柄变为无效,函数传回一个指向metafile(hmf)的句柄。

设备内容句柄信息的取得

设备内容信息可以通过


iValue = GetDeviceCaps (hdc, iIndex) ;

这个函数取得,和前面的SYSTEM程序里面那个函数一样iLndex也是一个告诉程序要返回怎么的整数。例如,iIndex为HORZRES时将使GetDeviceCaps传回设备的宽度(单位为图素);iIndex为VERTRES时将让GetDeviceCaps传回设备的高度(单位为图素)。

下面这个连接里面就是那个示例程序,我用SYSTEM进行了改装,就可以显示我们需要的内容了。

http://dl2.csdn.net/down4/20070715/15154745822.rar

设备的大小

假定要绘制边长为1英寸的正方形,您(程序写作者)或Windows(操作系统)需要知道视讯显示上1英寸对应多少图素。使用GetDeviceCaps函数能取得有关如视讯显示器和打印机之类输出设备的实际显示大小信息。

Windows应用程序可以使用SM_CXSCREEN和SM_CYSCREEN参数从GetSystemMetrics得到图素尺寸。从DEVCAPS1程序中您会注意到,程序可以用HORZRES(水平分辨率)和VERTRES参数从GetDeviceCaps中得到同样的值。这里「分辨率」指的是图素大小而不是每度量单位的图素数。

这些是设备大小的简单部分,现在开始复杂的部分。

前两个设备能力,HORZSIZE和VERTSIZE,文件中称为「以毫米计的实际屏幕的宽度」及「以毫米计的实际屏幕的高度」(在/Platform SDK/Graphics和Multimedia Services/GDI/Device Contexts/Device Context Reference/Device Context Functions/GetDeviceCaps中)。

在Windows的16位版本中(及在Windows NT中),Windows为HORZSIZE和VERTSIZE使用「标准」的显示大小。然而,从Windows 95开始,HORZSIZE和VERTSIZE值是从HORZRES、VERTRES、LOGPIXELSX和LOGPIXELSY值中衍生出来的。这是它的工作方式。

当您在「控制台」中使用「显示器」程序选择显示的图素大小时,也可以选择系统字体的大小。这个选项的原因是用于640×480显示的字体在提升到1024×768或更大时字太小,而您可能想要更大的系统字体。这些系统字体大小指「显示器」程序的「设定」页面卷标中的「小字体」和「大字体」。所以:当您在「控制台」的「显示」程序上选择小字体或大字体时,实际上是选择了一个假定的视讯显示分辨率,单位是每英寸的点数

在Windows程序中,您可以使用GetDeviceCaps函数取得使用者在「控制台」的「显示器」程序中选择的以每英寸的点数为单位的假定分辨率。要得到这些值(如果视讯显示器不具有正方形图素,在理论上这些值是不同的),可以使用索引LOGPIXELSX和LOGPIXELSY。LOGPIXELS指逻辑图素,它的基本意思是「以每英寸的图素数为单位的非实际分辨率」。

用HORZSIZE和VERTSIZE索引从GetDeviceCaps得到的设备能力,在文件上称为「实际屏幕的宽度,单位毫米」及「实际屏幕的高度,单位毫米」。因为这些值是从HORZRES、VERTRES、LOGPIXELSX和LOGPIXELSY值中衍生出来的,所以它们应该称为「逻辑宽度」和「逻辑高度」。公式是:

水平大小=25.4*水平像素/每英寸的点数
竖直大小=25.4*竖直像素/每英寸的点数


所以一般来说,程序返回的“真实大小”其实是不真实的,真正可以的方法是让用户自己填入显示器的大小。

关于色彩


这一节书上说的内容基本是针对以前的,和我们关系不太大,为了实用的角度,就不说了,直接记录怎么设定颜色。

我们知道一般的颜色是使用红(RED)绿(GREEN)蓝(BLUE)三种颜色组成的,而一般的每个颜色可以用一个32位的数字表示,就是0-255。或者可以用2个16进制数表示。

在大多数GDI函数呼叫中,使用COLORREF值(只是一个32位的无正负号长整数)来表示一种色彩。COLORREF值按照红、绿和蓝色的亮度指定了一种颜色,通常叫做「RGB色彩」 。

这个无正负号长整数常常称为一个「RGB色彩」。Windows表头文件WINGDI.H提供了几种使用RGB色彩值的宏。RGB宏要求三个参数分别代表红、绿和蓝值,然后将它们组合为一个无正负号长整数:

#define RGB(r,g,b) ((COLORREF)(((BYTE)(r) |

((WORD)((BYTE)(g)) << 8)) |

(((DWORD)(BYTE)(b)) << 16)))

就是说你可以用像这样的函数取得白色:RGB(255,255,255)。GetRValue、GetGValue和GetBValue宏从COLORREF值中抽取出原色值。当您在使用传回RGB色彩值的Windows函数时,这些宏有时会很方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐