⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 palette.cpp

📁 Windows 图形编程 书籍
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------------//
//              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 + -