//---------------------------------------------------------------------------- // FUNCTION: LoadBitmapFromBuffer // DESC: 从缓冲区中加载位图并返回句柄 //---------------------------------------------------------------------------- HBITMAP LoadBitmapFromBuffer(LPBYTE pBuffer, DWORD cbSize) { BITMAPFILEHEADER *pbmfHeader = LPBITMAPFILEHEADER(pBuffer);// File type should be 'BM' BITMAPINFOHEADER *pbmiHeader = LPBITMAPINFOHEADER(pBuffer + sizeof(BITMAPFILEHEADER)); BITMAPINFO *pbmInfo = LPBITMAPINFO (pBuffer + sizeof(BITMAPFILEHEADER)); // If bmiHeader.biClrUsed is zero we have to infer the number of colors from the number of bits used to specify it. int nColors = pbmiHeader->biClrUsed ? pbmiHeader->biClrUsed : 1 << pbmiHeader->biBitCount; if (pbmfHeader->bfType != (WORD('M' << 8) | 'B')) { return NULL; } LPVOID lpDIBBits; if( pbmInfo->bmiHeader.biBitCount > 8 ) { lpDIBBits = LPVOID(LPDWORD(pbmInfo->bmiColors + pbmInfo->bmiHeader.biClrUsed) + ((pbmInfo->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0)); } else { lpDIBBits = LPVOID(pbmInfo->bmiColors + nColors); } HDC hdc = GetDC(NULL); // Create the palette HPALETTE hPal, hOldPal; if( nColors <= 256 ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); LOGPALETTE *pLP = (LOGPALETTE *) malloc(nSize); pLP->palVersion = 0x300; pLP->palNumEntries = nColors; for( int i = 0; i < nColors; i++ ) { pLP->palPalEntry[i].peRed = pbmInfo->bmiColors[i].rgbRed; pLP->palPalEntry[i].peGreen = pbmInfo->bmiColors[i].rgbGreen; pLP->palPalEntry[i].peBlue = pbmInfo->bmiColors[i].rgbBlue; pLP->palPalEntry[i].peFlags = 0; } hPal = CreatePalette(pLP); free(pLP); hOldPal=(HPALETTE)SelectObject(hdc, hPal); RealizePalette(hdc); } HBITMAP hBmp = CreateDIBitmap( hdc, // handle to device context pbmiHeader, // pointer to bitmap size and format data CBM_INIT, // initialization flag lpDIBBits, // pointer to initialization data pbmInfo, // pointer to bitmap color-format data DIB_RGB_COLORS); // color-data usage if( hPal ) { SelectObject(hdc, hOldPal); DeleteObject(hPal); } ReleaseDC(NULL, hdc); return hBmp; }