📄 icons.c
字号:
/****************************************************************************
*
* FUNCTION: CreateBlankNewFormatIcon
*
* PURPOSE: Creates a blank icon image for a new format
*
* PARAMS: LPICONIMAGE lpii - pointer to icon image data
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL CreateBlankNewFormatIcon( LPICONIMAGE lpii )
{
DWORD dwFinalSize;
BITMAPINFOHEADER bmih;
// Fill in the bitmap header
ZeroMemory( &bmih, sizeof( BITMAPINFOHEADER ) );
bmih.biSize = sizeof( BITMAPINFOHEADER );
bmih.biBitCount = lpii->Colors;
bmih.biClrUsed = 0;
// How big will the final thing be?
// Well, it'll have a header
dwFinalSize = sizeof( BITMAPINFOHEADER );
// and a color table (even if it's zero length)
dwFinalSize += PaletteSize( (LPSTR)&bmih );
// and XOR bits
dwFinalSize += lpii->Height * WIDTHBYTES( lpii->Width * lpii->Colors );
// and AND bits. That's about it :)
dwFinalSize += lpii->Height * WIDTHBYTES( lpii->Width );
// Allocate some memory for it
lpii->lpBits = malloc( dwFinalSize );
ZeroMemory( lpii->lpBits, dwFinalSize );
lpii->dwNumBytes = dwFinalSize;
lpii->lpbi = (LPBITMAPINFO)(lpii->lpBits);
lpii->lpXOR = (LPSTR)(lpii->lpbi) + sizeof(BITMAPINFOHEADER) + PaletteSize( (LPSTR)&bmih );
lpii->lpAND = lpii->lpXOR + (lpii->Height * WIDTHBYTES( lpii->Width * lpii->Colors ));
// The bitmap header is zeros, fill it out
lpii->lpbi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpii->lpbi->bmiHeader.biWidth = lpii->Width;
// Don't forget the funky height*2 icon resource thing
lpii->lpbi->bmiHeader.biHeight = lpii->Height * 2;
lpii->lpbi->bmiHeader.biPlanes = 1;
lpii->lpbi->bmiHeader.biBitCount = lpii->Colors;
lpii->lpbi->bmiHeader.biCompression = BI_RGB;
return TRUE;
}
/* End CreateBlankNewFormatIcon() ******************************************/
/****************************************************************************
*
* FUNCTION: GetXORImageRect
*
* PURPOSE: Given a bounding Rect, calculates the XOR mask display Rect
*
* PARAMS: RECT Rect - Bounding rect for drawing area
* LPICONIMAGE lpIcon - pointer to icon image data
*
* RETURNS: RECT - the rect where the XOR image will be drawn
*
* History:
* July '95 - Created
*
\****************************************************************************/
RECT GetXORImageRect( RECT Rect, LPICONIMAGE lpIcon )
{
RECT NewRect;
// Just center the thing in the bounding display rect
NewRect.left = Rect.left + ((RectWidth(Rect)-lpIcon->lpbi->bmiHeader.biWidth)/2);
NewRect.top = Rect.top + ((RectHeight(Rect)-(lpIcon->lpbi->bmiHeader.biHeight/2))/2);
NewRect.bottom = NewRect.top + (lpIcon->lpbi->bmiHeader.biHeight/2);
NewRect.right = NewRect.left + lpIcon->lpbi->bmiHeader.biWidth;
return NewRect;
}
/* End GetXORImageRect() ***************************************************/
/****************************************************************************
*
* FUNCTION: DrawXORMask
*
* PURPOSE: Using DIB functions, draw XOR mask on hDC in Rect
*
* PARAMS: HDC hDC - The DC on which to draw
* RECT Rect - Bounding rect for drawing area
* LPICONIMAGE lpIcon - pointer to icon image data
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* COMMENTS: Does not use any palette information since the
* OS won't when it draws the icon anyway.
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL DrawXORMask( HDC hDC, RECT Rect, LPICONIMAGE lpIcon )
{
int x, y;
// Sanity checks
if( lpIcon == NULL )
return FALSE;
if( lpIcon->lpBits == NULL )
return FALSE;
// Account for height*2 thing
lpIcon->lpbi->bmiHeader.biHeight /= 2;
// Locate it
x = Rect.left + ((RectWidth(Rect)-lpIcon->lpbi->bmiHeader.biWidth)/2);
y = Rect.top + ((RectHeight(Rect)-lpIcon->lpbi->bmiHeader.biHeight)/2);
// Blast it to the screen
SetDIBitsToDevice( hDC, x, y, lpIcon->lpbi->bmiHeader.biWidth, lpIcon->lpbi->bmiHeader.biHeight, 0, 0, 0, lpIcon->lpbi->bmiHeader.biHeight, lpIcon->lpXOR, lpIcon->lpbi, DIB_RGB_COLORS );
// UnAccount for height*2 thing
lpIcon->lpbi->bmiHeader.biHeight *= 2;
return TRUE;
}
/* End DrawXORMask() *******************************************************/
/****************************************************************************
*
* FUNCTION: DrawANDMask
*
* PURPOSE: Using DIB functions, draw AND mask on hDC in Rect
*
* PARAMS: HDC hDC - The DC on which to draw
* RECT Rect - Bounding rect for drawing area
* LPICONIMAGE lpIcon - pointer to icon image data
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL DrawANDMask( HDC hDC, RECT Rect, LPICONIMAGE lpIcon )
{
LPBITMAPINFO lpbi;
int x, y;
// Sanity checks
if( lpIcon == NULL )
return FALSE;
if( lpIcon->lpBits == NULL )
return FALSE;
// Need a bitmap header for the mono mask
lpbi = malloc( sizeof(BITMAPINFO) + (2 * sizeof( RGBQUAD )) );
lpbi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbi->bmiHeader.biWidth = lpIcon->lpbi->bmiHeader.biWidth;
lpbi->bmiHeader.biHeight = lpIcon->lpbi->bmiHeader.biHeight/2;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 1;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = 0;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;
lpbi->bmiColors[0].rgbRed = 0;
lpbi->bmiColors[0].rgbGreen = 0;
lpbi->bmiColors[0].rgbBlue = 0;
lpbi->bmiColors[0].rgbReserved = 0;
lpbi->bmiColors[1].rgbRed = 255;
lpbi->bmiColors[1].rgbGreen = 255;
lpbi->bmiColors[1].rgbBlue = 255;
lpbi->bmiColors[1].rgbReserved = 0;
// Locate it
x = Rect.left + ((RectWidth(Rect)-lpbi->bmiHeader.biWidth)/2);
y = Rect.top + ((RectHeight(Rect)-lpbi->bmiHeader.biHeight)/2);
// Blast it to the screen
SetDIBitsToDevice( hDC, x, y, lpbi->bmiHeader.biWidth, lpbi->bmiHeader.biHeight, 0, 0, 0, lpbi->bmiHeader.biHeight, lpIcon->lpAND, lpbi, DIB_RGB_COLORS );
// clean up
free( lpbi );
return TRUE;
}
/* End DrawANDMask() *******************************************************/
/****************************************************************************
*
* FUNCTION: MakeNewANDMaskBasedOnPoint
*
* PURPOSE: Creates a new AND mask for the icon image
*
* PARAMS: LPICONIMAGE lpIcon - pointer to icon image data
* POINT pt - coords of transparent pixel
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* COMMENTS: Creates the AND mask using the color of the pixel at pt
* as a transparent color. The XOR mask is changed as well.
* This is because the OS expects the XOR mask to have the
* AND mask already applied (ie black in transparent areas)
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL MakeNewANDMaskBasedOnPoint( LPICONIMAGE lpIcon, POINT pt )
{
HBITMAP hXORBitmap, hOldXORBitmap;
HDC hDC, hMemDC1;
LPBYTE pXORBits;
COLORREF crTransparentColor;
LONG i,j;
// Account for height*2 thing
lpIcon->lpbi->bmiHeader.biHeight /= 2;
// Need a DC
hDC = GetDC( NULL );
// Use DIBSection for source
hXORBitmap = CreateDIBSection( hDC, lpIcon->lpbi, DIB_RGB_COLORS, &pXORBits, NULL, 0 );
memcpy( pXORBits, lpIcon->lpXOR, (lpIcon->lpbi->bmiHeader.biHeight) * BytesPerLine((LPBITMAPINFOHEADER)(lpIcon->lpbi)) );
hMemDC1 = CreateCompatibleDC( hDC );
hOldXORBitmap = SelectObject( hMemDC1, hXORBitmap );
// Set the color table if need be
if( lpIcon->lpbi->bmiHeader.biBitCount <= 8 )
SetDIBColorTable( hMemDC1, 0, DIBNumColors((LPSTR)(lpIcon->lpbi)), lpIcon->lpbi->bmiColors);
// What's the transparent color?
crTransparentColor = GetPixel( hMemDC1, pt.x, pt.y );
// Loop through the pixels
for(i=0;i<lpIcon->lpbi->bmiHeader.biWidth;i++)
{
for(j=0;j<lpIcon->lpbi->bmiHeader.biHeight;j++)
{
// Is the source transparent at this point?
if( GetPixel( hMemDC1, i, j ) == crTransparentColor )
{
// Yes, so set the pixel in AND mask, and clear it in XOR mask
SetMonoDIBPixel( lpIcon->lpAND, lpIcon->lpbi->bmiHeader.biWidth, lpIcon->lpbi->bmiHeader.biHeight, i, j, TRUE );
if( lpIcon->lpbi->bmiHeader.biBitCount == 1 )
SetMonoDIBPixel( pXORBits, lpIcon->lpbi->bmiHeader.biWidth, lpIcon->lpbi->bmiHeader.biHeight, i, j, FALSE );
else
SetPixelV( hMemDC1, i, j, RGB(0,0,0) );
}
else
{
// No, so clear pixel in AND mask
SetMonoDIBPixel( lpIcon->lpAND, lpIcon->lpbi->bmiHeader.biWidth, lpIcon->lpbi->bmiHeader.biHeight, i, j, FALSE );
}
}
}
// Flush the SetPixelV() calls
GdiFlush();
SelectObject( hMemDC1, hOldXORBitmap );
// Copy the new XOR bits back to our storage
memcpy( lpIcon->lpXOR, pXORBits, (lpIcon->lpbi->bmiHeader.biHeight) * BytesPerLine((LPBITMAPINFOHEADER)(lpIcon->lpbi)) );
// Clean up
DeleteObject( hXORBitmap );
DeleteDC( hMemDC1 );
ReleaseDC( NULL, hDC );
// UnAccount for height*2 thing
lpIcon->lpbi->bmiHeader.biHeight *= 2;
return TRUE;
}
/* End MakeNewANDMaskBasedOnPoint() *****************************************/
/****************************************************************************
*
* FUNCTION: IconImageFromBMPFile
*
* PURPOSE: Creates an icon image from a BMP file
*
* PARAMS: LPCTSTR szFileName - Filename for BMP file
* LPICONIMAGE lpii - pointer to icon image data
* BOOL bStretchToFit - TRUE to stretch, FALSE to take
* the upper left corner of the DIB
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL IconImageFromBMPFile( LPCTSTR szFileName, LPICONIMAGE lpii, BOOL bStretchToFit )
{
LPBYTE lpDIB = NULL;
BOOL bRet = FALSE;
if( (lpDIB=ReadBMPFile(szFileName)) == NULL )
return FALSE;
// Convert it to an icon image
bRet = DIBToIconImage( lpii, lpDIB, bStretchToFit );
free( lpDIB );
return bRet;
}
/* End IconImageFromBMPFile() ********************************************/
/****************************************************************************
*
* FUNCTION: IconImageToBMPFile
*
* PURPOSE: Creates BMP file from an icon image
*
* PARAMS: LPCTSTR szFileName - Filename for BMP file
* LPICONIMAGE lpii - pointer to icon image data
*
* RETURNS: BOOL - TRUE for success, FALSE for failure
*
* History:
* July '95 - Created
*
\****************************************************************************/
BOOL IconImageToBMPFile( LPCTSTR szFileName, LPICONIMAGE lpii )
{
return WriteBMPFile( szFileName, (LPBYTE)lpii->lpbi );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -