⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icons.c

📁 ICon文件格式
💻 C
📖 第 1 页 / 共 4 页
字号:

/****************************************************************************
*
*     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 + -