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

📄 bitmapbox.cpp

📁 c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++6.0
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
//       http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Resource.h"
#include "BitmapBox.h"

CBitmapBox::CBitmapBox()
{
	InitBackDC = false;
	Tiling = false;
}

CBitmapBox::~CBitmapBox()
{
}

BEGIN_MESSAGE_MAP(CBitmapBox, CWnd)
	ON_WM_DRAWITEM()
END_MESSAGE_MAP()

BOOL CBitmapBox::Create(DWORD dwStyle, const RECT& rect, 
					   CWnd* pParentWnd, UINT nID, 
					   UINT BitmapID, CSize bmpSize)
{
	BitmapSize = bmpSize;
	BOOL Result;

	Result = CWnd::CreateEx(WS_EX_LEFT, 
		_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);

	SetBitmap(BitmapID);
	return Result;
}

static CSize GetBitmapSize(CBitmap *Bmp)
{
	BITMAP bm;
	CSize size;

	Bmp->GetBitmap(&bm);

	size.cx = bm.bmWidth;
	size.cy = bm.bmHeight;

	return size;
}

void CBitmapBox::SetBitmap(UINT BitmapID)
{
//	if(BackBitmap)
//	{
//		delete BackBitmap;
//		BackBitmap = NULL;
//	}

	if(!InitBackDC)
	{
		InitBackDC = true;

		CClientDC ClientDC(this);

		BackDC.CreateCompatibleDC(&ClientDC);

		BackColor = RGB(191, 191, 191);
	}

	if(BitmapID > 0)
	{
		BackBitmap = new CBitmap;
		BackBitmap->LoadBitmap(BitmapID);
		BackDC.SelectObject(BackBitmap);

		BitmapSize = GetBitmapSize(BackBitmap);
	}
	else
	{
		CRect ClientRect;
		CBrush BackBrush(RGB(191, 191, 191));

		GetClientRect(&ClientRect);

		BackBitmap = new CBitmap;
		BackBitmap->CreateCompatibleBitmap(&BackDC, 
			ClientRect.Width(), ClientRect.Height());

		BackDC.SelectObject(BackBitmap);
		BackDC.FillRect(ClientRect, &BackBrush);
	}

	InvalidateRect(NULL, FALSE);
}

BOOL CBitmapBox::LoadBMPImage(LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal, 
							  CSize *BmpSize)
{
	CFile file;
	
	if(!file.Open( sBMPFile, CFile::modeRead))
		return FALSE;

	BITMAPFILEHEADER bmfHeader;	// Read file header
	if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
		return FALSE;	// File type should be 'BM'

	if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
		return FALSE;
	// Get length of the remainder of the file and allocate memory
	DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
	HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
	
	if (hDIB == 0)
		return FALSE;	// Read the remainder of the bitmap file.
	if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
	{
		::GlobalFree(hDIB);
		return FALSE;
	}

	BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
	// If bmiHeader.biClrUsed is zero we have to infer the number
	// of colors from the number of bits used to specify it.

	if(BmpSize)
	{
		BmpSize->cx = (int)bmiHeader.biWidth;
		BmpSize->cy = (int)bmiHeader.biHeight;
	}
	
	int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 
						1 << bmiHeader.biBitCount;	LPVOID lpDIBBits;
	if( bmInfo.bmiHeader.biBitCount > 8 )
		lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + 
			((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
	else
		lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
	
	// Create the logical palette
	if( pPal != NULL )
	{		// Create the palette
		if( nColors <= 256 )
		{
			UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
			LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
			pLP->palVersion = 0x300;
			pLP->palNumEntries = nColors;
			for( int i=0; i < nColors; i++)
			{
				pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
				pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
				pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
				pLP->palPalEntry[i].peFlags = 0;
			}
			
			pPal->CreatePalette( pLP );
			delete[] pLP;
		}
	}
	
	CClientDC dc(NULL);
	CPalette* pOldPalette = NULL;

	if( pPal )
	{
		pOldPalette = dc.SelectPalette( pPal, FALSE );
		dc.RealizePalette();
	}
	
	HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
				&bmiHeader,	// pointer to bitmap size and format data 
				CBM_INIT,	// initialization flag 
				lpDIBBits,	// pointer to initialization data 
				&bmInfo,	// pointer to bitmap color-format data 
				DIB_RGB_COLORS);		// color-data usage
	bitmap.Attach( hBmp );
	if( pOldPalette )
		dc.SelectPalette( pOldPalette, FALSE );
	
	::GlobalFree(hDIB);
	return TRUE;
}

void CBitmapBox::SetBitmap(char *BitmapName, bool IsResource, bool Tile)
{
	bool Clear = false;
	CBitmap *OldBitmap = BackBitmap;
	CClientDC ClientDC(this);
	CRect ClientRect;
	
	GetClientRect(&ClientRect);

	if(!InitBackDC)
	{
		InitBackDC = true;

		BackDC.CreateCompatibleDC(&ClientDC);

		BackColor = RGB(0, 191, 0);
	}

	if(BitmapName && strlen(BitmapName) > 0)
	{
		BackBitmap = new CBitmap;

		if(IsResource)
			BackBitmap->LoadBitmap(BitmapName);
		else
		{
			CPalette Palette;
			CSize NewBitmapSize;

			if(!LoadBMPImage(BitmapName, *BackBitmap, &Palette, &NewBitmapSize))
			{
				BitmapSize.cx = ClientRect.Width();
				BitmapSize.cy = ClientRect.Height();
				BackBitmap->CreateCompatibleBitmap(&BackDC, 
					BitmapSize.cx, BitmapSize.cy);
				Clear = true;
			}
			else
				BitmapSize = NewBitmapSize;
		}

		BackDC.SelectObject(BackBitmap);
	}
	else
	{
		BitmapSize.cx = ClientRect.Width();
		BitmapSize.cy = ClientRect.Height();
		BackBitmap->CreateCompatibleBitmap(&BackDC, 
			BitmapSize.cx, BitmapSize.cy);
		Clear = true;
	}

	if(Clear)
	{
		CRect ClipRect;
		CBrush WhiteBrush(RGB(255, 255, 255));

		ClipRect.top = 0;
		ClipRect.left = 0;
		ClipRect.right = BitmapSize.cx;
		ClipRect.bottom = BitmapSize.cy;

		BackDC.FillRect(ClipRect, &WhiteBrush);
	}
	else
	{
//		if(OldBitmap)
//			delete OldBitmap;
	}

	Tiling = Tile;

	InvalidateRect(NULL, FALSE);
}

void CBitmapBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
	CRect ClientRect;
	CClientDC DrawDC(this);

	GetClientRect(&ClientRect);

	CPoint StartPoint;
	CDC MemDC;
	CBitmap MemBmp, *OldBmp;

	if(!InitBackDC)
	{
		InitBackDC = true;

		BackDC.CreateCompatibleDC(&DrawDC);

		if(BackBitmap)
		{
			BackDC.SelectObject(BackBitmap);
			BackColor = BackDC.GetPixel(0, 0);
		}
		else
			BackColor = RGB(0, 191, 0);
	}

	CBrush BackBrush(BackColor);

	MemDC.CreateCompatibleDC(&DrawDC);
	MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
	OldBmp = MemDC.SelectObject(&MemBmp);

	CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
	MemDC.FillRect(&ZeroClient,	&BackBrush);

	StartPoint.x = (int)((ClientRect.Width() - BitmapSize.cx) / 2);
	StartPoint.y = (int)((ClientRect.Height() - BitmapSize.cy) / 2);
	
	if(BackBitmap)
	{
		if(!Tiling || (StartPoint.x <= 0 && StartPoint.y <= 0))
			MemDC.BitBlt(StartPoint.x, StartPoint.y, BitmapSize.cx, BitmapSize.cy,
				&BackDC, 0, 0, SRCCOPY);
		else
		{
			for(StartPoint.x = 0; StartPoint.x < ClientRect.Width();
				StartPoint.x += BitmapSize.cx)
			{
				for(StartPoint.y = 0; StartPoint.y < ClientRect.Height();
					StartPoint.y += BitmapSize.cy)
				{
					MemDC.BitBlt(StartPoint.x, StartPoint.y, 
						BitmapSize.cx, BitmapSize.cy,
						&BackDC, 0, 0, SRCCOPY);
				}
			}
		}
	}

	DrawDC.BitBlt(ClientRect.left, ClientRect.top, 
		ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);
	
	MemDC.SelectObject(OldBmp);

	return;
}

