📄 dibapi.cpp
字号:
#include "stdafx.h"
#include "dibapi.h"
#include <io.h>
#include <errno.h>
#include <math.h>
#include <direct.h>
//DIB文件头标志 ,0x4D42
#define DIB_HEADER_MARKER 0x4D42
BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette * pPal)
{
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
BOOL bSuccess=false;
HPALETTE hPal=NULL;
HPALETTE hOldPal=NULL;
if(hDIB==NULL)
{return FALSE;
}
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=::FindDIBBits(lpDIBHdr);
if(pPal!=NULL)
{
hPal=(HPALETTE)pPal->m_hObject;
hOldPal=::SelectPalette(hDC,hPal,true);
}
::SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&
(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
{
bSuccess=::SetDIBitsToDevice(hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
(int)DIBHeight(lpDIBHdr)-
lpDIBRect->top-RECTHEIGHT(lpDIBRect),
0,
(WORD)DIBHeight(lpDIBHdr),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS);
}
else
{
bSuccess=::StretchDIBits( hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
lpDIBRect->top,
RECTWIDTH(lpDIBRect),
RECTHEIGHT(lpDIBRect),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
}
::GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal!=NULL)
{
::SelectPalette(hDC,hOldPal,true);
}
return true;
}
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette *pPal)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal=NULL;
WORD wNumColors;
LPSTR lpbi;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
BOOL bResult=false;
if(hDIB==NULL)
{
return false;
}
lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=::DIBNumColors(lpbi);
if(wNumColors!=0)
{
hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
{
::GlobalUnlock((HGLOBAL)hDIB);
return false;
}
lpPal=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=(WORD)wNumColors;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
for(int i=0;i<(int)wNumColors;i++)
{
if(bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
}
}
bResult=pPal->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL)hLogPal);
::GlobalFree((HGLOBAL)hLogPal);
}
::GlobalUnlock((HGLOBAL)hDIB);
return bResult;
}
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
return (lpbi+*(LPDWORD)lpbi+PaletteSize(lpbi));
}
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
{
return lpbmi->biWidth;
}
else
{
return (DWORD)lpbmc->bcWidth;
}
}
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
{
return lpbmi->biHeight;
}
else
{
return (DWORD)lpbmc->bcHeight;
}
}
WORD WINAPI PaletteSize(LPSTR lpbi)
{
if(IS_WIN30_DIB(lpbi))
{
return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBQUAD));
}
else
{
return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
}
}
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
if(IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if(dwClrUsed!=0)
{
return (WORD)dwClrUsed;
}
}
if(IS_WIN30_DIB(lpbi))
{
wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
}
else
{
wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
}
switch(wBitCount)
{
case 1:
return 2;break;
case 4:
return 16;break;
case 8:
return 256;break;
default:
return 0;
}
}
HGLOBAL WINAPI CopyHandle(HGLOBAL 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;
}
BOOL WINAPI SaveDIB(HDIB hDib,CFile &file)
{
BITMAPFILEHEADER bmfHdr;
LPBITMAPINFOHEADER lpBI;
DWORD dwDIBSize;
if(hDib==NULL)
{
return false;
}
lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
if(lpBI==NULL)
{
return false;
}
if(!IS_WIN30_DIB(lpBI))
{
::GlobalUnlock((HGLOBAL)hDib);
return false;
}
bmfHdr.bfType=DIB_HEADER_MARKER;
dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)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((LPSTR)lpBI);
TRY
{
file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
file.WriteHuge(lpBI,dwDIBSize);
}
CATCH(CFileException,e)
{
::GlobalUnlock((HGLOBAL)hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL)hDib);
return true;
}
HDIB WINAPI ReadDIBFile(CFile &file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
dwBitsSize=file.GetLength();
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
{
return NULL;
}
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
{
return NULL;
}
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
if(hDIB==0)
{
return NULL;
}
pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=
dwBitsSize-sizeof(BITMAPFILEHEADER))
{
::GlobalUnlock((HGLOBAL)hDIB);
::GlobalFree((HGLOBAL)hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL)hDIB);
return hDIB;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -