📄 palette.cpp
字号:
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : palette.cpp //
// Description: Palette demo program, Chapter 13 //
// Version : 1.00.000, May 31, 2000 //
//-----------------------------------------------------------------------------------//
#define STRICT
#define _WIN32_WINNT 0x0500
#define WINVER 0x0500
#define NOCRYPT
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <math.h>
// #define SWITCH_BITMAP defined in preprocessor MACRO for toolbar
#include "..\..\include\wingraph.h"
#include "..\..\include\PalLoadBitmap.h"
#include "..\..\include\Octree.h"
#include "..\..\include\toolbarb.h"
#include "Resource.h"
#include "DIBWindow.h"
#include "PalWindow.h"
class KDIBView : public KScrollCanvas
{
typedef enum { GAP = 16 };
virtual void OnDraw(HDC hDC, const RECT * rcPaint);
virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void GetWndClassEx(WNDCLASSEX & wc);
HMENU m_hViewMenu;
int m_nViewOpt;
HWND m_hFrame;
int m_nUpdateCount;
BITMAPINFO * m_pNewBMI;
public:
HINSTANCE m_hInstance;
KImage m_DIB;
KDIBView(void)
{
m_hViewMenu = NULL;
m_nViewOpt = IDM_VIEW_STRETCHDIBITS;
m_nUpdateCount = 0;
m_pNewBMI = NULL;
}
~KDIBView(void)
{
if ( m_pNewBMI && ( m_pNewBMI!= m_DIB.GetBMI() ) )
delete [] (BYTE *) m_pNewBMI;
}
bool Initialize(const TCHAR * pFileName, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
{
m_hFrame = hFrame;
if ( m_DIB.LoadFile(pFileName) )
{
SetSize(m_DIB.GetWidth() + GAP*2,
m_DIB.GetHeight() + GAP*2, 5, 5);
m_hInstance = hInstance;
m_pStatus = pStatus;
RegisterClass(_T("DIBView"), hInstance);
return true;
}
else
return false;
}
bool Initialize(BITMAPINFO * pDIB, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
{
m_hFrame = hFrame;
if ( m_DIB.AttachDIB(pDIB, NULL, DIB_BMI_NEEDFREE) )
{
SetSize(m_DIB.GetWidth() + GAP*2,
m_DIB.GetHeight() + GAP*2, 5, 5);
m_hInstance = hInstance;
m_pStatus = pStatus;
RegisterClass(_T("DIBView"), hInstance);
return true;
}
else
return false;
}
bool GetTitle(const TCHAR * pFileName, TCHAR * pTitle)
{
if ( pFileName )
{
wsprintf(pTitle, "%s, %d x %d pixel, %d bits", pFileName,
m_DIB.GetWidth(), m_DIB.GetHeight(), m_DIB.GetDepth());
return true;
}
else
return false;
}
void CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle);
};
void KDIBView::GetWndClassEx(WNDCLASSEX & wc)
{
memset(& wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_PALETTE));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_GRAYTEXT + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = NULL;
wc.hIconSm = NULL;
}
// Let the main frame window handle it
void KDIBView::CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle)
{
if ( pDIB )
SendMessage(m_hFrame, WM_USER, (WPARAM) pDIB, (LPARAM) pTitle);
}
LRESULT KDIBView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
case WM_CREATE:
m_hWnd = hWnd;
m_hViewMenu = LoadMenu(m_hInstance, MAKEINTRESOURCE(IDR_DIBVIEW));
{
HDC hDC = GetDC(hWnd);
m_hPalette = CreateDIBPalette(m_DIB.GetBMI());
if ( m_hPalette==NULL )
{
m_hPalette = CreateHalftonePalette(hDC);
m_pNewBMI = IndexColorTable(m_DIB.GetBMI(), m_hPalette);
}
else
m_pNewBMI = IndexColorTable(m_DIB.GetBMI(), NULL);
ReleaseDC(hWnd, hDC);
}
return 0;
case WM_PAINT:
m_nUpdateCount = 0;
return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
case WM_SIZE:
case WM_HSCROLL:
case WM_VSCROLL:
{
LRESULT lr = KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
int nMin, nMax, nPos;
GetScrollRange(m_hWnd, SB_VERT, &nMin, &nMax);
nPos = GetScrollPos(m_hWnd, SB_VERT);
TCHAR mess[32];
wsprintf(mess, "%d %d %d", nMin, nPos, nMax);
m_pStatus->SetText(0, mess);
return lr;
}
case WM_PALETTEISCHANGING:
MessageBox(NULL, "Hello", "Hi", MB_OK);
return 0;
case WM_QUERYNEWPALETTE:
return OnQueryNewPalette();
case WM_PALETTECHANGED:
return OnPaletteChanged(hWnd, wParam);
case WM_COMMAND:
switch ( LOWORD(wParam) )
{
case IDM_VIEW_STRETCHDIBITS:
case IDM_VIEW_STRETCHHALFTONE:
case IDM_VIEW_STRETCHPALCOLORS:
case IDM_VIEW_SETDIBITSTODEVICE:
case IDM_VIEW_FITWINDOW:
case IDM_VIEW_MASKGREEN:
case IDM_VIEW_MASKBLUE:
if ( LOWORD(wParam)!= m_nViewOpt )
{
m_nViewOpt = LOWORD(wParam);
switch ( LOWORD(wParam) )
{
case IDM_VIEW_STRETCHDIBITS:
case IDM_VIEW_STRETCHHALFTONE:
case IDM_VIEW_STRETCHPALCOLORS:
case IDM_VIEW_SETDIBITSTODEVICE:
case IDM_VIEW_FITWINDOW:
case IDM_VIEW_MASKGREEN:
case IDM_VIEW_MASKBLUE:
SetSize(m_DIB.GetWidth() + GAP*2, m_DIB.GetHeight() + GAP*2, 5, 5, true);
break;
}
InvalidateRect(hWnd, NULL, TRUE);
}
return 0;
case IDM_COLORS_CDR_CLOSEST:
CreateNewView(Convert8bpp(m_DIB.GetBMI()), "Color Depth Reduction: Closest Match");
return 0;
case IDM_COLORS_CDR_ERRORDIFFUSION:
CreateNewView(Convert8bpp_ErrorDiffusion(m_DIB.GetBMI()), "Color Depth Reduction: Error Diffusuin");
return 0;
}
return 0;
default:
return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
}
}
extern DWORD dibtick;
void KDIBView::OnDraw(HDC hDC, const RECT * rcPaint)
{
DWORD tm = GetTickCount();
dibtick = 0;
int w = m_DIB.GetWidth();
int h = m_DIB.GetHeight();
if ( m_hPalette )
{
SelectPalette(hDC, m_hPalette, FALSE);
RealizePalette(hDC);
}
switch ( m_nViewOpt )
{
case IDM_VIEW_FITWINDOW:
{
RECT rect;
SetStretchBltMode(hDC, HALFTONE);
GetClientRect(m_hWnd, & rect);
m_DIB.DrawDIB(hDC, 0, 0, rect.right, rect.bottom, 0, 0, w, h, SRCCOPY);
}
break;
case IDM_VIEW_MASKGREEN:
{
KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0xFF, 0)));
m_DIB.DrawDIB(hDC, GAP, GAP, w, h, 0, 0, w, h, MERGECOPY);
}
break;
case IDM_VIEW_MASKBLUE:
{
KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0, 0xFF )));
m_DIB.DrawDIB(hDC, GAP, GAP, w, h, 0, 0, w, h, MERGECOPY);
}
break;
case IDM_VIEW_STRETCHDIBITS:
m_DIB.DrawDIB(hDC, GAP, GAP, w, h, 0, 0, w, h, SRCCOPY);
break;
case IDM_VIEW_STRETCHHALFTONE:
SetStretchBltMode(hDC, HALFTONE);
m_DIB.DrawDIB(hDC, GAP, GAP, w, h, 0, 0, w, h, SRCCOPY);
break;
case IDM_VIEW_STRETCHPALCOLORS:
StretchDIBits(hDC, GAP, GAP, w, h, 0, 0, w, h, m_DIB.GetBits(), m_pNewBMI, DIB_PAL_COLORS, SRCCOPY);
break;
case IDM_VIEW_SETDIBITSTODEVICE:
if ( ! m_DIB.IsCompressed() )
{
int bps = m_DIB.GetBPS();
BYTE * buffer = new BYTE[bps];
for (int i=0; i<m_DIB.GetHeight(); i++)
{
memcpy(buffer, m_DIB.GetBits() + bps*i, bps);
for (int j=0; j<bps; j++)
buffer[j] = ~ buffer[j];
m_DIB.SetDIB(hDC, GAP, GAP, i, 1, buffer);
}
delete [] buffer;
}
break;
}
RestoreDC(hDC, -1);
tm = GetTickCount() - tm;
if ( dibtick )
tm = dibtick;
TCHAR mess[32];
wsprintf(mess, "Time %d ms", tm);
m_pStatus->SetText(1, mess);
}
void Label(HDC hDC, int x, int y, const TCHAR * mess)
{
TextOut(hDC, x, y, mess, _tcslen(mess));
}
void WebColors(HDC hDC, int x, int y, int crtyp)
{
for (int r=0; r<6; r++)
for (int g=0; g<6; g++)
for (int b=0; b<6; b++)
{
COLORREF cr;
switch ( crtyp )
{
case 0: cr = RGB(r*51, g*51, b*51); break;
case 1: cr = PALETTERGB(r*51, g*51, b*51); break;
case 2: cr = PALETTEINDEX(r*36+g*6+b); break;
}
HBRUSH hBrush = CreateSolidBrush(cr);
RECT rect = { r * 110 + g*16+ x, b*16+ y,
r * 110 + g*16+15+x, b*16+15+y};
FillRect(hDC, & rect, hBrush);
DeleteObject(hBrush);
}
}
void AnalyzePalette(PALETTEENTRY entry[], int no, TCHAR mess[])
{
int web = 0;
int gray = 0;
for (int i=0; i<no; i++)
{
if ( ( (entry[i].peBlue % 0x33) + (entry[i].peGreen % 0x33) + (entry[i].peRed % 0x33) )==0 )
web ++;
else if ( ( entry[i].peBlue==entry[i].peGreen) && ( entry[i].peGreen==entry[i].peBlue) )
gray ++;
}
wsprintf(mess, "%d web colors, %d grayscale colors", web, gray);
}
void ShowPalette(HDC hDC, int x0, int y0, HPALETTE hPal)
{
PALETTEENTRY entries[256];
int no;
if ( hPal )
no = GetPaletteEntries(hPal, 0, 256, entries);
else
no = GetSystemPaletteEntries(hDC, 0, 256, entries);
SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
TCHAR temp[64];
for (int i=0; i<no; i++)
{
int x = x0 + ( i % 8) * 100;
int y = y0 + 20 + (i/8) * 18;
wsprintf(temp, "%02X%02X%02X %d", entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags);
Label(hDC, x, y, temp);
HBRUSH hBrush = CreateSolidBrush(PALETTERGB(entries[i].peRed, entries[i].peGreen, entries[i].peBlue));
RECT rect = { x + 70, y, x + 96, y+16 };
FillRect(hDC, & rect, hBrush);
DeleteObject(hBrush);
}
AnalyzePalette(entries, no, temp);
TextOut(hDC, x0, y0, temp, _tcslen(temp));
}
HPALETTE CreateGrayscalePalette(void)
{
LOGPALETTE * pLogPal = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x0300;
pLogPal->palNumEntries = 256;
for (int i=0; i<256; i++)
{
PALETTEENTRY entry = { i, i, i, 0 };
pLogPal->palPalEntry[i] = entry;
}
HPALETTE hPal = CreatePalette(pLogPal);
delete [] (BYTE *) pLogPal;
return hPal;
}
HPALETTE CreateExplicitPalette(void)
{
LOGPALETTE * pLogPal = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x0300;
pLogPal->palNumEntries = 256;
for (int i=0; i<256; i++)
{
PALETTEENTRY entry = { i, 0, 0, PC_EXPLICIT };
pLogPal->palPalEntry[i] = entry;
}
HPALETTE hPal = CreatePalette(pLogPal);
delete [] (BYTE *) pLogPal;
return hPal;
}
void TestPalette(HDC hDC, HINSTANCE hInstance, int type)
{
HPALETTE hPal;
switch ( type )
{
case 0: hPal = CreateHalftonePalette(hDC); break;
case 2: SetSystemPaletteUse(hDC, SYSPAL_NOSTATIC);
case 1: hPal = CreateGrayscalePalette(); break;
case 3: hPal = CreateExplicitPalette();
}
HPALETTE hOld = SelectPalette(hDC, hPal, FALSE);
int n = RealizePalette(hDC);
WebColors(hDC, 10, 10, 0);
WebColors(hDC, 10, 130, 1);
// WebColors(hDC, 10, 250, 2);
TCHAR temp[64];
wsprintf(temp, "%d colors realized", n);
TextOut(hDC, 10, 250, temp, _tcslen(temp));
ShowPalette(hDC, 10, 280, hPal);
SelectPalette(hDC, hOld, TRUE);
DeleteObject(hPal);
}
void TestPalette(HDC hDC, HINSTANCE hInstance)
{
TCHAR temp[64];
// palette support information
if ( GetDeviceCaps(hDC, RASTERCAPS ) && RC_PALETTE )
Label(hDC, 10, 10, "Palette Supported");
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -