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

📄 dibsectionce.cpp

📁 迅宝MC3000的PDA程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:



BOOL CDIBSectionCE::Load(LPCTSTR lpszFileName)
{
	CFile file;
	if (!file.Open(lpszFileName, CFile::modeRead))
		return FALSE;

	// Get the current file position.  
	DWORD dwFileStart = (DWORD)file.GetPosition();

	// The first part of the file contains the file header.
	// This will tell us if it is a bitmap, how big the header is, and how big 
	// the file is. The header size in the file header includes the color table.
	BITMAPFILEHEADER BmpFileHdr;
	int nBytes;
	nBytes = file.Read(&BmpFileHdr, sizeof(BmpFileHdr));
	if (nBytes != sizeof(BmpFileHdr)) 
	{
		TRACE0("Failed to read file header\n");
		return FALSE;
	}

	// Check that we have the magic 'BM' at the start.
	if (BmpFileHdr.bfType != DS_BITMAP_FILEMARKER)
	{
		TRACE0("Not a bitmap file\n");
		return FALSE;
	}

	// Read the header (assuming it's a DIB). 
	DIBINFO	BmpInfo;
	nBytes = file.Read(&BmpInfo, sizeof(BITMAPINFOHEADER)); 
	if (nBytes != sizeof(BITMAPINFOHEADER)) 
	{
		TRACE0("Failed to read BITMAPINFOHEADER\n");
		return FALSE;
	}

	// Check that we have a real Windows DIB file.
	if (BmpInfo.bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
	{
		TRACE0(" File is not a Windows DIB\n");
		return FALSE;
	}

	// See how big the color table is in the file (if there is one).  
	int nColors = NumColorEntries(BmpInfo.bmiHeader.biBitCount);
	if (nColors > 0) 
	{
		// Read the color table from the file.
		int nColorTableSize = nColors * sizeof(RGBQUAD);
		nBytes = file.Read(BmpInfo.ColorTable(), nColorTableSize);
		if (nBytes != nColorTableSize) 
		{
			TRACE0("Failed to read color table\n");
			return FALSE;
		}
	}

	// So how big the bitmap surface is.
	int nBitsSize = BmpFileHdr.bfSize - BmpFileHdr.bfOffBits;

	// Allocate the memory for the bits and read the bits from the file.
	BYTE* pBits = (BYTE*) malloc(nBitsSize);
	if (!pBits) 
	{
		TRACE0("Out of memory for DIB bits\n");
		return FALSE;
	}

	// Seek to the bits in the file.
	file.Seek(dwFileStart + BmpFileHdr.bfOffBits, CFile::begin);

	// read the bits
	nBytes = file.Read(pBits, nBitsSize);
	if (nBytes != nBitsSize) 
	{
		TRACE0("Failed to read bits\n");
		free(pBits);
		return FALSE;
	}

	// Everything went OK.
	BmpInfo.bmiHeader.biSizeImage = nBitsSize;

	if (!SetBitmap((LPBITMAPINFO) BmpInfo, pBits))
	{
		TRACE0("Failed to set bitmap info\n");
		free(pBits);
		return FALSE;
	}


	TRY {
		free(pBits);
	}
	CATCH (CException, e)
	{
		TRACE0("wrong to free pBites\n"); 
	}
	END_CATCH


		return TRUE;
}

// --- In?: lpszFileName - image filename
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Saves the image to file.

#ifndef DIBSECTION_NO_PALETTE

// --- In?:
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Creates the palette from the DIBSection's color table. Assumes 
//              m_iColorTableSize has been set and the DIBsection m_hBitmap created
BOOL CDIBSectionCE::CreatePalette()
{
	m_Palette.DeleteObject();

	if (!m_hBitmap)
		return FALSE;

	// Create a 256 color halftone palette if there is no color table in the DIBSection
	if (m_iColorTableSize == 0)
		return CreateHalftonePalette(m_Palette, 256);

	// Get space for the colour entries
	RGBQUAD *pRGB = new RGBQUAD[m_iColorTableSize];
	if (!pRGB)
		return CreateHalftonePalette(m_Palette, m_iColorTableSize);

	HDC hDC = ::GetDC(NULL);
	if (!hDC)
	{
		delete [] pRGB;
		return FALSE;
	}

	// Create a memory DC compatible with the current DC
	CDC MemDC;
	MemDC.CreateCompatibleDC(CDC::FromHandle(hDC));
	if (!MemDC.GetSafeHdc())
	{
		delete [] pRGB;
		::ReleaseDC(NULL, hDC);
		return CreateHalftonePalette(m_Palette, m_iColorTableSize);
	}
	::ReleaseDC(NULL, hDC);

	HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(MemDC.GetSafeHdc(), m_hBitmap);
	if (!hOldBitmap)
	{
		delete [] pRGB;
		return CreateHalftonePalette(m_Palette, m_iColorTableSize);
	}

	// Get the colours used. WinCE does not support GetDIBColorTable so if you
	// are using this on a CE device with palettes, then you need to replace
	// the call with code that manually gets the color table from the m_DIBinfo structure.
#ifdef _WIN32_WCE
	int nColours = ::CEGetDIBColorTable(MemDC.GetSafeHdc(), 0, m_iColorTableSize, pRGB);
#else
	int nColours = ::GetDIBColorTable(MemDC.GetSafeHdc(), 0, m_iColorTableSize, pRGB);
#endif

	// Clean up
	::SelectObject(MemDC.GetSafeHdc(), hOldBitmap);

	if (!nColours)   // No colours retrieved => the bitmap in the DC is not a DIB section
	{
		delete [] pRGB;
		return CreateHalftonePalette(m_Palette, m_iColorTableSize);
	}   

	// Create and fill a LOGPALETTE structure with the colours used.
	PALETTEINFO PaletteInfo;
	PaletteInfo.palNumEntries = (WORD) m_iColorTableSize;

	for (int i = 0; i < nColours; i++)
	{
		PaletteInfo.palPalEntry[i].peRed   = pRGB[i].rgbRed;
		PaletteInfo.palPalEntry[i].peGreen = pRGB[i].rgbGreen;
		PaletteInfo.palPalEntry[i].peBlue  = pRGB[i].rgbBlue;
		PaletteInfo.palPalEntry[i].peFlags = 0;
	}
	for (int j = 0; j < (int) m_iColorTableSize; j++)
	{
		PaletteInfo.palPalEntry[j].peRed   = 0;
		PaletteInfo.palPalEntry[j].peGreen = 0;
		PaletteInfo.palPalEntry[j].peBlue  = 0;
		PaletteInfo.palPalEntry[j].peFlags = 0;
	}

	delete [] pRGB;

	// Create Palette!
	return m_Palette.CreatePalette(&PaletteInfo);
}

// --- In?: pPalette - new palette to use
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Sets the current palette used by the image from the supplied CPalette,
//              and sets the color table in the DIBSection
BOOL CDIBSectionCE::SetPalette(CPalette* pPalette)
{
	m_Palette.DeleteObject();

	if (!pPalette)
		return FALSE;

	UINT nColours = pPalette->GetEntryCount();
	if (nColours <= 0 || nColours > 256)
		return FALSE;

	// Get palette entries
	PALETTEINFO pi;
	pi.palNumEntries = (WORD) pPalette->GetPaletteEntries(0, nColours, (LPPALETTEENTRY) pi);

	// TODO: If pi.palNumEntries < m_iColorTableSize, then fill in blanks with 0's

	return SetLogPalette(&pi);
}

// --- In?: pLogPalette - new palette to use
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Sets the current palette used by the image from the supplied LOGPALETTE
BOOL CDIBSectionCE::SetLogPalette(LOGPALETTE* pLogPalette)
{
	ASSERT(pLogPalette->palVersion == (WORD) 0x300);
	UINT nColours = pLogPalette->palNumEntries;
	if (nColours <= 0 || nColours > 256)
	{
		CreatePalette();
		return FALSE;
	}

	// Create new palette
	m_Palette.DeleteObject();
	if (!m_Palette.CreatePalette(pLogPalette))
	{
		CreatePalette();
		return FALSE;
	}

	if (m_iColorTableSize == 0)
		return TRUE;

	// Set the DIB colours
	RGBQUAD RGBquads[256]; 
	for (UINT i = 0; i < nColours; i++)
	{
		RGBquads[i].rgbRed   = pLogPalette->palPalEntry[i].peRed;
		RGBquads[i].rgbGreen = pLogPalette->palPalEntry[i].peGreen;
		RGBquads[i].rgbBlue  = pLogPalette->palPalEntry[i].peBlue;
		RGBquads[i].rgbReserved = 0;
	}

	return FillDIBColorTable(nColours, RGBquads);
}

// --- In?: nNumColours - number of colours to set
//           pRGB - colours to fill
// --- Out :
// --- Returns : Returns TRUE on success
// --- Effect : Sets the colours used by the image. Only works if # colours <= 256
BOOL CDIBSectionCE::FillDIBColorTable(UINT nNumColours, RGBQUAD *pRGB)
{
	if (!pRGB || !nNumColours || !m_iColorTableSize || nNumColours > 256)
		return FALSE;

	// get the number of colors to return per BITMAPINFOHEADER docs
	UINT nColors;
	LPBITMAPINFOHEADER pBmih = GetBitmapInfoHeader();
	if (pBmih->biClrUsed)
		nColors = pBmih->biClrUsed;
	else
		nColors = 1 << (pBmih->biBitCount*pBmih->biPlanes);

	// Initialize the loop variables
	nColors = min(nNumColours, nColors);

	LPRGBQUAD pColorTable = GetColorTable();
	for (UINT iColor = 0; iColor < nColors; iColor++)
	{
		pColorTable[iColor].rgbReserved = 0;
		pColorTable[iColor].rgbBlue     = pRGB[iColor].rgbBlue;
		pColorTable[iColor].rgbRed      = pRGB[iColor].rgbRed;
		pColorTable[iColor].rgbGreen    = pRGB[iColor].rgbGreen;
	}

	return TRUE;
}

#endif // DIBSECTION_NO_PALETTE


// --- In?: hdc     - the Device Context in which the DIBSection is selected
//           hBitmap - the bitmap whose solor entries are to be queried
//           lpbi    - a pointer to a BITMAPINFO structure that will have it's
//                     color table filled.
// --- Out :
// --- Returns : the number of colors placed in the color table
// --- Effect : This function is a replacement for GetDIBits, in that it retrieves 
//              (or synthesizes) the color table from the given bitmap, and stores 
//              the values in the BITMAPINFO structure supplied.
UINT CDIBSectionCE::GetColorTableEntries(HDC hdc, HBITMAP hBitmap)
{
	UINT nColorTableSize = m_iColorTableSize;
	if (!nColorTableSize)
		return 0;

	// Fill the color table with the colours from the bitmap's color table
	LPRGBQUAD pColorTable = GetColorTable();

	// Get the color table from the HBITMAP and copy them over.
	UINT nCount;
	RGBQUAD* pRGB = new RGBQUAD[nColorTableSize];
	if (pRGB)
	{
		HBITMAP hOldBitmap = (HBITMAP) SelectObject(hdc, hBitmap);
		nCount = CEGetDIBColorTable(hdc, 0, nColorTableSize, pRGB);
		SelectObject(hdc, hOldBitmap);
		if (nCount)
		{
			nColorTableSize = nCount;
			memcpy(pColorTable, pRGB, nCount*sizeof(RGBQUAD));
		}
	}
	delete [] pRGB;

	// Didn't work - so synthesize one.
	if (!nCount)
	{       
		int nNumStandardColours = sizeof(ms_StdColours) / sizeof(ms_StdColours[0]);
		UINT nIndex = 0;

		// The standard colours (16)
		for (int i = 0; i < nNumStandardColours; i++)
		{
			if (nIndex >= nColorTableSize) 
				break;

			memcpy( &(pColorTable[i]), &(ms_StdColours[i]), sizeof(RGBQUAD) );         

			nIndex++;
		}

		// A colour cube (6 divisions = 216)
		int i = 0;
		for (int blue = 0; blue <= 5; blue++)
			for (int green = 0; green <= 5; green++)
				for (int red = 0; red <= 5; red++)
				{
					if (nIndex >= nColorTableSize)
						break;

					pColorTable[i].rgbRed   = (BYTE) ((red*255)/5);
					pColorTable[i].rgbGreen = (BYTE) ((green*255)/5);
					pColorTable[i].rgbBlue  = (BYTE) ((blue*255)/5);
					pColorTable[i].rgbReserved = 0;
					nIndex++;
				}

				// A grey scale (24 divisions)
				for (int grey = 0; grey <= 23; grey++)
				{
					if (nIndex >= nColorTableSize) 
						break;

					pColorTable[i].rgbRed   = (BYTE) (grey*255/23);
					pColorTable[i].rgbGreen = (BYTE) (grey*255/23);
					pColorTable[i].rgbBlue  = (BYTE) (grey*255/23);
					pColorTable[i].rgbReserved = 0;
					nIndex++;
				}
	}

	return nColorTableSize;
}

/**********************************************************************
This function is from the MS KB article "HOWTO: Get the Color Table of 
a DIBSection in Windows CE".

PARAMETERS:
HDC - the Device Context in which the DIBSection is selected
UINT - the index of the first color table entry to retrieve
UINT - the number of color table entries to retrieve
RGBQUAD - a buffer large enough to hold the number of RGBQUAD
entries requested

RETURNS:
UINT - the number of colors placed in the buffer

***********************************************************************/
UINT CEGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries,
						RGBQUAD *pColors)
{   
	if (pColors == NULL)
		return 0;                       // No place to put them, fail

	// Get a description of the DIB Section
	HBITMAP hDIBSection = (HBITMAP) GetCurrentObject( hdc, OBJ_BITMAP );

	DIBSECTION ds;
	DWORD dwSize = GetObject( hDIBSection, sizeof(DIBSECTION), &ds );

	if (dwSize != sizeof(DIBSECTION))
		return 0;                      // Must not be a DIBSection, fail

	if (ds.dsBmih.biBitCount > 8)
		return 0;                      // Not Palettized, fail

	// get the number of colors to return per BITMAPINFOHEADER docs
	UINT cColors;
	if (ds.dsBmih.biClrUsed)
		cColors = ds.dsBmih.biClrUsed;
	else
		cColors = 1 << (ds.dsBmih.biBitCount*ds.dsBmih.biPlanes);

	// Create a mask for the palette index bits for 1, 2, 4, and 8 bpp
	WORD wIndexMask = (0xFF << (8 - ds.dsBmih.biBitCount)) & 0x00FF;

⌨️ 快捷键说明

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