📄 chap11_1.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>11.1调色板</title>
</head>
<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>
<table border="0" width="615" cellspacing="0" cellpadding="0">
<tr>
</b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
<tr>
<td width="377" bgcolor="#15397D" height="20"></td>
<td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">电脑报Visual
C++网络教程</font></a></span></td>
</tr>
</table>
</center></div><font FACE="Times New Roman" SIZE="3"><b><p ALIGN="CENTER"></b></font><font FACE="Times New Roman" size="4" color="#3973DE">11.1</font><font size="4" color="#3973DE">调色板</font><font FACE="Times New Roman" size="4"></p>
<p ALIGN="CENTER"></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font></b><font color="#3973DE" FACE="Times New Roman" SIZE="3">11.1.1
</font><font SIZE="3" color="#3973DE">调色板的原理</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">PC</font><font SIZE="3">机上显示的图象是由一个个像素组成的,每个像素都有自己的颜色属性。在</font><font FACE="Times New Roman" SIZE="3">PC</font><font SIZE="3">的显示系统中,像素的颜色是基于</font><font FACE="Times New Roman" SIZE="3">RGB</font><font SIZE="3">模型的,每一个像素的颜色由红</font><font FACE="Times New Roman" SIZE="3">(B)</font><font SIZE="3">、绿</font><font FACE="Times New Roman" SIZE="3">(G)</font><font SIZE="3">、蓝</font><font FACE="Times New Roman" SIZE="3">(B)</font><font SIZE="3">三原色组合而成。每种原色用</font><font FACE="Times New Roman" SIZE="3">8</font><font SIZE="3">位表示,这样一个的颜色就是</font><font FACE="Times New Roman" SIZE="3">24</font><font SIZE="3">位的。以此推算,</font><font FACE="Times New Roman" SIZE="3">PC</font><font SIZE="3">的</font><font FACE="Times New Roman" SIZE="3">SVGA</font><font SIZE="3">适配器可以同时显示</font><font FACE="Times New Roman" SIZE="3">2<sup>24</sup></font><font SIZE="3">约一千六百多万种颜色。</font><font FACE="Times New Roman" SIZE="3">24</font><font SIZE="3">位的颜色通常被称作真彩色,用真彩色显示的图象可达到十分逼真的效果。</p>
<p ALIGN="JUSTIFY">但是,真彩色的显示需要大量的视频内存,一幅</font><font FACE="Times New Roman" SIZE="3">640</font><font SIZE="3">×</font><font FACE="Times New Roman" SIZE="3">480</font><font SIZE="3">的真彩色图象需要约</font><font FACE="Times New Roman" SIZE="3">1MB</font><font SIZE="3">的视频内存。由于数据量大增,显示真彩色会使系统的整体性能迅速下降。为了解决这个问题,计算机使用调色板来限制颜色的数目。调色板实际上是一个有</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">个表项的</font><font FACE="Times New Roman" SIZE="3">RGB</font><font SIZE="3">颜色表,颜色表的每项是一个</font><font FACE="Times New Roman" SIZE="3">24</font><font SIZE="3">位的</font><font FACE="Times New Roman" SIZE="3">RGB</font><font SIZE="3">颜色值。使用调色板时,在视频内存中存储的不是的</font><font FACE="Times New Roman" SIZE="3">24</font><font SIZE="3">位颜色值,而是调色板的</font><font FACE="Times New Roman" SIZE="3">4</font><font SIZE="3">位或</font><font FACE="Times New Roman" SIZE="3">8</font><font SIZE="3">位的索引。这样一来,显示器可同时显示的颜色被限制在</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">色以内,对系统资源的耗费大大降低了。</p>
<p ALIGN="JUSTIFY">显示器可以被设置成</font><font FACE="Times New Roman" SIZE="3">16</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">64K</font><font SIZE="3">、真彩色等显示模式,前两种模式需要调色板。在</font><font FACE="Times New Roman" SIZE="3">16</font><font SIZE="3">或</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">色模式下,程序必须将想要显示的颜色正确地设置到调色板中,这样才能显示出预期的颜色。图</font><font FACE="Times New Roman" SIZE="3">11.1</font><font SIZE="3">显示了调色板的工作原理。使用调色板的一个好处是不必改变视频内存中的值,只需改变调色板的颜色项就可快速地改变一幅图象的颜色或灰度。</p>
<p ALIGN="JUSTIFY">在</font><font FACE="Times New Roman" SIZE="3">DOS</font><font SIZE="3">中,调色板的使用不会有什么问题。由于</font><font FACE="Times New Roman" SIZE="3">DOS</font><font SIZE="3">是一个单任务操作系统,一次只能运行一个程序,因此程序可以独占调色板。在</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">环境下,情况就不那么简单了。</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">是一个多任务操作系统,可以同时运行多个程序。如果有几个程序都要设置调色板,就有可能产生冲突。为了避免这种冲突,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">使用逻辑调色板来作为使用颜色的应用程序和系统调色板(物理调色板)之间的缓冲。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="center"></font><img src="T11_1.gif" alt="T11_1.tif (194188 bytes)" WIDTH="520" HEIGHT="282"><font SIZE="3"></p>
<p ALIGN="center">图</font><font FACE="Times New Roman" SIZE="3">11.1 </font><font SIZE="3">调色板工作原理</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </p>
<p ALIGN="JUSTIFY">在</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">中,应用程序是通过一个或多个逻辑调色板来使用系统调色板(物理调色板)。在</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">色系统调色板中,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">保留了</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种颜色作为静态颜色,这些颜色用作显示</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">界面,应用程序一般不能改变。缺省的系统调色板只包含这</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种静态颜色,调色板的其它项为空。应用程序要想使用新的颜色,必须将包含有所需颜色的逻辑调色板实现到系统调色板中。在实现过程中,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">首先将逻辑调色板中的项与系统调色板中的项作完全匹配,对于逻辑调色板中不能完全匹配的项,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">将其加入到系统调色板的空白项中,系统调色板总共有</font><font FACE="Times New Roman" SIZE="3">236</font><font SIZE="3">个空白项可供使用,若系统调色板已满,则</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">将逻辑调色板的剩余项匹配到系统调色板中尽可能接近的颜色上。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">每个设备上下文都拥有一个逻辑调色板,缺省的逻辑调色板只有</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种保留颜色,如果要使用新的颜色,则应该创建一个新的逻辑调色板并将其选入到设备上下文中。但光这样还不能使用新颜色,程序只有把设备上下文中的逻辑调色板实现到系统调色板中,新的颜色才能实现。在逻辑调色板被实现到系统调色板时,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">会建立一个调色板映射表。当设备上下文用逻辑调色板中的颜色绘图时,</font><font FACE="Times New Roman" SIZE="3">GDI</font><font SIZE="3">绘图函数会查询调色板映射表以把像素值从逻辑调色板的索引转换成系统调色板的索引,这样当像素被输出到视频内存中时就具有了正确的颜色值。图</font><font FACE="Times New Roman" SIZE="3">11.2</font><font SIZE="3">说明了这种映射关系,从图中读者可以体会到逻辑调色板的缓冲作用。在该图中,</font><font FACE="Times New Roman" SIZE="3">GDI</font><font SIZE="3">绘图函数使用逻辑调色板的索引</font><font FACE="Times New Roman" SIZE="3">1</font><font SIZE="3">中的颜色来绘图,通过查询调色板映射表,得知系统调色板中的第</font><font FACE="Times New Roman" SIZE="3">23</font><font SIZE="3">号索引与其完全匹配,这样实际输出到视频内存中的像素值是</font><font FACE="Times New Roman" SIZE="3">23</font><font SIZE="3">。注意图中还演示了颜色的不完全匹配,即逻辑调色板中的索引</font><font FACE="Times New Roman" SIZE="3">15</font><font SIZE="3">和系统调色板中的索引</font><font FACE="Times New Roman" SIZE="3">46</font><font SIZE="3">。</p>
<p ALIGN="JUSTIFY">每个要使用额外颜色的窗口都会实现自己的逻辑调色板,逻辑调色板中的每种颜色在系统调色板中都有相同或相近的匹配。调色板的实现优先权越高,匹配的精度也就越高。</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">规定,活动窗口的逻辑调色板</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">如果有的话</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">具有最高的实现优先权。这是因为活动窗口是当前与用户交互的窗口,应该保证其有最佳的颜色显示。非活动窗口的优先权是按</font><font FACE="Times New Roman" SIZE="3">Z</font><font SIZE="3">顺序自上到下确定的</font><font FACE="Times New Roman" SIZE="3">(Z</font><font SIZE="3">顺序就是重叠窗口的重叠顺序</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">。活动窗口有权将其逻辑调色板作为前景调色板实现,非活动窗口则只能实现背景调色板。</font><font FACE="Times New Roman" SIZE="3"></p>
</font><font SIZE="3"><b><div align="center"><center><table border="2" cellpadding="2" cellspacing="0" width="100%" bgcolor="#55C8FF">
<tr>
<td width="100%"></b>提示:术语活动窗口</font><font FACE="Times New Roman" SIZE="3">(Active window)</font><font SIZE="3">或前台窗口</font><font FACE="Times New Roman" SIZE="3">(Foreground window)</font><font SIZE="3">是指当前与用户交互的窗口,活动窗口的顶端的标题条呈高亮显示,而非活动窗口的标题条则是灰色的。活动窗口肯定是一个顶层窗口</font><font FACE="Times New Roman" SIZE="3">(Top-level window)</font><font SIZE="3">,顶层窗口是指没有父窗口或父窗口是桌面窗口的窗口,这种窗口一般都有标题和边框,主要包括框架窗口和对话框。术语重叠窗口是指作为应用程序主窗口的窗口,我们可以把对话框看成是一种特殊的重叠式窗口。</font></td>
</tr>
</table>
</center></div><p ALIGN="JUSTIFY"><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="center"></font></b><font SIZE="3"><img src="T11_2.gif" alt="T11_2.tif (192888 bytes)" WIDTH="520" HEIGHT="303"></font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="center"></font><font SIZE="3">图</font><font FACE="Times New Roman" SIZE="3">11.2
</font><font SIZE="3">调色板的映射关系</font><b><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font></b><font color="#3973DE" FACE="Times New Roman" SIZE="3">11.1.2
</font><font SIZE="3" color="#3973DE">调色板的创建和实现</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">MFC</font><font SIZE="3">的</font><font FACE="Times New Roman" SIZE="3">CPalette</font><font SIZE="3">类对逻辑调色板进行了封装。该类的成员函数</font><font FACE="Times New Roman" SIZE="3">CreatePalette</font><font SIZE="3">负责创建逻辑调色板,该函数的声明为:</p>
<blockquote>
<blockquote>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BOOL CreatePalette(
LPLOGPALETTE lpLogPalette ); //</font><font SIZE="3">成功则返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">。</p>
</blockquote>
</blockquote>
</blockquote>
<p ALIGN="JUSTIFY">参数</font><font FACE="Times New Roman" SIZE="3">lpLogPalette</font><font SIZE="3">是一个指向</font><font FACE="Times New Roman" SIZE="3">LPLOGPALETTE</font><font SIZE="3">结构的指针,</font><font FACE="Times New Roman" SIZE="3">LPLOGPALETTE</font><font SIZE="3">结构描述了逻辑调色板的内容,该结构的定义为:</p>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">typedef struct
tagLOGPALETTE { </p>
<p ALIGN="JUSTIFY">WORD palVersion; //Windows</font><font SIZE="3">版本号,一般是</font><font FACE="Times New Roman" SIZE="3">0x300</p>
<p ALIGN="JUSTIFY">WORD palNumEntries; //</font><font SIZE="3">调色板中颜色表项的数目</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">PALETTEENTRY
palPalEntry[1]; //</font><font SIZE="3">每个表项的颜色和使用方法</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">} LOGPALETTE;</p>
</blockquote>
<p ALIGN="JUSTIFY"></font><font SIZE="3">结构中最重要的成员是</font><font FACE="Times New Roman" SIZE="3">PALETTEENTRY</font><font SIZE="3">数组,数组项的数目由</font><font FACE="Times New Roman" SIZE="3">palNumEntries</font><font SIZE="3">成员指定。</font><font FACE="Times New Roman" SIZE="3">PALETTEENTRY</font><font SIZE="3">结构对调色板的某一个颜色表项进行了描述,该结构的定义为:</p>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">typedef struct
tagPALETTEENTRY {</p>
<p ALIGN="JUSTIFY">BYTE peRed; //</font><font SIZE="3">红色的强度</font><font FACE="Times New Roman" SIZE="3">(0~255</font><font SIZE="3">,下同</font><font FACE="Times New Roman" SIZE="3">)</p>
<p ALIGN="JUSTIFY">BYTE peGreen; //</font><font SIZE="3">绿色的强度</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BYTE peBlue; //</font><font SIZE="3">蓝色的强度</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BYTE peFlags; </p>
<p ALIGN="JUSTIFY">} PALETTEENTRY;</p>
</blockquote>
<p ALIGN="JUSTIFY"></font><font SIZE="3">成员</font><font FACE="Times New Roman" SIZE="3">peFlags</font><font SIZE="3">说明了颜色表项的使用方法,在一般应用时为</font><font FACE="Times New Roman" SIZE="3">NULL</font><font SIZE="3">,若读者对</font><font FACE="Times New Roman" SIZE="3">peFlags</font><font SIZE="3">的详细说明感兴趣,可以查看</font><font FACE="Times New Roman" SIZE="3">Visual C++</font><font SIZE="3">的联机帮助。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">可以看出,创建调色板的关键是在</font><font FACE="Times New Roman" SIZE="3">PALETTEENTRY</font><font SIZE="3">数组中指定要使用的颜色。这些颜色可以是程序自己指定的特殊颜色,也可以从</font><font FACE="Times New Roman" SIZE="3">DIB</font><font SIZE="3">位图中载入。逻辑调色板的大小可根据用户使用的颜色数来定,一般不能超过</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">个颜色表项。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">CreatePalette</font><font SIZE="3">只是创建了逻辑调色板,此时调色板只是一张孤立的颜色表,还不能对系统产生影响。程序必需调用</font><font FACE="Times New Roman" SIZE="3">CDC::SelectPalette</font><font SIZE="3">把逻辑调色板选入到要使用它的设备上下文中,然后调用</font><font FACE="Times New Roman" SIZE="3">CDC::RealizePalette</font><font SIZE="3">把逻辑调色板实现到系统调色板中。函数的声明为:</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -