HICON MakeIcon()

in tools/ExeView/iconcur.cpp [141:399]


HICON MakeIcon ( LPRESPACKET lprp )
{
    LPBITMAPINFOHEADER lpbihdr;
    LPBITMAPINFO       lpbinfo;

    HICON   hIcon = NULL;
    WORD    wH, wW, wXORSize, wANDSize, wColorTableSize, wScans;
    WORD    wIconW, wIconH;
    LPBYTE  lpANDbits;
    LPBYTE  lpXORbits;
    HDC     hDC, hSrcDC, hDestDC;
    HBITMAP hbmpXOR, hbmpAND;
    HBITMAP hbmpDestXOR, hbmpDestAND;
    HBITMAP hbmpOldSrc, hbmpOldDest;
    BITMAP  bmp;
    HANDLE  hXORbits, hANDbits;


    lpbihdr = (LPBITMAPINFOHEADER)lprp->lpMem;
    lpbinfo = (LPBITMAPINFO)lpbihdr;

    wW = (WORD)lpbihdr->biWidth;
    wH = (WORD)lpbihdr->biHeight / 2;

    wXORSize = (wW * wH * lpbihdr->biBitCount) / 8;
    wANDSize= (wW * wH) / 8;

    wColorTableSize = sizeof(RGBQUAD) * (0x0001<<lpbihdr->biBitCount);

    lpXORbits = ((LPBYTE)lpbihdr)+wColorTableSize+(WORD)lpbihdr->biSize;
    lpANDbits = lpXORbits + wXORSize;

    // Now we need to make a bitmap and convert these to DDB
    // Get a screen DC
    hDC = GetDC( NULL );
    if (!hDC)
        return NULL;

    
// XOR BITMAP
    // create color device-dependent bitmap for XOR mask
    hbmpXOR = CreateCompatibleBitmap( hDC, wW, wH );

    if (!hbmpXOR)
    {
        ReleaseDC( NULL, hDC );
        return NULL;
    }

    // modify BITMAPINFOHEADER structure for color bitmap 
    lpbihdr->biHeight = wH;

    // convert XOR mask from DIB to DDB
    wScans = SetDIBits(hDC, hbmpXOR, 0, wH, lpXORbits, lpbinfo, DIB_RGB_COLORS);

    if (wScans == 0)
    {
        DeleteObject( hbmpXOR );
        ReleaseDC( NULL, hDC );
        return NULL;
    }


// AND BITMAP
    // create MONO device-dependent bitmap for AND mask
    hbmpAND= CreateBitmap( wW, wH, 1, 1, NULL );

    if (!hbmpAND)
    {
        DeleteObject( hbmpXOR );
        ReleaseDC( NULL, hDC );
        return NULL;
    }
    else
    {
        RGBQUAD rgbBlack = { 0x00, 0x00, 0x00, 0x00 };
        RGBQUAD rgbWhite = { 0xFF, 0xFF, 0xFF, 0x00 };

        // modify BITMAPINFOHEADER structure for monochrome bitmap
        lpbihdr->biHeight = wH;
        lpbihdr->biSizeImage = wANDSize;
        lpbihdr->biBitCount = 1;

        lpbinfo->bmiColors[0] = rgbBlack;
        lpbinfo->bmiColors[1] = rgbWhite;

        // convert AND mask from DIB to DDB
        wScans = SetDIBits(hDC,hbmpAND,0,wH,lpANDbits,lpbinfo,DIB_RGB_COLORS);

        if (wScans == 0)
        {
            DeleteObject( hbmpXOR );
            DeleteObject( hbmpAND );
            ReleaseDC( NULL, hDC );
            return NULL;
        }
    }


// Now that we have a AND bitmap and a XOR bitmap, we need to
// convert the icon size to that of the display by using StretchBlt.

    hSrcDC  = CreateCompatibleDC( hDC );
    if (!hSrcDC)
    {
        DeleteObject( hbmpXOR );
        DeleteObject( hbmpAND );
        ReleaseDC( NULL, hDC );
        return NULL;
    }

    hDestDC = CreateCompatibleDC( hDC );
    if (!hDestDC)
    {
        DeleteDC( hSrcDC );
        DeleteObject( hbmpXOR );
        DeleteObject( hbmpAND );
        ReleaseDC( NULL, hDC );
        return NULL;
    }

    wIconW = GetSystemMetrics( SM_CXICON );
    wIconH = GetSystemMetrics( SM_CYICON );

    hbmpDestXOR = CreateCompatibleBitmap( hDC, wIconW, wIconH );

    if (!hbmpDestXOR)
    {
        DeleteObject( hbmpXOR );
        DeleteObject( hbmpAND );
        DeleteDC( hSrcDC );
        DeleteDC( hDestDC );
        ReleaseDC( NULL, hDC );
        return NULL;
    }

    hbmpDestAND = CreateBitmap( wIconW, wIconH, 1, 1, NULL );

    if (!hbmpDestAND)
    {
        DeleteObject( hbmpDestXOR );
        DeleteObject( hbmpXOR );
        DeleteObject( hbmpAND );
        DeleteDC( hSrcDC );
        DeleteDC( hDestDC );
        ReleaseDC( NULL, hDC );
        return NULL;
    }

    hbmpOldSrc = (HBITMAP)SelectObject( hSrcDC, hbmpXOR );
    hbmpOldDest = (HBITMAP)SelectObject( hDestDC, hbmpDestXOR );
    SetStretchBltMode( hDestDC, COLORONCOLOR );

    StretchBlt(hDestDC,0,0,wIconW,wIconH,hSrcDC,0,0,wW,wH,SRCCOPY);

    SelectObject( hSrcDC, hbmpAND );
    SelectObject( hDestDC, hbmpDestAND );
    SetStretchBltMode( hDestDC, BLACKONWHITE );

    StretchBlt(hDestDC,0,0,wIconW,wIconH,hSrcDC,0,0,wW,wH,SRCCOPY);

    // Clean up all but the two new bitmaps
    SelectObject( hSrcDC, hbmpOldSrc );
    SelectObject( hDestDC, hbmpOldDest );
    DeleteDC( hSrcDC );
    DeleteDC( hDestDC );
    ReleaseDC( NULL, hDC );
    DeleteObject( hbmpXOR );
    DeleteObject( hbmpAND );


// Now that the bitmaps are the correct size, we need to retrieve
// the DDB bits again so we can CreateIcon
    
    GetObject( hbmpDestXOR, sizeof(BITMAP), (LPSTR)&bmp );

    wXORSize = (bmp.bmWidth * bmp.bmHeight) *
                (bmp.bmPlanes * bmp.bmBitsPixel) / 8;

    hXORbits = GlobalAlloc( GHND, wXORSize );

    if (hXORbits == NULL)
    {
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }

    if ((lpXORbits = (LPBYTE)GlobalLock( hXORbits )) == NULL)
    {
        GlobalFree( hXORbits );
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }

    if (!GetBitmapBits( hbmpDestXOR, wXORSize, lpXORbits))
    {
        GlobalUnlock( hXORbits );
        GlobalFree( hXORbits );
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }

    GetObject( hbmpDestAND, sizeof(BITMAP), (LPSTR)&bmp );

    wANDSize = (bmp.bmWidth * bmp.bmHeight) / 8;

    hANDbits = GlobalAlloc( GHND, wANDSize );

    if (hANDbits == NULL)
    {
        GlobalUnlock( hXORbits );
        GlobalFree( hXORbits );
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }

    if ((lpANDbits = (LPBYTE)GlobalLock( hANDbits )) == NULL)
    {
        GlobalFree( hANDbits );
        GlobalUnlock( hXORbits );
        GlobalFree( hXORbits );
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }

    if (!GetBitmapBits( hbmpDestAND,wANDSize,lpANDbits))
    {
        GlobalUnlock( hANDbits );
        GlobalFree( hANDbits );
        GlobalUnlock( hXORbits );
        GlobalFree( hXORbits );
        DeleteObject( hbmpDestAND );
        DeleteObject( hbmpDestXOR );
        return NULL;
    }


// Now after all this we can finally make an icon.

    GetObject( hbmpDestXOR, sizeof(BITMAP), (LPSTR)&bmp );

    hIcon = CreateIcon( ghInst, wIconW, wIconH, bmp.bmPlanes,
        bmp.bmBitsPixel, lpANDbits, lpXORbits );

    GlobalUnlock( hANDbits );
    GlobalFree( hANDbits );
    GlobalUnlock( hXORbits );
    GlobalFree( hXORbits );
    DeleteObject( hbmpDestAND );
    DeleteObject( hbmpDestXOR );

    return hIcon;

} //*** MakeIcon