?? 16. 調色盤管理器.txt
字號:
調色盤管理器
智能中國——游戲組 整理編譯
--------------------------------------------------------------------------------
如果硬件允許,本章就沒有存在的必要。盡管許多現代的顯示卡提供24位顏色(也稱「true color」或「數百萬色」)或16位顏色(「增強色」或「數萬種顏色」),一些顯示卡-尤其是在便攜式計算機上或高分辨率模式中-每個圖素只允許8位。這意味著僅有256種顏色。
我們用256種顏色能做什么呢?很明顯,要顯示真實世界的圖像,僅16種顏色是不夠的,至少要使用數千或數百萬種顏色,256種顏色位于中間狀態。是的,用256種顏色來顯示真實世界的圖像足夠了,但需要根據特定的圖像來指定這些顏色。這意味著操作系統不能簡單地選擇「標準」系列的256種顏色,就希望它們對每個應用程序都是理想的顏色。
這就是Windows調色盤管理器所要涉及的全部內容。它用于指定程序在8位顯示模式下執行時所需要的顏色。如果知道程序肯定不會在8位顯示模式下執行,那么您也不需要使用調色盤管理器。不過,由于補充了位圖的一些細節,所以本章還是包含重要信息的。
使用調色盤
傳統上講,調色盤是畫家用來混合顏色的板子。這個詞也可以指畫家在繪畫過程中使用的所有顏色。在計算機圖形中,調色盤是在圖形輸出設備(例如視訊顯示器)上可用的顏色范圍。這個名詞也可以指支持256色模式的顯示卡上的對照表。
視頻硬件
顯示卡上的調色盤對照表運作過程如下圖所示:
在8位顯示模式中,每個圖素占8位。圖素值查詢包含256RGB值的對照表的地址。這些RGB值可以正好24位寬,或者小一點,通常是18位寬(即主要的紅、綠和藍各6位)。每種顏色的值都輸入到數字模擬轉換器,以得到發送給監視器的紅、綠和藍三個模擬信號。
通常,軟件可以用任意值來加載調色盤對照表,但這對設備無關的窗口接口,例如Microsoft Windows,會有一些干擾。首先,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
乳白色
在256種顏色顯示模式下執行時,由Windows維護系統調色盤,此調色盤與顯示卡上的硬件調色盤對照表相同。內定的系統調色盤如表16-1所示。應用程序可以通過指定「邏輯調色盤(logical palettes)」來修改其余236種顏色。如果有多個應用程序使用邏輯調色盤,那么Windows就給活動窗口最高優先權(我們知道,活動窗口有高亮顯示標題列,并且顯示在其它所有窗口的前面)。我們將用一些簡單的范例程序來檢查它是如何工作的。
要執行本章其它部分的程序,您可能需要將顯示卡切換成256色模式。在桌面上單擎鼠標右鍵,從菜單中選擇「屬性」,然后選擇「設定」頁面標簽。
顯示灰階
程序16-1所示的GRAYS1程序沒有使用Windows調色盤管理器,而嘗試用正常顯示的65級種階作為從黑到白的多種彩色的「來源」。
程序16-1 GRAYS1
GRAYS1.C
/*---------------------------------------------------------------------------
GRAYS1.C -- Gray Shades
(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Grays1") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Shades of Gray #1"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
static int cxClient, cyClient ;
HBRUSH hBrush ;
HDC hdc ;
int i ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
// Draw the fountain of grays
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) ;
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
在WM_PAINT消息處理期間,程序呼叫了65次FillRect函數,每次都使用不同灰階建立的畫刷。灰階值是RGB值(0,0,0)、(4,4,4)、(8,8,8)等等,直到最后一個值(255,255,255)。最后一個值來自CreateSolidBrush函數中的min宏。
如果在256色顯示模式下執行該程序,您將看到從黑到白的65種灰階,而且它們幾乎都用混色著色。純顏色只有黑色、暗灰色(128,128,128)、亮灰色(192,192,192)和白色。其它顏色是混合了這些純顏色的多位模式。如果我們在顯示行或文字,而不是用這65種灰階填充區域,Windows將不使用混色而只使用這四種純色。如果我們正在顯示位圖,則圖像將用20種標準Windows顏色近似。這時正如同您在執行最后一章中的程序的同時又加載了彩色或灰階DIB所見到的一樣。通常,Windows在位圖中不使用混色。
程序16-2所示的GRAYS2程序用較少的外部程序代碼驗證了調色盤管理器中最重要的函數和消息。
程序16-2 GRAYS2
GRAYS2.C
/*---------------------------------------------------------------------------
GRAYS2.C -- Gray Shades Using Palette Manager
(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Grays2") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (! RegisterClass (&wndclass))
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -