📄 dibsection.cpp
字号:
break;
pi.palPalEntry[iIndex].peRed = (BYTE)(grey * 255 / 23);
pi.palPalEntry[iIndex].peGreen = (BYTE)(grey * 255 / 23);
pi.palPalEntry[iIndex].peBlue = (BYTE)(grey * 255 / 23);
pi.palPalEntry[iIndex].peFlags = 0;
iIndex++;
}
return CreatePalette(&pi);
#else // USE_HALFTONE_1
// Sanity check on requested number of colors.
if(iNumColors <= 0 || iNumColors > 256)
iNumColors = 256;
else if(iNumColors <= 2)
iNumColors = 2;
else if(iNumColors <= 16)
iNumColors = 16;
else if(iNumColors <= 256)
iNumColors = 256;
PALETTEINFO pi;
pi.palNumEntries = (WORD)iNumColors;
if(iNumColors == 2)
{
// According to the MS article "The Palette Manager: How and Why"
// monochrome palettes not really needed (will use B&W)
pi.palPalEntry[0].peRed = ms_StdColors[0].peRed;
pi.palPalEntry[0].peGreen = ms_StdColors[0].peGreen;
pi.palPalEntry[0].peBlue = ms_StdColors[0].peBlue;
pi.palPalEntry[0].peFlags = 0;
pi.palPalEntry[1].peRed = ms_StdColors[255].peRed;
pi.palPalEntry[1].peGreen = ms_StdColors[255].peGreen;
pi.palPalEntry[1].peBlue = ms_StdColors[255].peBlue;
pi.palPalEntry[1].peFlags = 0;
}
else if(iNumColors == 16)
{
int i;
// According to the MS article "The Palette Manager: How and Why"
// 4-bit palettes not really needed (will use VGA palette)
for(i=0; i<8; i++)
{
pi.palPalEntry[i].peRed = ms_StdColors[i].peRed;
pi.palPalEntry[i].peGreen = ms_StdColors[i].peGreen;
pi.palPalEntry[i].peBlue = ms_StdColors[i].peBlue;
pi.palPalEntry[i].peFlags = 0;
}
for(i=8; i<16; i++)
{
pi.palPalEntry[i].peRed = ms_StdColors[248 + i].peRed;
pi.palPalEntry[i].peGreen = ms_StdColors[248 + i].peGreen;
pi.palPalEntry[i].peBlue = ms_StdColors[248 + i].peBlue;
pi.palPalEntry[i].peFlags = 0;
}
}
else // if(iNumColors == 256)
{
// Fill palette with full halftone palette
for(int i=0; i<256; i++)
{
pi.palPalEntry[i].peRed = ms_StdColors[i].peRed;
pi.palPalEntry[i].peGreen = ms_StdColors[i].peGreen;
pi.palPalEntry[i].peBlue = ms_StdColors[i].peBlue;
pi.palPalEntry[i].peFlags = 0;
}
}
return CreatePalette(&pi);
#endif // USE_HALFTONE_1
}
#endif // DIBSECTION_NO_PALETTE
/////////////////////////////////////////////////////////////////////////////
// CDIBSection
CDIBSection::CDIBSection()
{
#ifdef USE_HALFTONE_1
// Just in case...
ASSERT(sizeof(ms_StdColors) / sizeof(ms_StdColors[0]) == 256);
#endif // USE_HALFTONE_1
m_hBitmap = NULL;
#ifndef DIBSECTION_NO_PALETTE
m_hPalette = NULL;
#endif // DIBSECTION_NO_PALETTE
#ifdef _WIN32_WCE
m_hdcMem = NULL;
m_hbmpOld = NULL;
#ifndef DIBSECTION_NO_MEMDC_REUSE
m_bReuseMemoryDC = FALSE;
#endif // DIBSECTION_NO_MEMDC_REUSE
#ifndef DIBSECTION_NO_PALETTE
m_hpalOld = NULL;
#endif // DIBSECTION_NO_PALETTE
#endif // _WIN32_WCE
CleanUp(); // This will initialise to a known state - ie. empty
}
CDIBSection::~CDIBSection()
{
CleanUp();
}
// Resets the object to an empty state, and frees all memory used.
void CDIBSection::CleanUp()
{
#ifndef DIBSECTION_NO_PALETTE
if(m_hPalette != NULL)
{
DeleteObject(m_hPalette);
m_hPalette = NULL;
}
#endif // DIBSECTION_NO_PALETTE
if(m_hBitmap != NULL)
{
DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
m_ppvBits = NULL;
ZeroMemory(&m_DIBinfo, sizeof(m_DIBinfo));
m_uColorDataType = DIB_RGB_COLORS;
m_uColorTableSize = 0;
}
/////////////////////////////////////////////////////////////////////////////
// CDIBSection operations
// Draws the image 1:1 on the device context
BOOL CDIBSection::Draw(HDC hdc, const POINT& ptDest, BOOL bForceBackground)
{
if(m_hBitmap == NULL)
return FALSE;
SIZE size;
GetSize(size);
POINT ptSrcOrigin = { 0, 0 };
BOOL bResult = FALSE;
#ifdef _WIN32_WCE
// Create a memory DC compatible with the destination DC
HDC hdcMem = GetMemoryDC(hdc, FALSE);
if(!hdcMem)
return FALSE;
#endif // _WIN32_WCE
#ifndef DIBSECTION_NO_PALETTE
HPALETTE hpalOld = NULL;
if(m_hPalette != NULL && IsPaletteEnabled(hdc))
{
hpalOld = SelectPalette(hdc, m_hPalette, bForceBackground);
RealizePalette(hdc);
}
#endif // DIBSECTION_NO_PALETTE
#ifdef _WIN32_WCE
bResult = BitBlt(hdc, ptDest.x, ptDest.y, size.cx, size.cy, hdcMem,
ptSrcOrigin.x, ptSrcOrigin.y, SRCCOPY);
#else
bResult = SetDIBitsToDevice(hdc,
ptDest.x, ptDest.y,
size.cx, size.cy,
ptSrcOrigin.x, ptSrcOrigin.y,
ptSrcOrigin.y, size.cy - ptSrcOrigin.y,
GetDIBits(), GetBitmapInfo(),
DIB_RGB_COLORS);
#endif // _WIN32_WCE
#ifndef DIBSECTION_NO_PALETTE
if(hpalOld != NULL)
SelectPalette(hdc, hpalOld, FALSE);
#endif // DIBSECTION_NO_PALETTE
#ifdef _WIN32_WCE
ReleaseMemoryDC();
#endif // _WIN32_WCE
return bResult;
}
// Stretch draws the image to the desired size on the device context
BOOL CDIBSection::Stretch(HDC hdc, const POINT& ptDest, const SIZE& size, BOOL bForceBackground)
{
if(m_hBitmap == NULL)
return FALSE;
SIZE size2;
GetSize(size2);
POINT ptSrcOrigin = { 0, 0 };
BOOL bResult = FALSE;
#ifdef _WIN32_WCE
// Create a memory DC compatible with the destination DC
HDC hdcMem = GetMemoryDC(hdc, FALSE);
if(!hdcMem)
return FALSE;
#endif // _WIN32_WCE
#ifndef DIBSECTION_NO_PALETTE
HPALETTE hpalOld = NULL;
if(m_hPalette != NULL && IsPaletteEnabled(hdc))
{
hpalOld = SelectPalette(hdc, m_hPalette, bForceBackground);
RealizePalette(hdc);
}
#endif // DIBSECTION_NO_PALETTE
#ifdef _WIN32_WCE
bResult = StretchBlt(hdc, ptDest.x, ptDest.y, size.cx, size.cy,
hdcMem,
ptSrcOrigin.x, ptSrcOrigin.y, size2.cx, size2.cy,
SRCCOPY);
#else // _WIN32_WCE
SetStretchBltMode(hdc, COLORONCOLOR);
bResult = StretchDIBits(hdc,
ptDest.x, ptDest.y,
size.cx, size.cy,
ptSrcOrigin.x, ptSrcOrigin.y,
size2.cx, size2.cy,
GetDIBits(), GetBitmapInfo(),
DIB_RGB_COLORS, SRCCOPY);
#endif // _WIN32_WCE
#ifndef DIBSECTION_NO_PALETTE
if(hpalOld != NULL)
SelectPalette(hdc, hpalOld, FALSE);
#endif // DIBSECTION_NO_PALETTE
#ifdef _WIN32_WCE
ReleaseMemoryDC();
#endif // _WIN32_WCE
return bResult;
}
//////////////////////////////////////////////////////////////////////////////
// Create an empty bitmap
BOOL CDIBSection::CreateBitmap(int cx, int cy, int iBits)
{
ASSERT(cx > 0);
ASSERT(cy > 0);
#ifdef _WIN32_WCE
ASSERT((iBits == 1)
|| (iBits == 2)
|| (iBits == 4) || (iBits == 8)
|| (iBits == 16) || (iBits == 24) || (iBits == 32));
#else
ASSERT((iBits == 1)
|| (iBits == 4) || (iBits == 8)
|| (iBits == 16) || (iBits == 24) || (iBits == 32));
#endif // _WIN32_WCE
CleanUp();
// Initialize the bitmap info header
ZeroMemory(&m_DIBinfo, sizeof(m_DIBinfo));
BITMAPINFOHEADER& bmih = *(PBITMAPINFOHEADER)m_DIBinfo;
// Populate bitmapinfo header
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = cx; // ((((int)cx * 8) + 31) & ~31) >> 3;
bmih.biHeight = cy;
bmih.biPlanes = 1;
bmih.biBitCount = (WORD)iBits;
bmih.biCompression = BI_RGB;
bmih.biClrUsed = (iBits > 8) ? 0 : (1 << iBits);
bmih.biSizeImage = BytesPerLine(cx, iBits) * cy;
m_uColorTableSize = bmih.biClrUsed;
/// TODO: fill color table here
// Create the DIB section.
m_hBitmap = CreateDIBSection(NULL, (PBITMAPINFO)&bmih, m_uColorDataType, (void**)&m_ppvBits, NULL, 0);
ASSERT(m_hBitmap);
ASSERT(m_ppvBits);
return m_hBitmap != NULL;
}
//////////////////////////////////////////////////////////////////////////////
// Setting the bitmap
BOOL CDIBSection::SetBitmap(UINT uResId, HINSTANCE hInstance)
{
return SetBitmap(MAKEINTRESOURCE(uResId), hInstance);
}
BOOL CDIBSection::SetBitmap(LPCTSTR pszResName, HINSTANCE hInstance)
{
if(hInstance == NULL)
hInstance = GetModuleHandle(NULL);
HBITMAP hBitmap = (HBITMAP)LoadImage(hInstance, pszResName, IMAGE_BITMAP, 0, 0,
#ifdef _WIN32_WCE
0
#else // _WIN32_WCE
LR_CREATEDIBSECTION
#endif // _WIN32_WCE
);
if(hBitmap == NULL)
return FALSE;
BOOL bResult = SetBitmap(hBitmap);
DeleteObject(hBitmap);
return bResult;
}
BOOL CDIBSection::SetBitmap(PBITMAPINFO pbi, PVOID pBits)
{
CleanUp();
if(pbi == NULL/* || pBits == NULL*/)
return FALSE;
BOOL bResult = FALSE;
// Compute the number of colors in the color table
m_uColorTableSize = NumColorEntries(pbi->bmiHeader.biBitCount, pbi->bmiHeader.biCompression,
pbi->bmiHeader.biClrUsed);
DWORD dwSize = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * m_uColorTableSize;
// Copy over BITMAPINFO contents
CopyMemory(&m_DIBinfo, pbi, dwSize);
// Should now have all the info we need to create the sucker.
m_hBitmap = CreateDIBSection(NULL, (const PBITMAPINFO)m_DIBinfo, m_uColorDataType, (void**)&m_ppvBits, NULL, 0);
if(m_hBitmap != NULL)
{
DWORD& dwImageSize = m_DIBinfo.bmiHeader.biSizeImage;
if(dwImageSize == 0)
{
int nBytesPerLine = BytesPerLine(pbi->bmiHeader.biWidth, pbi->bmiHeader.biBitCount);
dwImageSize = nBytesPerLine * pbi->bmiHeader.biHeight;
}
#ifndef _WIN32_WCE
// Flush the GDI batch queue
GdiFlush();
#endif // !_WIN32_WCE
// Only copy bits if they were provided
if(pBits != NULL)
CopyMemory(m_ppvBits, pBits, dwImageSize);
#ifndef DIBSECTION_NO_PALETTE
if(CreateSparePalette())
#endif // DIBSECTION_NO_PALETTE
bResult = TRUE;
}
if(!bResult)
{
_ShowLastError();
CleanUp();
}
return bResult;
}
// Initialises the bitmap from the HBITMAP supplied. If failure, then object is
// initialised back to an empty bitmap.
BOOL CDIBSection::SetBitmap(HBITMAP hBitmap
#ifndef DIBSECTION_NO_PALETTE
, HPALETTE hPalette
#endif // DIBSECTION_NO_PALETTE
)
{
CleanUp();
if(hBitmap == NULL)
return FALSE;
// Get dimensions of bitmap
BITMAP bm;
if(!GetObject(hBitmap, sizeof(bm), &bm))
return FALSE;
BOOL bResult = FALSE;
#ifndef DIBSECTION_NO_PALETTE
HPALETTE hpalOld = NULL;
#endif // DIBSECTION_NO_PALETTE
HDC hdcMem = NULL;
HDC hdcCopy = NULL;
BITMAPINFOHEADER& bih = m_DIBinfo.bmiHeader;
if(bm.bmHeight < 0)
bm.bmHeight = -bm.bmHeight;
HDC hdc = GetWindowDC(NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -