windows 程序设计 调色板

调色板

这时就需要使用Windows调色盘管理器(在Windows 3.0中提出)了。Windows保留了256种颜色中的20种,而允许应用程序修改其余的236种。(在某些情况下,应用程序最多可以改变256种颜色中的254种-只有黑色和白色除外-但这有一点麻烦)。Windows为系统保留的20种颜色(有时称为20种「静态」颜色)如表16-1所示。

表16-1 256种颜色显示模式中的20种保留的颜色

图素位

RGB值

颜色名称

图素位

RGB值

颜色名称

00000000

00 00 00

11111111

FF FF FF

00000001

80 00 00

暗红

11111110

00 FF FF

00000010

00 80 00

暗绿

11111101

FF 00 FF

洋红

00000011

80 80 00

暗黄

11111100

00 00 FF

00000100

00 00 80

暗蓝

11111011

FF FF 00

00000101

80 00 80

暗洋红

11111010

00 FF 00

绿

00000110

00 80 80

暗青

11111001

FF 00 00

00000111

C0 C0 C0

亮灰

11111000

80 80 80

暗灰

00001000

C0 DC C0

美元绿

11110111

A0 A0 A4

中性灰

00001001

A6 CA F0

天蓝

11110110

FF FB F0

乳白色



程序16-1所示的GRAYS1程序没有使用Windows调色盘管理器,而尝试用正常显示的65级种阶作为从黑到白的多种彩色的「来源」。

部分核心代码:
                          for (i = 0 ; i < 65 ; i++)
        
                          {
        
                                                 rect.left             = i * cxClient / 65 ;
        
                                                 rect.top              = 0 ;
        
                                                 rect.right            = (i + 1) * cxClient / 65 ;
        
                                                 rect.bottom           = cyClient ;
        

                                  hBrush = CreateSolidBrush (RGB(min (255, 4 * i),    
        
                                                          min (255, 4 * i),
        
                                                          min (255, 4 * i))) ;
        
                                                 FillRect (hdc, &rect, hBrush) ;
        
                                                 DeleteObject (hBrush) ;
        
                         }

在WM_PAINT消息处理期间,程序呼叫了65次FillRect函数,每次都使用不同灰阶建立的画刷。灰阶值是RGB值(0,0,0)、(4,4,4)、(8,8,8)等等,直到最后一个值(255,255,255)。最后一个值来自CreateSolidBrush函数中的min宏。

程序16-2所示的GRAYS2程序用较少的外部程序代码验证了调色盘管理器中最重要的函数和消息。

在wm_create 中调用

         LOGPALETTE    * plp = malloc (sizeof (LOGPALETTE) + 64 * sizeof (PALETTEENTRY)) ;


          plp->palVersion    = 0x0300 ;//兼容 windows 3.0
          plp->palNumEntries = 65 ;    //表示调色盘中的项目数


          for (i = 0 ; i < 65 ; i++)
          {
               plp->palPalEntry[i].peRed   = (BYTE) min (255, 4 * i) ;
               plp->palPalEntry[i].peGreen = (BYTE) min (255, 4 * i) ;
               plp->palPalEntry[i].peBlue  = (BYTE) min (255, 4 * i) ;
               plp->palPalEntry[i].peFlags = 0 ;
          }
         HPALETTE hPalette = CreatePalette (plp) ;//创建逻辑调色盘

WM_PAINT 调用
SelectPalette (hdc, hPalette, FALSE) ;// 选入调色盘到设备环境
          RealizePalette (hdc) ;//逻辑调色盘颜色映射到系统调色盘


               // Draw the fountain of grays


          for (i = 0 ; i < 65 ; i++)
          {
               rect.left   = i * cxClient / 64 ;
               rect.top    = 0 ;
               rect.right  = (i + 1) * cxClient / 64 ;
               rect.bottom = cyClient ;


               hBrush = CreateSolidBrush (PALETTERGB (min (255, 4 * i), 
                                                      min (255, 4 * i), 
                                                      min (255, 4 * i))) ;
               FillRect (hdc, &rect, hBrush) ;
               DeleteObject (hBrush) ;
          }

