📄 dib.cpp
字号:
if (! ReadDib(&file))
{
CString str = lpszDibFile;
str += " : Read file error!";
AfxMessageBox(str);
return FALSE;
}
}
CATCH (CException, e)
{
CString str = lpszDibFile;
str += " : Read file error!";
AfxMessageBox(str);
return FALSE;
}
END_CATCH
return TRUE;
}
BOOL CDib::SaveDib(LPCSTR lpszDibFile)
{
TRY
{
CFile file(lpszDibFile, CFile::modeCreate|CFile::modeWrite);
if (! WriteDib(&file))
{
CString str = lpszDibFile;
str += " : Write file error!";
AfxMessageBox(str);
return FALSE;
}
}
CATCH (CException, e)
{
CString str = lpszDibFile;
str += " : Write file error!";
AfxMessageBox(str);
return FALSE;
}
END_CATCH
return TRUE;
}
BOOL CDib::ReadDib(CFile *pFile)
{
ASSERT(m_dwLength == 0L);
TRY
{
m_dwLength = pFile->GetLength();
if (! AllocMemory())
return FALSE;
DWORD dwCount = pFile->ReadHuge(m_lpBuf, m_dwLength);
if (dwCount != m_dwLength)
return FALSE;
}
CATCH (CException, e)
{
return FALSE;
}
END_CATCH
if (m_lpBMFH->bfType != 0x4d42)
return FALSE;
if (IS_WIN30_DIB(m_lpBMIH))
ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount== 4)||
(m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24));
else
ASSERT((m_lpBMCH->bcBitCount==1)||(m_lpBMCH->bcBitCount== 4)||
(m_lpBMCH->bcBitCount==8)||(m_lpBMCH->bcBitCount==24));
m_lpData = (LPSTR)m_lpBMFH + m_lpBMFH->bfOffBits;
m_nBits = m_lpBMIH->biBitCount;
return TRUE;
}
BOOL CDib::WriteDib(CFile *pFile)
{
TRY
{
pFile->WriteHuge(m_lpBuf, m_dwLength);
}
CATCH (CException, e)
{
return FALSE;
}
END_CATCH
return TRUE;
}
BOOL CDib::Display(CDC * pDC, CPoint ptDest, DWORD dwRop)
{
BOOL bSuccess = FALSE;
if (m_lpBuf == NULL)
return bSuccess;
CPalette* pOldPal = pDC->SelectPalette(GetPalette(), TRUE);
pDC->RealizePalette();
pDC->SetStretchBltMode(COLORONCOLOR);
bSuccess = ::StretchDIBits(pDC->GetSafeHdc(),
ptDest.x,
ptDest.y,
(int)m_lpBMIH->biWidth,
(int)m_lpBMIH->biHeight,
0,
0,
(int)m_lpBMIH->biWidth,
(int)m_lpBMIH->biHeight,
m_lpData,
m_lpBMI,
DIB_RGB_COLORS,
dwRop);
pDC->SelectPalette(pOldPal, FALSE); //TRUE);
return bSuccess;
}
BOOL CDib::Display(CDC* pDC, CRect rcDest, CRect rcSrc, DWORD dwRop)
{
BOOL bSuccess = FALSE;
if (m_lpBuf == NULL)
return bSuccess;
CPalette* pOldPal = pDC->SelectPalette(GetPalette(), TRUE);
pDC->RealizePalette();
pDC->SetStretchBltMode(COLORONCOLOR);
bSuccess = ::StretchDIBits(pDC->GetSafeHdc(),
rcDest.left,
rcDest.top,
rcDest.Width(),
rcDest.Height(),
rcSrc.left,
(int)m_lpBMIH->biHeight-rcSrc.top-rcSrc.Height(), // SrcY --rcSrc.top,
rcSrc.Width(),
rcSrc.Height(),
m_lpData,
m_lpBMI,
DIB_RGB_COLORS,
dwRop);
pDC->SelectPalette(pOldPal, FALSE); //TRUE);
return bSuccess;
}
CPalette * CDib::GetPalette()
{
if (m_pPalette == NULL)
MakePalette();
return m_pPalette;
}
int CDib::GetColorBits()
{
return m_nBits;
}
BOOL CDib::IsEmpty()
{
if (m_dwLength == 0L || m_hDib == NULL)
return TRUE;
else
return FALSE;
}
DWORD CDib::GetLength()
{
return m_dwLength;
}
WORD CDib::GetWidth()
{
if (IsEmpty())
return 0;
if (IS_WIN30_DIB(m_lpBMIH))
return (WORD)(m_lpBMIH->biWidth);
else
return (WORD)(m_lpBMCH->bcWidth);
}
WORD CDib::GetHeight()
{
if (IsEmpty())
return 0;
if (IS_WIN30_DIB(m_lpBMIH))
return (WORD)(m_lpBMIH->biHeight);
else
return (WORD)(m_lpBMCH->bcHeight);
}
HDIB CDib::GetHandle()
{
return m_hDib;
}
HDIB CDib::CopyHandle()
{
if (IsEmpty())
return NULL;
HGLOBAL hCopy = ::GlobalAlloc(GHND, m_dwLength);
if (hCopy == NULL)
return NULL;
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
memcpy(lpCopy, m_lpBMI, m_dwLength);
::GlobalUnlock(hCopy);
return hCopy;
}
HANDLE CDib::CopyDataHandle()
{
if (IsEmpty())
return NULL;
DWORD dwDataLength = m_dwLength-sizeof(BITMAPFILEHEADER);
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwDataLength);
if (hCopy == NULL)
return NULL;
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
memcpy(lpCopy, m_lpBMI, dwDataLength);
::GlobalUnlock(hCopy);
return hCopy;
}
WORD CDib::GetNumColors()
{
WORD wBitCount; // DIB bit count
/* If this is a Windows-style DIB, the number of colors in the
* color table can be less than the number of bits per pixel
* allows for (i.e. lpbi->biClrUsed can be set to some value).
* If this is the case, return the appropriate value.
*/
if (IS_WIN30_DIB(m_lpBMIH))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)m_lpBMIH)->biClrUsed;
if (dwClrUsed != 0)
return (WORD)dwClrUsed;
}
/* Calculate the number of colors in the color table based on
* the number of bits per pixel for the DIB.
*/
if (IS_WIN30_DIB(m_lpBMIH))
wBitCount = ((LPBITMAPINFOHEADER)m_lpBMIH)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)m_lpBMIH)->bcBitCount;
/* return number of colors based on bits per pixel
* This function calculates the number of colors in the DIB's color table
* by finding the bits per pixel for the DIB (whether Win3.0 or other-style
* DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256,
* if 24, no colors in color table.
*/
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
WORD CDib::GetPaletteSize()
{
// calculate the size required by the palette
if (IS_WIN30_DIB (m_lpBMIH))
return (WORD)(GetNumColors() * sizeof(RGBQUAD));
else
return (WORD)(GetNumColors() * sizeof(RGBTRIPLE));
}
BOOL CDib::AllocMemory(BOOL bRealloc /* default = FALSE */)
{
if (bRealloc)
m_hDib = ::GlobalReAlloc(m_hDib, m_dwLength, GMEM_MOVEABLE | GMEM_ZEROINIT);
//m_lpBuf = (char *)GlobalReAllocPtr(m_lpBuf, m_dwLength, GHND);
else
m_hDib = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_dwLength);
//m_lpBuf = (char *)GlobalAllocPtr(GHND, m_dwLength);
if (m_hDib == NULL)
{
return FALSE;
}
m_lpBuf = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib);
if (m_lpBuf == NULL)
{
AfxMessageBox("Allocate DIB memory error!");
m_dwLength = 0L;
m_nBits = 0;
m_hDib = NULL;
return FALSE;
}
m_lpBMFH = (LPBITMAPFILEHEADER)m_lpBuf;
m_lpBMIH = (LPBITMAPINFOHEADER)((LPSTR)m_lpBuf + sizeof(BITMAPFILEHEADER));
m_lpBMI = (LPBITMAPINFO)m_lpBMIH;
m_lpBMCH = (LPBITMAPCOREHEADER)m_lpBMIH;
m_lpBMC = (LPBITMAPCOREINFO)m_lpBMIH;
return TRUE;
}
BOOL CDib::MakePalette()
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL; // handle to a palette
WORD wNumColors; // number of colors in color table
if (m_pPalette != NULL)
return TRUE;
if (m_lpBuf == NULL)
return FALSE;
wNumColors = GetNumColors();
if (wNumColors == 0)
return FALSE;
hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * wNumColors);
if (hLogPal == 0)
return FALSE;
lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
/* set version and number of palette entries */
lpPal->palVersion = 0x300;
lpPal->palNumEntries = (WORD)wNumColors;
/* is this a Win 3.0 DIB? */
BOOL bWinStyleDIB = IS_WIN30_DIB(m_lpBMIH);
for (int i=0; i<(int)wNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = m_lpBMI->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = m_lpBMI->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = m_lpBMI->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
lpPal->palPalEntry[i].peRed = m_lpBMC->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = m_lpBMC->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = m_lpBMC->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
}
m_pPalette = new CPalette;
BOOL bResult = m_pPalette->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL) hLogPal);
::GlobalFree((HGLOBAL) hLogPal);
return bResult;
}
CBitmap * CDib::MakeBitmap(CDC * pDC)
{
if (m_pBitmap != NULL)
return pDC->SelectObject(m_pBitmap); // return Original-bitmap
if (IsEmpty())
return NULL;
CPalette *pOldPal = pDC->SelectPalette(GetPalette(), TRUE);
pDC->RealizePalette();
int nPlanes = pDC->GetDeviceCaps(PLANES);
int nBitsPixel = pDC->GetDeviceCaps(BITSPIXEL);
CBitmap* pConfigBitmap = new CBitmap;
char bits[100];
if (m_lpBMIH->biBitCount == 1)
pConfigBitmap->CreateBitmap(1, 1, 1, 1, bits);
else
pConfigBitmap->CreateBitmap(1, 1, nPlanes, nBitsPixel, bits);
CBitmap* pOriginalBitmap = (CBitmap *)pDC->SelectObject(pConfigBitmap);
DWORD dwFore, dwBack;
if (GetMonoColors(dwFore, dwBack))
SetMonoColors(0L, 0xFFFFFFL);
HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(),
m_lpBMIH, CBM_INIT,
(CONST BYTE *)(m_lpBuf+m_lpBMFH->bfOffBits),
m_lpBMI, DIB_RGB_COLORS);
if (hBitmap == NULL)
{
TRACE("null bitmap!\n");
return NULL;
}
SetMonoColors(dwFore, dwBack);
m_pBitmap = new CBitmap;
m_pBitmap->Attach(hBitmap);
pDC->SelectObject(m_pBitmap); // delete config-bitmap
delete pConfigBitmap;
pDC->SelectPalette(pOldPal, FALSE);
return pOriginalBitmap; // return original-bitmap
}
void CDib::SetMonoColors(DWORD dwForegrpund, DWORD dwBackGround)
{
if (m_nBits != 1)
return;
unsigned long far* pPalette = (unsigned long far*)
((LPSTR)m_lpBMIH+sizeof(BITMAPINFOHEADER));
*pPalette = dwForegrpund;
*(++pPalette) = dwBackGround;
return;
}
BOOL CDib::GetMonoColors(DWORD& dwForegrpund, DWORD& dwBackGround)
{
if (m_nBits != 1)
return FALSE;
unsigned long far* pPalette = (unsigned long far*)
((LPSTR)m_lpBMIH+sizeof(BITMAPINFOHEADER));
dwForegrpund = *pPalette;
dwBackGround = *(++pPalette);
return TRUE;
}
HANDLE CopyHandle (HANDLE h)
{
if (h == NULL)
return NULL;
DWORD dwLen = ::GlobalSize((HGLOBAL) h);
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
if (hCopy != NULL)
{
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void* lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -