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