?? dib.cpp
字號:
{
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;
}
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;
}
BOOL CDib::UpdateInternal()
{
BuildPalette();
return BuildBitmap();
}
CPalette* CDib::GetPalette()
{
return m_pPalette;
}
CBitmap* CDib::GetBitmap()
{
return m_pBitmap;
}
BOOL CDib::IsEmpty()
{
if (m_hDib == NULL)
return TRUE;
if (! GlobalLock(m_hDib))
return TRUE;
GlobalUnlock(m_hDib);
return FALSE;
}
DWORD CDib::GetCompression()
{
LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
if (!lpBI)
{
GlobalUnlock(m_hDib);
return 0;
}
DWORD dwCompression = lpBI->biCompression;
GlobalUnlock(m_hDib);
return dwCompression;
}
WORD CDib::GetBitCount()
{
LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
if (!lpBI)
{
GlobalUnlock(m_hDib);
return 0;
}
WORD wBitCount = lpBI->biBitCount;
GlobalUnlock(m_hDib);
return wBitCount;
}
LONG CDib::GetWidth()
{
// get DIB buffer pointer
LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
if (! lpDIB)
{
GlobalUnlock(m_hDib);
return 0;
}
LONG lWidth = (LONG)DIBWidth(lpDIB);
GlobalUnlock(m_hDib);
return lWidth;
}
LONG CDib::GetHeight()
{
// get DIB buffer pointer
LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
if (! lpDIB)
{
GlobalUnlock(m_hDib);
return 0;
}
LONG lHeight = (LONG)DIBHeight(lpDIB);
GlobalUnlock(m_hDib);
return lHeight;
}
LONG CDib::GetWidthBytes()
{
return WIDTHBYTES((GetWidth())*((DWORD)GetBitCount()));
}
COLORREF CDib::GetPixel(LONG x, LONG y)
{
COLORREF cColor;
switch (GetBitCount())
{
case 1 : if (1<<(7-x%8) &
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)))
cColor = RGB(255,255,255);
else
cColor = RGB(0,0,0);
break;
case 4 :
{
PALETTEENTRY PaletteColors[16];
m_pPalette->GetPaletteEntries(0, 16, PaletteColors);
int nIndex = (*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)) &
(x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
cColor = RGB(PaletteColors[nIndex].peRed,
PaletteColors[nIndex].peGreen,
PaletteColors[nIndex].peBlue);
}
break;
case 8 :
{
PALETTEENTRY PaletteColors[256];
m_pPalette->GetPaletteEntries(0, 256, PaletteColors);
int nIndex = *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y));
cColor = RGB(PaletteColors[nIndex].peRed,
PaletteColors[nIndex].peGreen,
PaletteColors[nIndex].peBlue);
}
break;
default: cColor = RGB(*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)),
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+1),
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+2));
break;
}
return cColor;
}
LONG CDib::GetPixelOffset(LONG x, LONG y)
{
return (GetHeight()-y-1)*GetWidthBytes()+x/(8/GetBitCount());
}
LPBYTE CDib::GetBitsPtr()
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
if (! lpDIB)
{
GlobalUnlock(m_hDib);
return NULL;
}
LPBYTE lpData = FindDIBBits(lpDIB);
GlobalUnlock(m_hDib);
return lpData;
}
HANDLE CDib::GetHandle()
{
return m_hDib;
}
WORD CDib::GetColorNumber()
{
LPBYTE lpBI = (LPBYTE)GlobalLock(m_hDib);
if (! lpBI)
{
GlobalUnlock(m_hDib);
return 0;
}
WORD wColors = DIBNumColors(lpBI);
GlobalUnlock(m_hDib);
return wColors;
}
WORD CDib::GetPaletteSize()
{
LPBYTE lpBI = (LPBYTE)GlobalLock(m_hDib);
if (! lpBI)
{
GlobalUnlock(m_hDib);
return 0;
}
WORD wPalSize = PaletteSize(lpBI);
GlobalUnlock(m_hDib);
return wPalSize;
}
CDC* CDib::BeginPaint(CDC *pDC)
{
m_pMemDC = new CDC;
m_pMemDC->CreateCompatibleDC(pDC);
m_pPaletteTmp = m_pMemDC->SelectPalette(m_pPalette, TRUE);
m_pMemDC->RealizePalette();
m_pBitmapTmp = (CBitmap *)m_pMemDC->SelectObject(m_pBitmap);
return m_pMemDC;
}
void CDib::EndPaint()
{
m_pMemDC->SelectObject(m_pBitmapTmp);
m_pMemDC->SelectPalette(m_pPaletteTmp, TRUE);
delete m_pMemDC;
Create(m_hBitmap);
}
BOOL CDib::DisplayPalette(CDC* pDC, CRect rc)
{
return ::DisplayPalette(pDC->GetSafeHdc(), &rc, (HPALETTE)m_pPalette->GetSafeHandle());
}
BOOL CDib::DisplayTransparent(CDC * pDC, int x, int y, COLORREF cTransparentColor)
{
CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
pDC->RealizePalette();
DrawTransparentBitmap(pDC->GetSafeHdc(),
m_hBitmap,
x,
y,
cTransparentColor);
pDC->SelectPalette(pOldPal, TRUE);
return TRUE;
}
#define UPVALUE(x, n) ((x)/((n) ? (n) : 1) + ((x)%((n) ? (n) : 1) ? 1 : 0))
BOOL CDib::DisplayFadeIn(CDC* pDC, int x, int y, int nDeta, DWORD dwDelayTime)
{
// backup DIB
HDIB hDib = CopyHandle(m_hDib);
// get color number
WORD wNumColors = GetColorNumber();
BITMAPINFO *bmi = (BITMAPINFO *)GlobalLock(m_hDib);
BITMAPINFO *bmi0 = (BITMAPINFO *)GlobalLock(hDib);
if (! bmi)
return FALSE;
BOOL bDone = FALSE;
int nDetaR, nDetaG, nDetaB;
// fade out
if (wNumColors) // There is palette
{
// build black image
for (WORD i=0; i<wNumColors; ++i)
{
bmi->bmiColors[i].rgbRed = 0 ;
bmi->bmiColors[i].rgbGreen = 0 ;
bmi->bmiColors[i].rgbBlue = 0 ;
}
UpdateInternal();
// display black first
Display(pDC, x, y, SRCCOPY);
while (! bDone)
{
bDone = TRUE;
for (WORD i=0; i<wNumColors; i++)
{
nDetaR = UPVALUE(bmi0->bmiColors[i].rgbRed-bmi->bmiColors[i].rgbRed, nDeta);
nDetaG = UPVALUE(bmi0->bmiColors[i].rgbGreen-bmi->bmiColors[i].rgbGreen, nDeta);
nDetaB = UPVALUE(bmi0->bmiColors[i].rgbBlue-bmi->bmiColors[i].rgbBlue, nDeta);
if (! Fade(nDetaR, nDetaG, nDetaB,
bmi0->bmiColors[i].rgbRed,
bmi0->bmiColors[i].rgbGreen,
bmi0->bmiColors[i].rgbBlue,
&(bmi->bmiColors[i].rgbRed),
&(bmi->bmiColors[i].rgbGreen),
&(bmi->bmiColors[i].rgbBlue)))
bDone = FALSE;
}
UpdateInternal();
Display(pDC, x, y, SRCCOPY);
Delay(dwDelayTime);
nDeta--;
}
}
else // No palette
{
// should increase the speed!
dwDelayTime /= 10;
// bits position
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)bmi;
LPBYTE lpBits = (LPBYTE)lpbi + lpbi->biSize;
LPBYTE lpBits0 = (LPBYTE)bmi0 + lpbi->biSize;
int nDelta = WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth) - lpbi->biWidth*lpbi->biBitCount/8;
int nx, ny;
// build black image
for (ny=0; ny<lpbi->biHeight; ny++)
{
for (nx=0; nx<lpbi->biWidth; nx++)
{
*lpBits++ = 0;
*lpBits++ = 0;
*lpBits++ = 0;
}
lpBits += nDelta;
}
lpBits = (LPBYTE)lpbi + lpbi->biSize;
UpdateInternal();
// display black first
Display(pDC, x, y, SRCCOPY);
BYTE r, g, b, r0, g0, b0;
while (! bDone)
{
bDone = TRUE;
for (ny=0; ny<lpbi->biHeight; ny++)
{
for (nx=0; nx<lpbi->biWidth; nx++)
{
b0 = (BYTE)*lpBits0++;
g0 = (BYTE)*lpBits0++;
r0 = (BYTE)*lpBits0++;
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
nDetaR = UPVALUE(r0-r, nDeta);
nDetaG = UPVALUE(g0-g, nDeta);
nDetaB = UPVALUE(b0-b, nDeta);
if (! Fade(nDetaR, nDetaG, nDetaB, r0, g0, b0, &r, &g, &b))
bDone = FALSE;
*lpBits++ = b;
*lpBits++ = g;
*lpBits++ = r;
}
lpBits += nDelta;
lpBits0 += nDelta;
}
lpBits = (LPBYTE)lpbi + lpbi->biSize;
lpBits0 = (LPBYTE)bmi0 + lpbi->biSize;
UpdateInternal();
Display(pDC, x, y, SRCCOPY);
Delay(dwDelayTime);
nDeta--;
}
}
// cleanup
GlobalUnlock(m_hDib);
GlobalUnlock(hDib);
// restore DIB
m_hDib = CopyHandle(hDib);
GlobalFree(hDib);
return TRUE;
}
BOOL CDib::DisplayFadeOut(CDC* pDC, int x, int y, int nDeta, DWORD dwDelayTime)
{
// display first
Display(pDC, x, y, SRCCOPY);
// backup DIB
HDIB hDib = CopyHandle(m_hDib);
// get color number
WORD wNumColors = GetColorNumber();
BITMAPINFO *bmi = (BITMAPINFO *)GlobalLock(m_hDib);
if (! bmi)
return FALSE;
BOOL bDone = FALSE;
int nDetaR, nDetaG, nDetaB;
// fade out
if (wNumColors) // There is palette
{
while (! bDone)
{
bDone = TRUE;
for (WORD i=0; i<wNumColors; i++)
{
nDetaR = -1*UPVALUE(bmi->bmiColors[i].rgbRed, nDeta);
nDetaG = -1*UPVALUE(bmi->bmiColors[i].rgbGreen, nDeta);
nDetaB = -1*UPVALUE(bmi->bmiColors[i].rgbBlue, nDeta);
if (! Fade(nDetaR, nDetaG, nDetaB,
0, 0, 0,
&(bmi->bmiColors[i].rgbRed),
&(bmi->bmiColors[i].rgbGreen),
&(bmi->bmiColors[i].rgbBlue)))
bDone = FALSE;
}
UpdateInternal();
Display(pDC, x, y, SRCCOPY);
Delay(dwDelayTime);
nDeta--;
}
}
else // No palette
{
// should increase the speed!
dwDelayTime /= 10;
// bits position
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)bmi;
LPBYTE lpBits = (LPBYTE)lpbi + lpbi->biSize;
int nDelta = WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth) - lpbi->biWidth*lpbi->biBitCount/8;
BYTE r, g, b;
int nx, ny;
while (! bDone)
{
bDone = TRUE;
for (ny=0; ny<lpbi->biHeight; ny++)
{
for (nx=0; nx<lpbi->biWidth; nx++)
{
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
nDetaR = -1*UPVALUE(r, nDeta);
nDetaG = -1*UPVALUE(g, nDeta);
nDetaB = -1*UPVALUE(b, nDeta);
if (! Fade(nDetaR, nDetaG, nDetaB, 0, 0, 0, &r, &g, &b))
bDone = FALSE;
*lpBits++ = b;
*lpBits++ = g;
*lpBits++ = r;
}
lpBits += nDelta;
}
lpBits = (LPBYTE)lpbi + lpbi->biSize;
UpdateInternal();
Display(pDC, x, y, SRCCOPY);
Delay(dwDelayTime);
nDeta--;
}
}
// cleanup
GlobalUnlock(m_hDib);
// restore DIB
m_hDib = CopyHandle(hDib);
GlobalFree(hDib);
return TRUE;
}
BOOL CDib::DisplayMosaicIn(CDC *pDC, int xx, int yy, int nTileSize, DWORD dwDelayTime, DWORD dwRop)
{
// count the number of dwTileNum
DWORD dwTileNum=(GetWidth()/nTileSize + ((GetWidth() % nTileSize) ? 1:0))*
(GetHeight()/nTileSize + ((GetHeight() % nTileSize) ? 1:0));
// allocate tile array
POINT *point = new POINT[dwTileNum];
if (point == NULL)
return FALSE;
// initialize the tile array
LONG x=0, y=0;
for (DWORD i=0;i<dwTileNum;++i)
{
point[i].x=x;
point[i].y=y;
x+=nTileSize;
if (x >= GetWidth())
{
x=0;
y+=nTileSize;
}
}
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
pDC->RealizePalette();
double fMax = RAND_MAX;
BOOL bDone = FALSE;
while (! bDone)
{
DWORD n = (DWORD)((double)dwTileNum*(double)((double)rand()/fMax));
x = point[n].x;
y = point[n].y;
pDC->BitBlt(xx+x,
yy+y,
nTileSize,
nTileSize,
&MemDC,
x,
y,
dwRop);
dwTileNum--;
bDone = !dwTileNum;
point[n].x = point[dwTileNum].x;
point[n].y = point[dwTileNum].y;
Delay(dwDelayTime);
}
MemDC.SelectObject(pOldBmp);
pDC->SelectPalette(pOldPal, TRUE);
delete[] point;
return TRUE;
}
BOOL CDib::DisplayMosaicOut(CDC *pDC, int xx, int yy, int nTileSize, DWORD dwDelayTime)
{
// display dib first
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
pDC->RealizePalette();
pDC->BitBlt(xx, yy,
GetWidth(), GetHeight(),
&MemDC,
0, 0,
SRCCOPY);
// count the number of dwTileNum
DWORD dwTileNum=(GetWidth()/nTileSize + ((GetWidth() % nTileSize) ? 1:0))*
(GetHeight()/nTileSize + ((GetHeight() % nTileSize) ? 1:0));
// allocate tile array
POINT *point = new POINT[dwTileNum];
if (point == NULL)
return FALSE;
// initialize the tile array
LONG x=0, y=0;
for (DWORD i=0;i<dwTileNum;++i)
{
point[i].x=x;
point[i].y=y;
x+=nTileSize;
if (x >= GetWidth())
{
x=0;
y+=nTileSize;
}
}
CBrush brush(GetSysColor(COLOR_WINDOW));
CBrush* oldbrush = pDC->SelectObject(&brush);
CPen pen(PS_SOLID,1,GetSysColor(COLOR_WINDOW));
CPen* oldpen = pDC->SelectObject(&pen);
double fMax = RAND_MAX;
BOOL bDone = FALSE;
while (! bDone)
{
DWORD n = (DWORD)((double)dwTileNum*(double)((double)rand()/fMax));
x = point[n].x;
y = point[n].y;
pDC->Rectangle( xx+x,
yy+y,
xx+x+nTileSize+1,
yy+y+nTileSize+1);
dwTileNum--;
bDone = !dwTileNum;
point[n].x = point[dwTileNum].x;
point[n].y = point[dwTileNum].y;
Delay(dwDelayTime);
}
MemDC.SelectObject(pOldBmp);
pDC->SelectPalette(pOldPal, TRUE);
pDC->SelectObject(oldbrush);
pDC->SelectObject(oldpen);
delete[] point;
return TRUE;
}
BOOL CDib::Display(int nEffect, CDC* pDC, int x, int y, int nDeta, DWORD dwDelayTime, DWORD dwRop)
{
if (nEffect == EFFECT_FADE)
return DisplayFadeIn(pDC, x, y, nDeta, dwDelayTime);
else if (nEffect == EFFECT_MOSAIC)
return DisplayMosaicIn(pDC, x, y, nDeta, dwDelayTime, dwRop);
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);
CPalette* pOldPal = pDC->SelectPalette(m_pPalette, TRUE);
pDC->RealizePalette();
LONG i = 0;
BOOL bDone = FALSE;
while (! bDone)
{
switch (nEffect)
{
case EFFECT_SCANDOWN:
if (i > GetHeight())
{
i = GetHeight();
bDone = TRUE;
}
pDC->BitBlt(x,
y+i,
GetWidth(),
nDeta,
&MemDC,
0,
i,
dwRop);
i += nDeta;
break;
case EFFECT_SCANUP:
if (i > GetHeight())
{
i = GetHeight();
bDone = TRUE;
}
pDC->BitBlt(x,
y+GetHeight()-i,
GetWidth(),
nDeta,
&MemDC,
0,
GetHeight()-i,
dwRop);
i += nDeta;
break;
case EFFECT_SCANRIGHT:
if (i > GetWidth())
{
i = GetWidth();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -