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

📄 dibsectionce.cpp

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

#include "stdafx.h"
#include "DIBSectionCE.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifndef _WIN32_WCE  
#undef TRY
#undef CATCH
#undef END_CATCH
#define TRY try
#define CATCH(ex_class, ex_object) catch(ex_class* ex_object)
#define END_CATCH
#endif  // _WIN32_WCE

// Standard colours
RGBQUAD CDIBSectionCE::ms_StdColours[] = {
	{ 0x00, 0x00, 0x00, 0 },    // First 2 will be palette for monochrome bitmaps
	{ 0xFF, 0xFF, 0xFF, 0 },

	{ 0x00, 0x00, 0xFF, 0 },    // First 16 will be palette for 16 colour bitmaps
	{ 0x00, 0xFF, 0x00, 0 },
	{ 0x00, 0xFF, 0xFF, 0 },
	{ 0xFF, 0x00, 0x00, 0 },
	{ 0xFF, 0x00, 0xFF, 0 },
	{ 0xFF, 0xFF, 0x00, 0 },

	{ 0x00, 0x00, 0x80, 0 },
	{ 0x00, 0x80, 0x00, 0 },
	{ 0x00, 0x80, 0x80, 0 },
	{ 0x80, 0x00, 0x00, 0 },
	{ 0x80, 0x00, 0x80, 0 },
	{ 0x80, 0x80, 0x00, 0 },
	{ 0x80, 0x80, 0x80, 0 },

	{ 0xC0, 0xC0, 0xC0, 0 },
};


/////////////////////////////////////////////////////////////////////////////
// CE DIBSection global functions

UINT CEGetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries, RGBQUAD *pColors);
/*static*/ int CDIBSectionCE::NumColorEntries(int nBitsPerPixel) 
{
	int nColors = 0;

	switch (nBitsPerPixel) 
	{
	case 1:  nColors = 2;   break;
#ifdef _WIN32_WCE
	case 2:  nColors = 4;   break;   // winCE only       
#endif
	case 4:  nColors = 16;  break;
	case 8:  nColors = 256; break;
	case 16:
	case 24:
	case 32: nColors = 0;   break;   // 16,24 or 32 bpp have no color table

	default:
		ASSERT(FALSE);
	}

	return nColors;
}

/*static*/ int CDIBSectionCE::BytesPerLine(int nWidth, int nBitsPerPixel)
{
	int nBytesPerLine = nWidth * nBitsPerPixel;
	nBytesPerLine = ( (nBytesPerLine + 31) & (~31) ) / 8;

	return nBytesPerLine;
}

#ifndef DIBSECTION_NO_PALETTE

// 
// --- In?: palette - reference to a palette object which will be filled
//           nNumColours - number of colour entries to fill
// --- Out :
// --- Returns : TRUE on success, false otherwise
// --- Effect : Creates a halftone color palette independant of screen color depth.
//              palette will be filled with the colors, and nNumColours is the No.
//              of colors to file. If nNumColoursis 0 or > 256, then 256 colors are used.
/*static*/ BOOL CDIBSectionCE::CreateHalftonePalette(CPalette& palette, int nNumColours)
{
	palette.DeleteObject();

	int nNumStandardColours = sizeof(ms_StdColours) / sizeof(ms_StdColours[0]);
	int nIndex = 0;
	int nNumEntries = nNumColours;
	if (nNumEntries <= 0 || nNumEntries > 256)
		nNumEntries = 256;

	PALETTEINFO PalInfo;                   
	PalInfo.palNumEntries = (WORD) nNumEntries;

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

		PalInfo.palPalEntry[nIndex].peRed   = ms_StdColours[i].rgbRed;
		PalInfo.palPalEntry[nIndex].peGreen = ms_StdColours[i].rgbGreen;
		PalInfo.palPalEntry[nIndex].peBlue  = ms_StdColours[i].rgbBlue;
		PalInfo.palPalEntry[nIndex].peFlags = 0;
		nIndex++;
	}

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

				PalInfo.palPalEntry[nIndex].peRed   = (BYTE) ((red*255)/5);
				PalInfo.palPalEntry[nIndex].peGreen = (BYTE) ((green*255)/5);
				PalInfo.palPalEntry[nIndex].peBlue  = (BYTE) ((blue*255)/5);
				PalInfo.palPalEntry[nIndex].peFlags = 0;
				nIndex++;
			}

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

				PalInfo.palPalEntry[nIndex].peRed   = (BYTE) (grey*255/23);
				PalInfo.palPalEntry[nIndex].peGreen = (BYTE) (grey*255/23);
				PalInfo.palPalEntry[nIndex].peBlue  = (BYTE) (grey*255/23);
				PalInfo.palPalEntry[nIndex].peFlags = 0;
				nIndex++;
			}

			return palette.CreatePalette((LPLOGPALETTE) PalInfo);
}
#endif // DIBSECTION_NO_PALETTE


/////////////////////////////////////////////////////////////////////////////
// CDIBSectionCE

CDIBSectionCE::CDIBSectionCE()
{
	m_hBitmap     = NULL;
	m_hOldBitmap  = NULL;
	m_bReuseMemDC = FALSE;

	DeleteObject(); // This will initialise to a known state - ie. empty
}

CDIBSectionCE::~CDIBSectionCE()
{
	DeleteObject();
}

// --- In?:
// --- Out :
// --- Returns :
// --- Effect : Resets the object to an empty state, and frees all memory used.
void CDIBSectionCE::DeleteObject()
{
	// Unselect the bitmap out of the memory DC before deleting bitmap
	ReleaseMemoryDC(TRUE);

	if (m_hBitmap)
		::DeleteObject(m_hBitmap);
	m_hBitmap = NULL;
	m_ppvBits = NULL;

#ifndef DIBSECTION_NO_PALETTE
	m_Palette.DeleteObject();
#endif

	memset(&m_DIBinfo, 0, sizeof(m_DIBinfo));

	m_iColorDataType = DIB_RGB_COLORS;
	m_iColorTableSize = 0;
}

/////////////////////////////////////////////////////////////////////////////
// CDIBSectionCE diagnostics




/////////////////////////////////////////////////////////////////////////////
// CDIBSectionCE operations

// --- In?: pDC - Pointer to a device context
//           ptDest - point at which the topleft corner of the image is drawn
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Draws the image 1:1 on the device context
BOOL CDIBSectionCE::Draw(CDC* pDC, CPoint ptDest, BOOL bForceBackground /*=FALSE*/) 
{ 

	if (!m_hBitmap)
		return FALSE;

	CSize size = GetSize();
	CPoint ptOrigin = CPoint(0,0);

	/*
	pDC->BitBlt(ptDest.x, ptDest.y, size.cx, size.cy,&m_MemDC, 
	ptOrigin.x, ptOrigin.y, SRCCOPY);

	return TRUE;
	*/

	// Create a memory DC compatible with the destination DC
	CDC* pMemDC = GetMemoryDC(pDC, FALSE);
	if (!pMemDC)
		return FALSE;

#ifndef DIBSECTION_NO_PALETTE
	// Select and realize the palette
	CPalette* pOldPalette = NULL;
	if (m_Palette.m_hObject && UsesPalette(pDC))
	{
		pOldPalette = pDC->SelectPalette(&m_Palette, bForceBackground);
		pDC->RealizePalette();
	}
#endif // DIBSECTION_NO_PALETTE

	BOOL bResult = pDC->BitBlt(ptDest.x, ptDest.y, size.cx, size.cy, pMemDC, 
		ptOrigin.x, ptOrigin.y, SRCCOPY);

#ifndef DIBSECTION_NO_PALETTE
	if (pOldPalette)
		pDC->SelectPalette(pOldPalette, FALSE);
#endif // DIBSECTION_NO_PALETTE

	ReleaseMemoryDC();
	return bResult;
}

// --- In?: pDC - Pointer to a device context
//           ptDest - point at which the topleft corner of the image is drawn
//           size - size to stretch the image
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Stretch draws the image to the desired size on the device context
BOOL CDIBSectionCE::Stretch(CDC* pDC, CPoint ptDest, CSize size,
							BOOL bForceBackground /*=FALSE*/) 
{ 


	if (!m_hBitmap)
		return FALSE;


	CPoint ptOrigin = CPoint(0,0);
	CSize imagesize = GetSize();
	/*
	///=====================

	pDC->StretchBlt(ptDest.x, ptDest.y, size.cx, size.cy, 
	&m_MemDC, 
	ptOrigin.x, ptOrigin.y, imagesize.cx, imagesize.cy, 
	SRCCOPY);
	return TRUE;

	*/

	// Create a memory DC compatible with the destination DC
	CDC* pMemDC = GetMemoryDC(pDC, FALSE);
	if (!pMemDC)
		return FALSE;

#ifndef DIBSECTION_NO_PALETTE
	// Select and realize the palette
	CPalette* pOldPalette = NULL;
	if (m_Palette.m_hObject && UsesPalette(pDC))
	{
		pOldPalette = pDC->SelectPalette(&m_Palette, bForceBackground);
		pDC->RealizePalette();
	}
#endif // DIBSECTION_NO_PALETTE

#ifndef _WIN32_WCE
	pDC->SetStretchBltMode(COLORONCOLOR);
#endif // _WIN32_WCE

	BOOL bResult = pDC->StretchBlt(ptDest.x, ptDest.y, size.cx, size.cy, 
		pMemDC, 
		ptOrigin.x, ptOrigin.y, imagesize.cx, imagesize.cy, 
		SRCCOPY);

#ifndef DIBSECTION_NO_PALETTE
	if (pOldPalette)
		pDC->SelectPalette(pOldPalette, FALSE);
#endif // DIBSECTION_NO_PALETTE

	ReleaseMemoryDC();
	return bResult;
}

//////////////////////////////////////////////////////////////////////////////

// --- In?: lpBitmapInfo - pointer to a BITMAPINFO structure
//           lpBits - pointer to image bits
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Initialises the bitmap using the information in lpBitmapInfo to determine
//              the dimensions and colours, and the then sets the bits from the bits in
//              lpBits. If failure, then object is initialised back to an empty bitmap.
BOOL CDIBSectionCE::SetBitmap(LPBITMAPINFO lpBitmapInfo, LPVOID lpBits)
{
	DeleteObject();

	if (!lpBitmapInfo || !lpBits)
		return FALSE;

	HDC hDC = NULL;
	TRY {
		BITMAPINFOHEADER& bmih = lpBitmapInfo->bmiHeader;

		// Compute the number of colours in the colour table
		m_iColorTableSize = NumColorEntries(bmih.biBitCount);

		DWORD dwBitmapInfoSize = sizeof(BITMAPINFO) + m_iColorTableSize*sizeof(RGBQUAD);

		// Copy over BITMAPINFO contents
		memcpy(&m_DIBinfo, lpBitmapInfo, dwBitmapInfoSize);

		// Should now have all the info we need to create the sucker.
		//TRACE(_T("Width %d, Height %d, Bits/pixel %d, Image Size %d\n"),
		//      bmih.biWidth, bmih.biHeight, bmih.biBitCount, bmih.biSizeImage);

		// Create a DC which will be used to get DIB, then create DIBsection
		hDC = ::GetDC(NULL);
		if (!hDC) 
		{
			TRACE0("Unable to get DC\n");
			AfxThrowResourceException();
		}

		//m_iColorDataType = DIB_PAL_COLORS;
		//m_DIBinfo.bmiHeader.biCompression = 0;
		DWORD dwImageSize = m_DIBinfo.bmiHeader.biSizeImage;
		if (dwImageSize == 0)
		{
			int nBytesPerLine = BytesPerLine(lpBitmapInfo->bmiHeader.biWidth, 
				lpBitmapInfo->bmiHeader.biBitCount);
			dwImageSize = nBytesPerLine * lpBitmapInfo->bmiHeader.biHeight;
		}

		//解码数据流
		int nWidth = m_DIBinfo.bmiHeader.biWidth;
		int nHeight =  m_DIBinfo.bmiHeader.biHeight;

		if(m_DIBinfo.bmiHeader.biCompression != 0 )
		{
			int nRealWidth = m_DIBinfo.bmiHeader.biWidth;
			if((nRealWidth % 4) != 0)
				nRealWidth += 4 - (nRealWidth%4);
			m_DIBinfo.bmiHeader.biWidth = nRealWidth;
			int nRealHeight = m_DIBinfo.bmiHeader.biHeight;
			//delete []lpBits;
			BYTE *p = new BYTE[nRealHeight*nRealWidth];
			memset(p,0,nRealHeight*nRealWidth);
			m_DIBinfo.bmiHeader.biSizeImage = nRealHeight*nRealWidth;
			//last dwImageSize is the compassed bytes
			if(m_DIBinfo.bmiHeader.biCompression == 1)
				BI_RLE8Processor(m_MemDC.GetSafeHdc(),(BYTE*)lpBits,dwImageSize,p,nRealWidth);
			else
				return FALSE;
			// BI_RLE4Processor(m_MemDC.GetSafeHdc(),(BYTE*)lpBits,dwImageSize,p,505);
			lpBits = p;
			m_DIBinfo.bmiHeader.biCompression = 0;

		};

		m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*) m_DIBinfo,
			m_iColorDataType, &m_ppvBits, NULL, 0);

		::ReleaseDC(NULL, hDC);
		if (!m_hBitmap)
		{
			TRACE(L"CreateDIBSection failed %d\n", GetLastError());
			AfxThrowResourceException();
		}

		dwImageSize = m_DIBinfo.bmiHeader.biSizeImage;
		if (dwImageSize == 0)
		{
			int nBytesPerLine = BytesPerLine(lpBitmapInfo->bmiHeader.biWidth, 
				lpBitmapInfo->bmiHeader.biBitCount);
			dwImageSize = nBytesPerLine * lpBitmapInfo->bmiHeader.biHeight;
		}


#ifndef _WIN32_WCE
		// Flush the GDI batch queue 
		GdiFlush();
#endif

		memcpy(m_ppvBits, lpBits, dwImageSize);

#ifndef DIBSECTION_NO_PALETTE
		if (!CreatePalette())
		{
			TRACE0("Unable to create palette\n");
			AfxThrowResourceException();
		}
#endif // DIBSECTION_NO_PALETTE
	}
	CATCH (CException, e)
	{
		e->Delete();
		_ShowLastError();
		if (hDC) 
			::ReleaseDC(NULL, hDC);
		DeleteObject();
		return FALSE;
	}
	END_CATCH

		return TRUE;
}

⌨️ 快捷键说明

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