CBackBitmapBox::CBackBitmapBox()
{
	InitBackDC = false;
}

CBackBitmapBox::~CBackBitmapBox()
{
}

BEGIN_MESSAGE_MAP(CBackBitmapBox, CWnd)
	ON_WM_DRAWITEM()
END_MESSAGE_MAP()

BOOL CBackBitmapBox::Create(DWORD dwStyle, const RECT& rect, 
					   CWnd* pParentWnd, UINT nID, 
					   LPCTSTR BmpID, CSize bmpSize, COLORREF BackgroundColor)
{
	BitmapSize = bmpSize;
	VERIFY(BackBitmap.LoadBitmap(BmpID));
	OriginalImageBackground = BackgroundColor;

	return CWnd::CreateEx(WS_EX_LEFT, 
		_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}

BOOL CBackBitmapBox::Create(DWORD dwStyle, const RECT& rect, 
					   CWnd* pParentWnd, UINT nID, 
					   UINT BmpID, CSize bmpSize, COLORREF BackgroundColor)
{
	BitmapSize = bmpSize;
	VERIFY(BackBitmap.LoadBitmap(BmpID));

	OriginalImageBackground = BackgroundColor;

	return CWnd::CreateEx(WS_EX_LEFT, 
		_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}

BOOL CBackBitmapBox::LoadBMPImage(LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal, 
								  CSize *BmpSize)
{
	CFile file;
	
	if(!file.Open( sBMPFile, CFile::modeRead))
		return FALSE;

	BITMAPFILEHEADER bmfHeader;	// Read file header
	if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
		return FALSE;	// File type should be 'BM'

	if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
		return FALSE;
	// Get length of the remainder of the file and allocate memory
	DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
	HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
	
	if (hDIB == 0)
		return FALSE;	// Read the remainder of the bitmap file.
	if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
	{
		::GlobalFree(hDIB);
		return FALSE;
	}

	BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
	// If bmiHeader.biClrUsed is zero we have to infer the number
	// of colors from the number of bits used to specify it.

	if(BmpSize)
	{
		BmpSize->cx = (int)bmiHeader.biWidth;
		BmpSize->cy = (int)bmiHeader.biHeight;
	}
	
	int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 
						1 << bmiHeader.biBitCount;	LPVOID lpDIBBits;
	if( bmInfo.bmiHeader.biBitCount > 8 )
		lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + 
			((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
	else
		lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
	
	// Create the logical palette
	if( pPal != NULL )
	{		// Create the palette
		if( nColors <= 256 )
		{
			UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
			LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
			pLP->palVersion = 0x300;
			pLP->palNumEntries = nColors;
			for( int i=0; i < nColors; i++)
			{
				pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
				pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
				pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
				pLP->palPalEntry[i].peFlags = 0;
			}
			
			pPal->CreatePalette( pLP );
			delete[] pLP;
		}
	}
	
	CClientDC dc(NULL);
	CPalette* pOldPalette = NULL;

	if( pPal )
	{
		pOldPalette = dc.SelectPalette( pPal, FALSE );
		dc.RealizePalette();
	}
	
	HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
				&bmiHeader,	// pointer to bitmap size and format data 
				CBM_INIT,	// initialization flag 
				lpDIBBits,	// pointer to initialization data 
				&bmInfo,	// pointer to bitmap color-format data 
				DIB_RGB_COLORS);		// color-data usage
	bitmap.Attach( hBmp );
	if( pOldPalette )
		dc.SelectPalette( pOldPalette, FALSE );
	
	::GlobalFree(hDIB);
	return TRUE;
}

void CBackBitmapBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
	CRect ClientRect;
	CClientDC DrawDC(this);

	GetClientRect(&ClientRect);

	CPoint StartPoint;
	CDC MemDC;
	CBitmap MemBmp, *OldBmp;

	if(!InitBackDC)
	{
		InitBackDC = true;

		BackDC.CreateCompatibleDC(&DrawDC);
		BackDC.SelectObject(&BackBitmap);

		BackColor = BackDC.GetPixel(0, 0);
	}

	CBrush BackBrush(BackColor);

	MemDC.CreateCompatibleDC(&DrawDC);
	MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
	OldBmp = MemDC.SelectObject(&MemBmp);

	CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
	MemDC.FillRect(&ZeroClient,	&BackBrush);

	StartPoint.x = (int)((ClientRect.Width() - BitmapSize.cx) / 2);
	StartPoint.y = (int)((ClientRect.Height() - BitmapSize.cy) / 2);
	
	MemDC.BitBlt(StartPoint.x, StartPoint.y, BitmapSize.cx, BitmapSize.cy,
		&BackDC, 0, 0, SRCCOPY);

	/* Combine the image (MemDC) with the background (DrawDC) */
	CBitmap MaskBmp, *OldMaskBmp;
	CDC MaskDC;
	MaskDC.CreateCompatibleDC(&DrawDC);

	/* Create monochrome bitmap for the mask */
	MaskBmp.CreateBitmap(ClientRect.Width(), ClientRect.Height(), 1, 1, NULL);
	OldMaskBmp = MaskDC.SelectObject(&MaskBmp);

	/* Set image background color */
	MemDC.SetBkColor(OriginalImageBackground);

	/* Mask is white wherever the icon is colored */
	MaskDC.BitBlt(0, 0, ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);

	/* Make the background black wherever the icon is colored */
	DrawDC.SetBkColor(RGB(255,255,255));
	DrawDC.SetTextColor(RGB(0,0,0));
	DrawDC.BitBlt(ClientRect.left, ClientRect.top, 
		ClientRect.Width(), ClientRect.Height(),
		&MaskDC, 0, 0, SRCAND);

	MemDC.SetBkColor(RGB(0,0,0));
	MemDC.SetTextColor(RGB(255,255,255));
	MemDC.BitBlt(0, 0, ClientRect.Width(), ClientRect.Height(), 
		&MaskDC, 0, 0, SRCAND);

	/* OR the bitmaps together */
	DrawDC.BitBlt(ClientRect.left, ClientRect.top, 
		ClientRect.Width(), ClientRect.Height(),
		&MemDC, 0, 0, SRCPAINT);

	MaskDC.SelectObject(OldMaskBmp);
	MemDC.SelectObject(OldBmp);

	return;
}

CFontPreviewBox::CFontPreviewBox()
{
}

CFontPreviewBox::~CFontPreviewBox()
{
}

BEGIN_MESSAGE_MAP(CFontPreviewBox, CWnd)
	ON_WM_DRAWITEM()
END_MESSAGE_MAP()

BOOL CFontPreviewBox::Create(DWORD dwStyle, const RECT& rect, 
					   CWnd* pParentWnd, UINT nID)
{
	return CWnd::CreateEx(WS_EX_LEFT, 
		_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}

void CFontPreviewBox::SetFont(LOGFONT font)
{
	LogFont = font;
	InvalidateRect(NULL, FALSE);
}

void CFontPreviewBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
	CRect ClientRect;
	CClientDC DrawDC(this);
	COLORREF BackColor = RGB(255, 255, 255);
	CFont ViewFont, *OldFont;

	GetClientRect(&ClientRect);

	CDC MemDC;
	CBitmap MemBmp, *OldBmp;

	CBrush BackBrush(BackColor);

	MemDC.CreateCompatibleDC(&DrawDC);
	MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
	OldBmp = MemDC.SelectObject(&MemBmp);

	CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
	MemDC.FillRect(&ZeroClient,	&BackBrush);

	ViewFont.CreateFontIndirect(&LogFont);

	OldFont = MemDC.SelectObject(&ViewFont);
	MemDC.DrawText("ABCXYZ\nabcxyz", -1, ZeroClient, DT_NOCLIP);

	DrawDC.BitBlt(ClientRect.left, ClientRect.top, 
		ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);
	
	MemDC.SelectObject(OldBmp);
	MemDC.SelectObject(OldFont);

	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -