📄 dib.cpp
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Dib.h"
#include "DibAPI.h"
#include "MACRO.h"
/////////////////////////////////////////////////////////////////////////////
// CDib
IMPLEMENT_SERIAL( CDib, CObject, VERSIONABLE_SCHEMA | 2 )
/****************************************************************************
Constructor of class CDib
*****************************************************************************/
CDib::CDib()
{
m_hDib = NULL;
m_pBitmap = NULL;
m_pPalette = NULL;
}
/****************************************************************************
Desconstructor
parameter: void
return: void
****************************************************************************/
CDib::~CDib()
{
Destroy();
if(m_pBitmap != NULL)
{
delete m_pBitmap;
m_pBitmap = NULL;
}
if(m_pPalette != NULL)
{
delete m_pPalette;
m_pPalette = NULL;
}
}
/****************************************************************************
Serialization
parameter: void
return: void
****************************************************************************/
void CDib::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
ar.Flush();
if(ar.IsStoring())
{
Write(ar.GetFile());
}
else
{
Read(ar.GetFile());
}
}
/****************************************************************************
default constructor
parameter: void
return: BOOL
****************************************************************************/
BOOL CDib::Create()
{
HDIB hDib = CreateDefaultDIB(100, 100);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a empty CDib with system's palette
parameter: DWORD(dwWidth), DWORD(dwHeight)
return: BOOL
****************************************************************************/
BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight)
{
HDIB hDib = CreateDefaultDIB(dwWidth,dwHeight);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a empty CDib
parameter: DWORD(dwWidth), DWORD(dwHeight), WORD(wBitCount)
return: BOOL
****************************************************************************/
BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight, WORD dwBitCount)
{
HDIB hDib = CreateDIB(dwWidth,dwHeight,dwBitCount);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a default CDib from memory block of a DIB
parameter: LPBYTE(lpDIB)
return: BOOL
****************************************************************************/
BOOL CDib::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)
{
GlobalUnlock(hDib);
return FALSE;
}
memcpy(lpbi, lpDib, dwSize);
GlobalUnlock(hDib);
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a CDib from memory block of a DIB
parameter: LPBYTE(lpDIB), WORD(wBitCount)
return: BOOL
****************************************************************************/
BOOL CDib::Create(LPBYTE lpDib, WORD wBitCount)
{
if(lpDib == NULL)
return FALSE;
if(!Create(lpDib))
return FALSE;
WORD wBits = ((LPBITMAPINFOHEADER)lpDib)->biBitCount;
if(wBits == wBitCount)
return TRUE;
HDIB hNewDib = ConvertDIBFormat(m_hDib, wBitCount, NULL);
if(!hNewDib)
return FALSE;
Destroy();
m_hDib = hNewDib;
return UpdateInternal();
}
/****************************************************************************
Create a default CDib from DIBSection of a DIB
parameter: HBITMAP(hBitmap)
return: BOOL
****************************************************************************/
BOOL CDib::Create(HBITMAP hBitmap)
{
if(!hBitmap)
return FALSE;
HDIB hDib = DIBSectionToDIB(hBitmap);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a CDib from DIBSection of a DIB
parameter: HBITMAP(hBitmap), WORD(wBitCount)
return: BOOL
****************************************************************************/
BOOL CDib::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 UpdateInternal();
}
/****************************************************************************
Create a CDib from DIBSection of a DIB with specifed palette
parameter: HBITMAP(hBitmap), HPALETTE(hPalette)
return: BOOL
****************************************************************************/
BOOL CDib::Create(HBITMAP hBitmap, HPALETTE hPalette)
{
if(!hBitmap)
return FALSE;
HDIB hDib = BitmapToDIB(hBitmap, hPalette);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a CDib from DIBSection of a DIB with specifed palette
parameter: HBITMAP(hBitmap), HPALETTE(hPalette), WORD(wBitCount)
return: BOOL
****************************************************************************/
BOOL CDib::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 UpdateInternal();
}
/****************************************************************************
Create default a CDib from specified area of screen
parameter: CRect(rcScreen)
return: BOOL
****************************************************************************/
BOOL CDib::Create(CRect rcScreen)
{
HDIB hDib = CopyScreenToDIB(&rcScreen);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Create a default CDib from specified area of a window
parameter: HWND, WORD(fPrintArea)
return: BOOL
****************************************************************************/
BOOL CDib::Create(HWND hWnd, WORD fPrintArea)
{
HDIB hDib = CopyWindowToDIB(hWnd, fPrintArea);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/******************************************************
Create a default CDib from specified area of a window
parameter: HWND, CRect(rcClientArea)
return: BOOL
******************************************************/
BOOL CDib::Create(HWND hWnd, CRect rcClientArea)
{
HDIB hDib = CopyClientRectToDIB(hWnd, &rcClientArea);
if(!hDib)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/******************************************************
Associate specified handle of DIB to CDib
parameter: HDIB
return: BOOL
******************************************************/
BOOL CDib::Attach(HDIB hDib)
{
if(hDib == NULL)
return FALSE;
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
/****************************************************************************
Free memory for DIB
parameter: void
return: void
****************************************************************************/
void CDib::Destroy()
{
if(m_hDib != NULL)
{
DestroyDIB(m_hDib);
m_hDib = NULL;
}
}
/****************************************************************************
Update data of CDib
parameter: void
return BOOL
****************************************************************************/
BOOL CDib::UpdateInternal()
{
BuildPalette();
return BuildBitmap();
}
/******************************************************
Update CDib's palette
parameter: void
return: BOOL
******************************************************/
BOOL CDib::BuildPalette()
{
if(m_pPalette != NULL)
{
delete m_pPalette;
m_pPalette = NULL;
}
HPALETTE hPalette = CreateDIBPalette(m_hDib);
if(hPalette == NULL)
return FALSE;
m_pPalette = new CPalette;
m_pPalette->Attach(hPalette);
return TRUE;
}
/******************************************************
Update CDib's Bitmap
parameter: void
return: BOOL
******************************************************/
BOOL CDib::BuildBitmap()
{
if(m_pBitmap != NULL)
{
delete m_pBitmap;
m_pBitmap = NULL;
m_hBitmap = NULL;
}
m_hBitmap = DIBToDIBSection(m_hDib);
if(m_hBitmap == NULL)
return FALSE;
m_pBitmap = new CBitmap;
m_pBitmap->Attach(m_hBitmap);
return TRUE;
}
/******************************************************
Detach CDib from handle of DIB
parameter: void
return: HDIB
******************************************************/
HDIB CDib::DeTach()
{
if(m_hDib == NULL)
return FALSE;
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;
}
/******************************************************
Read CDib from file
parameter: CFile*
return: BOOL
******************************************************/
BOOL CDib::Read(CFile* pFile)
{
SetCursor(LoadCursor(NULL, IDC_WAIT));
LPBITMAPINFOHEADER lpbi;
DWORD dwSize;
HDIB hDib;
TRY
{
BITMAPFILEHEADER bmfHdr;
pFile->Read(&bmfHdr, sizeof(BITMAPFILEHEADER));
if((bmfHdr.bfType) != DIB_HEADER_MARKER)
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
DWORD dwLength = pFile->GetLength();
if(bmfHdr.bfSize != dwLength)
bmfHdr.bfSize = dwLength;
dwSize = bmfHdr.bfSize-sizeof(BITMAPFILEHEADER);
hDib = GlobalAlloc(GHND, dwSize);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
DWORD dwCount = pFile->ReadHuge(lpbi, dwSize);
if(dwCount != dwSize)
{
GlobalUnlock(hDib);
GlobalFree(hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
if(lpbi->biSize != sizeof(BITMAPINFOHEADER))
{
GlobalUnlock(hDib);
GlobalFree(hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
int nNumColors = (UINT)lpbi->biClrUsed;
if(nNumColors == 0)
{
if(lpbi->biBitCount != 24)
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)
{
GlobalUnlock(hDib);
GlobalFree(hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
END_CATCH
BOOL bSuccess = Create((LPBYTE)lpbi);
GlobalUnlock(hDib);
GlobalFree(hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
}
/******************************************************
Write file from CDib
parameter: CFile*
return: BOOL
******************************************************/
BOOL CDib::Write(CFile* pFile)
{
SetCursor(LoadCursor(NULL,IDC_WAIT));
BITMAPFILEHEADER bmfHdr;
LPBITMAPINFOHEADER lpbi;
DWORD dwDibSize;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
if(!lpbi)
{
GlobalUnlock(m_hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
if(lpbi->biSize != sizeof(BITMAPINFOHEADER))
{
GlobalUnlock(m_hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
bmfHdr.bfType = DIB_HEADER_MARKER;
dwDibSize = *(LPDWORD)lpbi+PaletteSize((LPBYTE)lpbi);
if((lpbi->biClrImportant == BI_RLE8) || (lpbi->biClrImportant == BI_RLE4))
dwDibSize += lpbi->biSizeImage;
else
{
DWORD dwBmBitSize;
dwBmBitSize = WIDTHBYTES((lpbi->biWidth)*((DWORD)lpbi->biBitCount))*lpbi->biHeight;
dwDibSize += dwBmBitSize;
lpbi->biSizeImage = dwBmBitSize;
}
bmfHdr.bfSize = dwDibSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 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);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return FALSE;
}
END_CATCH
GlobalUnlock(m_hDib);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
}
/******************************************************
Load CDib from file
parameter: LPCSTR(file name)
return: BOOL
******************************************************/
BOOL CDib::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;
}
/******************************************************
Save CDib to file
parameter: LPCSTR(target file name)
return: BOOL
******************************************************/
BOOL CDib::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;
}
/******************************************************
Load CDib from file
parameter: UINT, LPCSTR(file name)
return: BOOL
******************************************************/
BOOL CDib::Load(UINT uID, LPCTSTR lpszDibType)
{
LPCSTR lpszDibRes = MAKEINTRESOURCE(uID);
//The MAKEINTRESOURCE macro converts an integer value to a resource
//type compatible with the resource-management functions.
return Load(lpszDibRes, lpszDibType);
}
BOOL CDib::Load(LPCTSTR lpszDibRes,LPCTSTR lpszDibType)
{
HINSTANCE hInst = AfxGetInstanceHandle();
HRSRC hRes = FindResource(hInst, lpszDibRes, lpszDibType);
HGLOBAL hData = LoadResource(hInst, hRes);
//resource ok?
if(hRes == NULL || hData == NULL)
return FALSE;
//get resource buffer
LPBYTE lpBuf = (LPBYTE)LockResource(hData);
//dib?
if(((LPBITMAPFILEHEADER)lpBuf)->bfType != DIB_HEADER_MARKER)
return FALSE;
//CREATE
LPBYTE lpDib = lpBuf+sizeof(BITMAPFILEHEADER);
return Create(lpDib);
}
/******************************************************
Is empty?
parameter: void
return: BOOL
******************************************************/
BOOL CDib::IsEmpty()
{
if(m_hDib == NULL)
return TRUE;
if(!GlobalLock(m_hDib))
return TRUE;
GlobalUnlock(m_hDib);
return FALSE;
}
/******************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -