www.pudn.com > ±ÏÒµÁôÄî²á.rar > MidDib.cpp


#include "stdafx.h" 
#include  
#include  
#include  
#include  
 
#include "MidDib.h" 
 
IMPLEMENT_SERIAL(CMidDib, CObject, 0) 
 
CMidDib::CMidDib() 
{ 
	m_hDib		= NULL; 
	m_hBitmap   = NULL; 
	m_pPalette  = NULL; 
	m_pBitmap   = NULL; 
}            
                                       
CMidDib::~CMidDib() 
{ 
	Destroy(); 
	if (m_pBitmap != NULL) 
	{ 
		delete m_pBitmap; 
		m_pBitmap = NULL; 
	} 
	if (m_pPalette != NULL) 
	{ 
		delete m_pPalette; 
		m_pPalette = NULL; 
	} 
} 
 
void CMidDib::Destroy() 
{ 
	if (m_hDib != NULL) 
	{ 
		DestroyDIB(m_hDib); 
		m_hDib = NULL; 
	} 
} 
 
HDIB CMidDib::Detach() 
{ 
	if (m_hDib == NULL) 
		return NULL; 
 
	HDIB hDib = m_hDib; 
	m_hDib = NULL; 
	if (m_pBitmap != NULL) 
	{ 
		delete m_pBitmap; 
		m_pBitmap = NULL; 
	} 
	if (m_pPalette != NULL) 
	{ 
		delete m_pPalette; 
		m_pPalette = NULL; 
	} 
 
	return hDib; 
} 
 
BOOL CMidDib::Create(DWORD dwWidth, DWORD dwHeight) 
{ 
	HDIB hDib = CreateDefaultDIB(dwWidth, dwHeight); 
	if (! hDib) 
		return FALSE; 
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) 
{ 
	HDIB hDib = CreateDIB(dwWidth, dwHeight, wBitCount); 
	if (! hDib) 
		return FALSE; 
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(LPBYTE lpDIB) 
{ 
	if (lpDIB == NULL) 
		return FALSE; 
	 
	DWORD dwSize = DIBlockSize(lpDIB); 
 
    HDIB hDib  = GlobalAlloc(GHND, dwSize);  
    if (! hDib)  
        return FALSE;  
  
    LPBYTE lpbi  = (LPBYTE)GlobalLock(hDib);  
	if (! lpbi) 
        return FALSE;  
		 
	CopyMemory(lpbi, lpDIB, dwSize); 
	GlobalUnlock(hDib); 
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(LPBYTE lpDIB, 
				  WORD  wBitCount)	 
{ 
	if (lpDIB == NULL) 
		return FALSE; 
	if (! Create(lpDIB)) 
		return FALSE; 
 
	WORD wBits = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; 
	if (wBitCount == wBits) 
		return TRUE; 
 
	HDIB hNewDib = ConvertDIBFormat(m_hDib, wBitCount, NULL);  
	if (! hNewDib) 
		return FALSE; 
 
	Destroy(); 
	m_hDib = hNewDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HBITMAP hBitmap)		 
{ 
	if (! hBitmap) 
        return FALSE;  
 
	HDIB hDib = DIBSectionToDIB(hBitmap);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HBITMAP hBitmap,	 
				  WORD  wBitCount)	 
{ 
	HDIB hNewDib; 
 
	if (! hBitmap) 
        return FALSE;  
 
	HDIB hDib = DIBSectionToDIB(hBitmap);  
    if (! hDib)  
        return FALSE;  
 
	DIBSECTION ds; 
	GetObject(hBitmap, sizeof(DIBSECTION), &ds); 
 
	if (wBitCount == ds.dsBmih.biBitCount) 
		hNewDib = hDib; 
	else 
	{ 
		hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);  
		GlobalFree(hDib); 
	} 
	if (! hNewDib) 
		return FALSE; 
 
	Destroy(); 
	m_hDib = hNewDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HBITMAP hBitmap,	 
			      HPALETTE hPalette)	 
{ 
	if (! hBitmap) 
        return FALSE;  
 
	HDIB hDib = BitmapToDIB(hBitmap, hPalette);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HBITMAP hBitmap,		 
			      HPALETTE hPalette,	 
				  WORD  wBitCount)		  
{ 
	if (! hBitmap) 
        return FALSE;  
 
	HDIB hDib = BitmapToDIB(hBitmap, hPalette, wBitCount);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(CRect rcScreen) 
{ 
	HDIB hDib = CopyScreenToDIB(rcScreen);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HWND hWnd, WORD fPrintArea) 
{ 
	HDIB hDib = CopyWindowToDIB(hWnd, fPrintArea);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Create(HWND hWnd, CRect rcClientArea) 
{ 
	HDIB hDib = CopyClientRectToDIB(hWnd, rcClientArea);  
    if (! hDib)  
        return FALSE;  
 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
BOOL CMidDib::Attach(HDIB hDib) 
{ 
	if (hDib == NULL) 
		return FALSE; 
	 
	Destroy(); 
	m_hDib = hDib; 
	return TRUE; 
} 
 
void CMidDib::Serialize(CArchive& ar) 
{ 
	CObject::Serialize(ar); 
	ar.Flush(); 
	if (ar.IsStoring()) 
	{ 
		Write(ar.GetFile()); 
	} 
    else 
    { 
   		Read(ar.GetFile()); 
    } 
} 
 
BOOL CMidDib::Load(UINT uIDS, LPCTSTR lpszDibType) 
{                                 
	LPCTSTR lpszDibRes = MAKEINTRESOURCE(uIDS); 
 
	return Load(lpszDibRes, lpszDibType); 
} 
 
BOOL CMidDib::Load(LPCTSTR lpszDibRes, LPCTSTR lpszDibType) 
{                                 
	HINSTANCE hInst = AfxGetInstanceHandle(); 
	HRSRC   hRes    = ::FindResource(hInst, lpszDibRes, lpszDibType); 
	HGLOBAL hData   = ::LoadResource(hInst, hRes); 
	if (hRes == NULL || hData == NULL) 
		return FALSE; 
	LPBYTE lpBuf = (LPBYTE)::LockResource(hData); 
	if (((LPBITMAPFILEHEADER)lpBuf)->bfType != DIB_HEADER_MARKER) 
		return FALSE; 
 
	LPBYTE lpDIB = lpBuf + sizeof(BITMAPFILEHEADER); 
	return Create(lpDIB); 
} 
 
BOOL CMidDib::Load(LPCTSTR lpszDibFile) 
{                                 
	TRY 
	{ 
		CFile file(lpszDibFile, CFile::modeRead|CFile::shareDenyNone); 
 
		if (! Read(&file)) 
			return FALSE; 
	} 
	CATCH (CException, e) 
	{ 
		return FALSE; 
	} 
	END_CATCH 
 
	return TRUE; 
}                
 
BOOL CMidDib::Save(LPCTSTR lpszDibFile) 
{ 
	TRY 
	{ 
		CFile file(lpszDibFile, CFile::modeCreate|CFile::modeWrite); 
 
		if (! Write(&file)) 
			return FALSE; 
	} 
	CATCH (CException, e) 
	{ 
		return FALSE; 
	} 
	END_CATCH 
 
	return TRUE; 
} 
 
BOOL CMidDib::Read(CFile *pFile) 
{ 
	WaitCursorBegin(); 
 
	LPBITMAPINFOHEADER lpbi; 
	DWORD dwSize; 
	TRY 
	{ 
		BITMAPFILEHEADER bmfHdr; 
		pFile->Read(&bmfHdr, sizeof(BITMAPFILEHEADER)); 
		if (bmfHdr.bfType != DIB_HEADER_MARKER)  
		{ 
			WaitCursorEnd(); 
			return FALSE; 
		} 
		DWORD dwLength = pFile->GetLength(); 
		if (bmfHdr.bfSize != dwLength) 
			bmfHdr.bfSize = dwLength; 
		dwSize = bmfHdr.bfSize - sizeof(BITMAPFILEHEADER); 
		lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, dwSize); 
		DWORD dwCount = pFile->ReadHuge(lpbi, dwSize); 
		if (dwCount != dwSize) 
		{ 
			GlobalFreePtr(lpbi); 
			WaitCursorEnd(); 
			return FALSE; 
		} 
 
	    if (lpbi->biSize != sizeof(BITMAPINFOHEADER))  
		{ 
			GlobalFreePtr(lpbi); 
			WaitCursorEnd(); 
			return FALSE; 
		} 
		int nNumColors = (UINT)lpbi->biClrUsed; 
		if (nNumColors == 0)  
		{  
	        if (lpbi->biBitCount > 8) 
		        nNumColors = 1 << lpbi->biBitCount;  
		}  
 
	    if (lpbi->biClrUsed == 0)  
		    lpbi->biClrUsed = nNumColors;  
		if (lpbi->biSizeImage == 0)  
			lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight;  
 	} 
	CATCH (CException, e) 
	{ 
		GlobalFreePtr(lpbi); 
		WaitCursorEnd(); 
		return FALSE; 
	} 
	END_CATCH 
	BOOL bSuccess = Create((LPBYTE)lpbi); 
	GlobalFreePtr(lpbi); 
	 
	WaitCursorEnd(); 
 
	return bSuccess; 
} 
 
BOOL CMidDib::Write(CFile *pFile) 
{ 
	WaitCursorBegin(); 
 
    BITMAPFILEHEADER    bmfHdr;     
    LPBITMAPINFOHEADER  lpBI;       
    DWORD               dwDIBSize;  
 
    lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);  
    if (!lpBI)  
	{ 
		GlobalUnlock(m_hDib); 
		WaitCursorEnd(); 
        return FALSE;  
	} 
 
    if (lpBI->biSize != sizeof(BITMAPINFOHEADER))  
    {  
        GlobalUnlock(m_hDib);  
		WaitCursorEnd(); 
        return FALSE;  
    }  
   
    bmfHdr.bfType = DIB_HEADER_MARKER;   
    dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);    
  
    if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))  
        dwDIBSize += lpBI->biSizeImage;  
    else  
    {  
        DWORD dwBmBitsSize;   
        dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *  
                lpBI->biHeight;  
  
        dwDIBSize += dwBmBitsSize;  
  
        lpBI->biSizeImage = dwBmBitsSize;  
    }  
                     
    bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);  
    bmfHdr.bfReserved1 = 0;  
    bmfHdr.bfReserved2 = 0;  
 
      
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize +  
            PaletteSize((LPBYTE)lpBI);  
  
 	TRY 
	{ 
		pFile->Write(&bmfHdr, sizeof(BITMAPFILEHEADER)); 
		pFile->WriteHuge(lpBI, dwDIBSize); 
	} 
	CATCH (CException, e) 
	{ 
        GlobalUnlock(m_hDib);  
		WaitCursorEnd(); 
		return FALSE; 
	} 
	END_CATCH 
 
	GlobalUnlock(m_hDib);  
	WaitCursorEnd(); 
	 
	return TRUE; 
} 
 
CMidDib * CMidDib::Clone() 
{ 
	if (m_hDib == NULL) 
		return NULL; 
 
	HDIB hDIB = CopyHandle(m_hDib); 
	if (hDIB == NULL) 
		return NULL; 
 
	CMidDib *pDib = new CMidDib; 
	pDib->m_hDib = hDIB; 
	return pDib; 
} 
BOOL CMidDib::IsEmpty() 
{ 
	if (m_hDib == NULL) 
		return TRUE; 
 
	if (! GlobalLock(m_hDib)) 
		return TRUE; 
 
	GlobalUnlock(m_hDib); 
	return FALSE; 
} 
 
WORD CMidDib::GetBitCount() 
{ 
    LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);  
    if (!lpBI)  
	{ 
		GlobalUnlock(m_hDib); 
        return 0;  
	} 
  
	WORD wBitCount = lpBI->biBitCount; 
	GlobalUnlock(m_hDib); 
 
	return wBitCount; 
} 
 
LONG CMidDib::GetWidth() 
{ 
    LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);  
	if (! lpDIB) 
	{ 
		GlobalUnlock(m_hDib); 
		return 0; 
	} 
 
	LONG lWidth = (LONG)DIBWidth(lpDIB); 
	GlobalUnlock(m_hDib); 
 
	return lWidth;  
} 
 
LONG CMidDib::GetHeight() 
{ 
    LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);  
	if (! lpDIB) 
	{ 
		GlobalUnlock(m_hDib); 
		return 0; 
	} 
 
	LONG lHeight = (LONG)DIBHeight(lpDIB); 
	GlobalUnlock(m_hDib); 
 
	return lHeight;  
} 
 
BOOL CMidDib::ConvertFormat(WORD wBitCount) 
{ 
	if (IsEmpty()) 
		return FALSE; 
 
	if (GetBitCount() == wBitCount) 
		return TRUE; 
 
	HDIB hNewDib = ConvertDIBFormat(m_hDib, wBitCount, NULL);  
	if (! hNewDib) 
		return FALSE; 
 
	Destroy(); 
	m_hDib = hNewDib; 
	return TRUE; 
} 
 
LPBYTE CMidDib::GetBitsPtr() 
{ 
    LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);  
    if (! lpDIB)  
	{ 
		GlobalUnlock(m_hDib); 
		return NULL; 
	} 
 
	LPBYTE lpData = FindDIBBits(lpDIB); 
	GlobalUnlock(m_hDib); 
 
	return lpData; 
} 
 
HANDLE CMidDib::GetHandle() 
{ 
	return m_hDib; 
}