如果程序在逻辑调色盘中指定一种颜色,该颜色又是20种保留颜色之一,那么Windows将把逻辑调色盘项目映像给该颜色。另外,如果两个或多个应用程序都在它们的逻辑调色盘中指定了同一种颜色,那么这些应用程序将共享系统调色盘项目。程序可以通过将PALETTEENTRY结构的peFlags字段指定为常数PC_NOCOLLAPSE来忽略该内定状态(其余两个可能的标记是PC_EXPLICIT(用于显示系统调色盘)和PC_RESERVED(用于调色盘动画),我将在本章的后面展示这两个标记)。

要帮助组织系统调色盘,Windows调色盘管理器含有两个发送给主窗口的消息。

第一个是QM_QUERYNEWPALETTE。当主窗口活动时,该消息发送给主窗口。如果程序在您的窗口上绘画时使用了调色盘管理器,则它必须处理该消息。GRAYS2展示具体的作法。程序获得设备内容句柄,并选进调色盘,呼叫RealizePalette,然后使窗口失效以产生WM_PAINT消息。如果显现了逻辑调色盘,则窗口消息处理程序从该消息传回TRUE,否则传回FALSE。

当系统调色盘改成与WM_QUERYNEWPALETTE消息的结果相同时,Windows将WM_PALETTECHANGED消息发送给由目前活动的窗口来启动并终止处理窗口链的所有主窗口。这允许前台窗口有优先权。传递给窗口消息处理程序的wParam值是活动窗口的句柄。只有当wParam不等于程序的窗口句柄时,使用调色盘管理器的程序才会处理该消息。

通常,在处理WM_PALETTECHANGED时,使用自订调色盘的任何程序都呼叫SelectPalette和RealizePalette。后续的窗口在消息处理期间呼叫RealizePalette时,Windows首先检查逻辑调色盘中的RGB颜色是否与已加载到系统调色盘中的RGB颜色相匹配。如果两个程序需要相同的颜色,那么这两个程序就共同使用一个系统调色盘项目。接下来,Windows检查未使用的系统调色盘项目。如果都已使用,则逻辑调色盘中的颜色从20种保留项目映像到最近的颜色。

如果不关心程序非活动时显示区域的外观,那么您不必处理WM_PALETTECHANGED消息。否则,您有两个选择。GRAYS2显示其中之一:在处理WM_QUERYNEWPALETTE消息时,它获得设备内容,选进调色盘,然后呼叫RealizePalette。这时就可以在处理WM_QUERYNEWPALETTE时呼叫InvalidateRect了。相反地,GRAYS2呼叫UpdateColors。这个函数通常比重新绘制窗口更有效,同时它改变窗口中图素的值来帮助保护以前的颜色。

使用调色盘管理器的许多程序都将让WM_QUERYNEWPALETTE和WM_PALETTECHANGED消息用GRAYS2所显示的方法来处理。



case WM_QUERYNEWPALETTE:
          if (!hPalette)
               return FALSE ;


          hdc = GetDC (hwnd) ;
          SelectPalette (hdc, hPalette, FALSE) ;
          RealizePalette (hdc) ;
          InvalidateRect (hwnd, NULL, TRUE) ;


          ReleaseDC (hwnd, hdc) ;
          return TRUE ;


     case WM_PALETTECHANGED:
          if (!hPalette || (HWND) wParam == hwnd)
               break ;


          hdc = GetDC (hwnd) ;
          SelectPalette (hdc, hPalette, FALSE) ;
          RealizePalette (hdc) ;
          UpdateColors (hdc) ;


          ReleaseDC (hwnd, hdc) ;
          break ;


「调色盘」索引的颜色不同于调色盘RGB颜色,其高字节是1,而低字节的值是目前在设备内容中选择的、逻辑调色盘中的索引。在GRAYS3中,逻辑调色盘有65个项目,用于这些项目的索引从0到64。值

PALETTEINDEX (0)
        

指黑色,

PALETTEINDEX (32)
        

指灰色,而

PALETTEINDEX (64)
        

指白色。

因为Windows不需要执行最近颜色的搜索,所以使用调色盘索引比使用RGB值更有效。



系统调色盘

我在前面提过,Windows系统调色盘直接与显示卡上的硬件调色盘查询表相符(然而,硬件调色盘查询表可能比系统调色盘的颜色分辨率低)。程序可以通过呼叫下面的函数来获得系统调色盘中的某些或全部的RGB项目:

GetSystemPaletteEntries (hdc, uStart, uNum, &pe) ;

你可能感兴趣的:(windows,动画)