📄 zgtools.cpp
字号:
// ((DWORD)(pClr[2] & 0xf8) << 7);
}
const DWORD RGNDATAHEADER_SIZE = sizeof(RGNDATAHEADER);
const DWORD ADD_RECTS_COUNT = 40; // number of rects to be appended
// to region data buffer
// BitPerPixel
BYTE Bpp = bih.biBitCount >> 3; // bytes per pixel
// bytes per line in pBits is DWORD aligned and bmp.bmWidthBytes is WORD aligned
// so, both of them not
DWORD m_dwAlignedWidthBytes = (bmp.bmWidthBytes & ~0x3) + (!!(bmp.bmWidthBytes & 0x3) << 2);
// DIB image is flipped that's why we scan it from the last line
LPBYTE pColor = pBits + (bih.biHeight - 1) * m_dwAlignedWidthBytes;
DWORD dwLineBackLen = m_dwAlignedWidthBytes + bih.biWidth * Bpp; // offset of previous scan line
// (after processing of current)
DWORD dwRectsCount = bih.biHeight; // number of rects in allocated buffer
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when mask has been found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
// region data here is set of regions that are rectangles with height 1 pixel (scan line)
// that's why first allocation is <bm.biHeight> RECTs - number of scan lines in image
RGNDATAHEADER* pRgnData =
(RGNDATAHEADER*)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
// get pointer to RECT table
LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
// zero region data header memory (header part only)
memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RGNDATAHEADER_SIZE;
pRgnData->iType = RDH_RECTANGLES;
for ( i = 0; i < bih.biHeight; i++ )
{
for ( j = 0; j < bih.biWidth; j++ )
{
// get color
switch ( bih.biBitCount )
{
case 8:
ismask = (clr_tbl[ *pColor ] != color);
break;
case 16:
ismask = (*(LPWORD)pColor != (WORD)color);
break;
case 24:
ismask = ((*(LPDWORD)pColor & 0x00ffffff) != color);
break;
case 32:
ismask = (*(LPDWORD)pColor != color);
}
// shift pointer to next color
pColor += Bpp;
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if ( wasfirst )
{
if ( !ismask )
{
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, i, j, i + 1 );
// if buffer full reallocate it with more room
if ( pRgnData->nCount >= dwRectsCount )
{
dwRectsCount += ADD_RECTS_COUNT;
// allocate new buffer
LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
// copy current region data to it
memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
// delte old region data buffer
delete pRgnData;
// set pointer to new regiondata buffer to current
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
// correct pointer to RECT table
pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
}
wasfirst = false;
}
}
else if ( ismask ) // set wasfirst when mask is found
{
first = j;
wasfirst = true;
}
}
if ( wasfirst && ismask )
{
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, i, j, i + 1 );
// if buffer full reallocate it with more room
if ( pRgnData->nCount >= dwRectsCount )
{
dwRectsCount += ADD_RECTS_COUNT;
// allocate new buffer
LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
// copy current region data to it
memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
// delte old region data buffer
delete pRgnData;
// set pointer to new regiondata buffer to current
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
// correct pointer to RECT table
pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
}
wasfirst = false;
}
pColor -= dwLineBackLen;
}
// release image data
delete pBits;
delete bi;
// create region
HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
// release region data
delete pRgnData;
return hRgn;
}
BOOL CZgBitmap::Draw( CDC *pDC, int x, int y, LPRECT sr )
{
if (!GetSafeHandle())
return FALSE;
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
if ( sr != NULL)
pDC->BitBlt( x, y, sr->right - sr->left, sr->bottom - sr->top, &dc,
sr->left, sr->top, SRCCOPY );
else
pDC->BitBlt( x, y, Width(), Height(), &dc,
0, 0, SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
BOOL CZgBitmap::Draw(CDC *pDC, LPRECT r)
{
if (!GetSafeHandle())
return FALSE;
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
pDC->BitBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, 0, 0 ,
SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
BOOL CZgBitmap::Draw( CDC *pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans )
{
if (!GetSafeHandle())
return FALSE;
if ( !bTrans )
Draw( pDC ,x, y, sr );
else
{
ZgTransparentBlt(pDC->GetSafeHdc(), x, y, sr->right - sr->left, sr->bottom - sr->top,
(HBITMAP)this->GetSafeHandle(), sr->left, sr->top, colTrans, NULL );
}
return TRUE;
}
BOOL CZgBitmap::DrawTransparent(CDC * pDC, int x, int y, COLORREF crColour)
{
if (!GetSafeHandle())
return FALSE;
ZgTransparentBlt(pDC->GetSafeHdc(), x, y, GetWidth(), GetHeight(), (HBITMAP)this->GetSafeHandle(), 0, 0, crColour, NULL );
return TRUE;
}
void CZgBitmap::ZgTransparentBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth,
int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc,
COLORREF colorTransparent, HPALETTE hPal )
{
CDC dc, memDC, maskDC, tempDC;
dc.Attach( hdcDest );
maskDC.CreateCompatibleDC(&dc);
CBitmap maskBitmap;
//add these to store return of SelectObject() calls
CBitmap* pOldMemBmp = NULL;
CBitmap* pOldMaskBmp = NULL;
HBITMAP hOldTempBmp = NULL;
memDC.CreateCompatibleDC(&dc);
tempDC.CreateCompatibleDC(&dc);
CBitmap bmpImage;
bmpImage.CreateCompatibleBitmap( &dc, nWidth, nHeight );
pOldMemBmp = memDC.SelectObject( &bmpImage );
// Select and realize the palette
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && hPal )
{
::SelectPalette( dc, hPal, FALSE );
dc.RealizePalette();
::SelectPalette( memDC, hPal, FALSE );
}
hOldTempBmp = (HBITMAP) ::SelectObject( tempDC.m_hDC, hBitmap );
memDC.BitBlt( 0,0,nWidth, nHeight, &tempDC, nXSrc, nYSrc, SRCCOPY );
// Create monochrome bitmap for the mask
maskBitmap.CreateBitmap( nWidth, nHeight, 1, 1, NULL );
pOldMaskBmp = maskDC.SelectObject( &maskBitmap );
memDC.SetBkColor( colorTransparent );
// Create the mask from the memory DC
maskDC.BitBlt( 0, 0, nWidth, nHeight, &memDC,
0, 0, SRCCOPY );
// Set the background in memDC to black. Using SRCPAINT with black
// and any other color results in the other color, thus making
// black the transparent color
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(0, 0, nWidth, nHeight, &maskDC, 0, 0, SRCAND);
// Set the foreground to black. See comment above.
dc.SetBkColor(RGB(255,255,255));
dc.SetTextColor(RGB(0,0,0));
dc.BitBlt(nXDest, nYDest, nWidth, nHeight, &maskDC, 0, 0, SRCAND);
// Combine the foreground with the background
dc.BitBlt(nXDest, nYDest, nWidth, nHeight, &memDC,
0, 0, SRCPAINT);
if (hOldTempBmp)
::SelectObject( tempDC.m_hDC, hOldTempBmp);
if (pOldMaskBmp)
maskDC.SelectObject( pOldMaskBmp );
if (pOldMemBmp)
memDC.SelectObject( pOldMemBmp );
dc.Detach();
}
BOOL CZgBitmap::StretchDraw(CDC *pDC, LPRECT r, LPRECT sr )
{
if (!GetSafeHandle())
return FALSE;
if ( !r ) return FALSE;
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
pDC->SetStretchBltMode(COLORONCOLOR);
if ( !sr )
pDC->StretchBlt( r->left, r->top, r->right, r->bottom, &dc, 0, 0, GetWidth(), GetHeight() ,
SRCCOPY );
else
pDC->StretchBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, sr->left, sr->top,
sr->right - sr->left, sr->bottom - sr->top,
SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
BOOL CZgBitmap::StretchDraw(CDC *pDC, LPRECT r)
{
if (!GetSafeHandle())
return FALSE;
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
pDC->StretchBlt( r->left, r->top, r->right, r->bottom, &dc, 0, 0, GetWidth(), GetHeight() ,
SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
CZgPenDC::CZgPenDC (CDC *pDC, COLORREF crColor) : m_hDC (pDC->m_hDC)
{
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
///////////////////////////////////////////////////////////////////////////////
CZgPenDC::~CZgPenDC ()
{
::SelectObject (m_hDC, m_hOldPen);
}
///////////////////////////////////////////////////////////////////////////////
void CZgPenDC::Color (COLORREF crColor)
{
::SelectObject (m_hDC, m_hOldPen);
VERIFY(m_pen.DeleteObject());
VERIFY(m_pen.CreatePen (PS_SOLID, 1, crColor));
m_hOldPen = (HPEN)::SelectObject (m_hDC, m_pen);
}
///////////////////////////////////////////////////////////////////////////////
COLORREF CZgPenDC::Color () const
{
LOGPEN logPen;
((CZgPenDC*)this)->m_pen.GetLogPen (&logPen);
return logPen.lopnColor;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
CZgBrushDC::CZgBrushDC (CDC *pDC, COLORREF crColor) : m_hDC (pDC->m_hDC)
{
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
///////////////////////////////////////////////////////////////////////////////
CZgBrushDC::~CZgBrushDC ()
{
::SelectObject (m_hDC, m_hOldBrush);
}
///////////////////////////////////////////////////////////////////////////////
void CZgBrushDC::Color (COLORREF crColor)
{
::SelectObject (m_hDC, m_hOldBrush);
VERIFY(m_brush.DeleteObject());
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
else VERIFY(m_brush.CreateSolidBrush (crColor));
m_hOldBrush = (HBRUSH)::SelectObject (m_hDC, m_brush);
}
///////////////////////////////////////////////////////////////////////////////
COLORREF CZgBrushDC::Color () const
{
LOGBRUSH logBrush;
((CZgBrushDC*)this)->m_brush.GetLogBrush (&logBrush);
return logBrush.lbColor;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CZgFontDC::CZgFontDC (CDC *pDC, LPCTSTR sFaceName, COLORREF crText)
: m_hDC (pDC->m_hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
*this = sFaceName;
if ( crText != CLR_DEFAULT )
{
*this = crText;
}
}
/////////////////////////////////////////////////////////////////////////////
CZgFontDC::CZgFontDC (CDC *pDC, BYTE nStockFont, COLORREF crText)
: m_hDC (pDC->m_hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
*this = nStockFont;
if ( crText != CLR_DEFAULT )
{
*this = crText;
}
}
/////////////////////////////////////////////////////////////////////////////
CZgFontDC::CZgFontDC (CDC *pDC, HFONT hFont, COLORREF crText)
: m_hDC (pDC->m_hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
*this = hFont;
if ( crText != CLR_DEFAULT )
{
*this = crText;
}
}
/////////////////////////////////////////////////////////////////////////////
CZgFontDC::~CZgFontDC ()
{
if ( m_hDefFont != NULL )
{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
if ( m_crTextOld != CLR_NONE )
{
::SetTextColor (m_hDC, m_crTextOld);
}
}
/////////////////////////////////////////////////////////////////////////////
const CZgFontDC& CZgFontDC::operator = (LPCTSTR sFaceName)
{
LOGFONT lf;
::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), &lf);
if ( _tcsicmp (sFaceName, lf.lfFaceName) )
{
if ( m_hDefFont != NULL )
{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
_tcscpy (lf.lfFaceName, sFaceName);
m_hFont = ::CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
}
return *this;
}
/////////////////////////////////////////////////////////////////////////////
const CZgFontDC& CZgFontDC::operator = (BYTE nStockFont)
{
if ( m_hDefFont != NULL )
{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = (HFONT)::GetStockObject (nStockFont);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/////////////////////////////////////////////////////////////////////////////
const CZgFontDC& CZgFontDC::operator = (HFONT hFont)
{
if ( m_hDefFont != NULL )
{
::SelectObject (m_hDC, m_hDefFont);
DeleteObject (m_hFont);
}
m_hFont = hFont;
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_hFont);
return *this;
}
/////////////////////////////////////////////////////////////////////////////
const CZgFontDC& CZgFontDC::operator = (COLORREF crText)
{
if ( m_crTextOld == CLR_NONE )
{
m_crTextOld = ::GetTextColor (m_hDC);
}
::SetTextColor (m_hDC, crText);
return *this;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CZgBoldDC::CZgBoldDC (CDC *pDC, bool bBold) : m_hDC (pDC->m_hDC), m_hDefFont (NULL)
{
LOGFONT lf;
CFont::FromHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT))->GetLogFont (&lf);
if ( ( bBold && lf.lfWeight != FW_BOLD) ||
(!bBold && lf.lfWeight == FW_BOLD) )
{
lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
m_fontBold.CreateFontIndirect (&lf);
m_hDefFont = (HFONT)::SelectObject (m_hDC, m_fontBold);
}
}
/////////////////////////////////////////////////////////////////////////////
CZgBoldDC::~CZgBoldDC ()
{
if ( m_hDefFont != NULL )
{
::SelectObject (m_hDC, m_hDefFont);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -