系统调色板
系统为每个使用 调色板 的设备维护一个系统调色板。 系统调色板包含设备当前可显示或绘制的所有颜色的颜色值。 除了查看系统调色板的内容外,应用程序无法直接访问系统调色板。 相反,系统完全控制系统调色板,并且仅允许通过使用逻辑调色板进行访问。
应用程序可以使用 GetSystemPaletteEntries 函数查看系统调色板的内容。 此函数检索一个或多个条目的内容,最多检索系统调色板中的条目总数。 总计始终等于 GetDeviceCaps 函数为 SIZEPALETTE 值返回的数字,并且与任何给定逻辑调色板的最大大小相同。
尽管应用程序无法直接更改系统调色板中的颜色,但在实现逻辑调色板时,它们可能会导致更改。 为了实现调色板,系统将检查每个请求的颜色,并尝试在系统调色板中查找包含完全匹配项。 如果系统找到匹配的颜色,则会将逻辑调色板索引映射到相应的系统调色板索引。 如果系统找不到完全匹配项,则会在映射索引之前将请求的颜色复制到未使用的系统调色板条目。 如果所有系统调色板条目都在使用中,系统会将逻辑调色板索引映射到其颜色与所请求颜色最接近的系统调色板条目。 设置此映射后,应用程序无法替代它。 例如,应用程序无法使用系统调色板索引来指定颜色;仅允许使用逻辑调色板索引。
创建逻辑调色板时,应用程序可以通过将 PALETTEENTRY 结构的 peFlags 成员设置为所选值来修改索引的映射方式。 例如,无论系统调色板条目是否已包含该颜色,PC_NOCOLLAPSE标志都会指示系统立即将请求的颜色复制到未使用的系统调色板条目。 此外,PC_EXPLICIT标志指示系统将逻辑调色板索引映射到显式给定的系统调色板索引。 (应用程序在 PALETTEENTRY 结构的低序字中提供系统调色板索引。)
通过在 SelectPalette 函数中分别为 bForceBackground 参数指定 TRUE 或 FALSE,可以将调色板实现为背景调色板或前景调色板。 系统中一次只能有一个前台调色板。 如果窗口是当前活动窗口或当前活动窗口的后代,则可以实现前景调色板。 否则,无论 bForceBackground 参数的值如何,调色板都会实现为背景调色板。 前台调色板的关键属性是,在实现时,它可以覆盖除系统调色板中) 静态条目之外的所有项 (。 在实现前台调色板之前,系统通过将系统调色板中非静态的所有条目标记为未使用,从而消除所有已用条目来实现此目的。 对于背景调色板实现,系统调色板上不进行预处理。 前景调色板设置所有可能的非静态颜色。 后台调色板只能设置保持打开状态的内容,并以先到先得的方式设置优先级。 通常,应用程序使用子窗口的背景调色板,这些子窗口可实现自己的单独调色板。 这有助于最大程度地减少系统调色板发生更改的数量。
未使用的系统调色板条目是未保留且不包含静态颜色的任何条目。 保留条目使用PC_RESERVED值显式标记。 当应用程序实现调色板动画的逻辑调色板时,将创建这些条目。 静态颜色条目由系统创建,对应于默认调色板中的颜色。 GetDeviceCaps 函数可用于检索 NUMRESERVED 值,该值指定为静态颜色保留的系统调色板条目数。
由于系统调色板的条目数有限,因此为给定设备选择和实现逻辑调色板可能会影响与同一设备的其他逻辑调色板关联的颜色。 这些颜色变化在显示器上发生时尤其明显。 应用程序可以通过在每次使用前重置调色板,确保为其当前选择的逻辑调色板使用合理的颜色。 应用程序通过调用 UnrealizeObject 和 RealizePalette 函数来重置调色板。 使用这些函数会导致系统将逻辑调色板中的颜色重新映射到系统调色板中的合理颜色。