📄 复件 (3) 新建 文本文档 (2).txt
字号:
{
static TCHAR szAppName[] = TEXT ("Grays3") ;
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 #3"),
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 HPALETTE hPalette ;
static int cxClient, cyClient ;
HBRUSH hBrush ;
HDC hdc ;
int i ;
LOGPALETTE * plp ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
// Set up a LOGPALETTE structure and create a palette
plp = malloc (sizeof (LOGPALETTE) + 64 * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
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 = CreatePalette (plp) ;
free (plp) ;
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
// Select and realize the palette in the device context
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 (PALETTEINDEX (i)) ;
FillRect (hdc, &rect, hBrush) ;
DeleteObject (hBrush) ;
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_QUERYNEWPALETTE:
if (!hPalette)
return FALSE ;
hdc = GetDC (hwnd) ;
SelectPalette (hdc, hPalette, FALSE) ;
RealizePalette (hdc) ;
InvalidateRect (hwnd, NULL, FALSE) ;
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 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
通常,使用调色盘管理器的第一步就是呼叫CreatePalette函数来建立逻辑调色盘。逻辑调色盘包含程序所需要的全部颜色-即236种颜色。GRAYS1程序在WM_CREATE消息处理期间处理此作业。它初始化LOGPALETTE(「logical palette:逻辑调色盘」)结构的字段,并将这个结构的指针传递给CreatePalette函数。CreatePalette传回逻辑调色盘的句柄,并将此句柄储存在静态变量hPalette中。
LOGPALETTE结构定义如下:
typedef struct
{
WORD palVersion ;
WORD palNumEntries ;
PALETTEENTRY palPalEntry[1] ;
}
LOGPALETTE, * PLOGPALETTE ;
第一个字段通常设为0x0300,表示兼容Windows 3.0。第二个字段设定为调色盘表中的项目数。LOGPALETTE结构中的第三个字段是一个PALETTEENTRY结构的数组,此结构也是一个调色盘项目。PALETTEENTRY结构定义如下:
typedef struct
{
BYTE peRed ;
BYTE peGreen ;
BYTE peBlue ;
BYTE peFlags ;
}
PALETTEENTRY, * PPALETTEENTRY ;
每个PALETTEENTRY结构都定义了一个我们要在调色盘中使用的RGB颜色值。
注意,LOGPALETTE中只能定义一个PALETTEENTRY结构的数组。您需要为LOGPALETTE结构和附加的PALETTEENTRY结构配置足够大的内存空间。GRAYS2需要65种灰阶,因此它为LOGPALETTE结构和64个附加的PALETTEENTRY结构配置了足够大的内存空间。GRAYS2将palNumEntries字段设定为65,然后从0到64循环,计算灰阶等级(一般是循环索引的4倍,但不超过255),将结构中的peRed、peGreen和peBlue字段设定为此灰阶等级。peFlags字段设为0。程序将指向这个内存块的指针传递给CreatePalette,在一个静态变量中储存该调色盘句柄,然后释放内存。
逻辑调色盘是GDI对象。程序应该删除它们建立的所有逻辑调色盘。WndProc透过在WM_DESTROY消息处理期间呼叫DeleteObject,仔细地删除了逻辑调色盘。
注意逻辑调色盘是独立的设备内容。在真正使用之前,必须确保将其选进设备内容。在WM_PAINT消息处理期间,SelectPalette将逻辑调色盘选进设备内容。除了含有第三个参数以外,此函数与SelectObject函数相似。通常,第三个参数设为FALSE。如果SelectPalette的第三个参数设为TRUE,那么调色盘将始终是「背景调色盘」,这意味着当其它所有程序都显现了各自的调色盘之后,该调色盘才可以获得仍位于系统调色盘中的一个未使用项目。
在任何时候都只有一个逻辑调色盘能选进设备内容。函数将传回前一个选进设备内容的逻辑调色盘句柄。如果您希望将此逻辑调色盘重新选进设备内容,则可以储存此句柄。
通过将颜色映像到系统调色盘,RealizePalette函数使Windows在设备内容中「显现」逻辑调色盘,而系统调色盘是与显示卡实际的实际调色盘相对应。实际工作在此函数呼叫期间进行。Windows必须决定呼叫函数的窗口是活动的还是非活动的,并尽可能将系统调色盘已改变通知给其它窗口(我们将简要说明一下通知的程序)。
回忆一下GRAYS1,它用RGB宏来指定纯色画刷的颜色。RGB宏建构一个32位长整数(记作COLORREF值),其中高字节是0,3个低字节是红、绿和蓝的亮度。
使用Windows调色盘管理器的程序可以继续使用RGB颜色值来指定颜色。不过,这些RGB颜色值将不能存取逻辑调色盘中的附加颜色。它们的作用与没有使用调色盘管理器相同。要在逻辑调色盘中使用附加的颜色,就要用到PALETTERGB宏。除了COLORREF值的高字节设为2而不是0以外,「调色盘RGB」颜色与RGB颜色很相似。
下面是重要的规则:
为了使用逻辑调色盘中的颜色,请用调色盘RGB值或调色盘索引来指定(我将简要讨论调色盘索引)。不要使用常规的RGB值。如果使用了常规的RGB值,您将得到一种标准颜色,而不是逻辑调色盘中的颜色。
没有将调色盘选进设备内容时,不要使用调色盘RGB值或调色盘索引。
尽管可以使用调色盘RGB值来指定逻辑调色盘中没有的颜色,但您还是要从逻辑调色盘获得颜色。
例如,在GRAYS2中处理WM_PAINT期间,当您选择并显现了逻辑调色盘之后,如果试图显示红色,则将显示灰阶。您必须用RGB颜色值来选择不在逻辑调色盘中的颜色。
注意,GRAYS2从不检查视讯显示驱动程序是否支持调色盘管理程序。在不支持调色盘管理程序的显示模式(即所有非256种颜色的显示模式)下执行GRAYS2时,GRAYS2的功能与GRASY1相同。
调色盘信息
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -