HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal) { BITMAP bm; // bitmap structure BITMAPINFOHEADER bi; // bitmap header LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER DWORD dwLen; // size of memory block HANDLE hDIB, h; // handle to DIB, temp handle HDC hDC; // handle to DC WORD biBits; // bits per pixel // check if bitmap handle is valid if (!hBitmap) return NULL; // fill in BITMAP structure, return NULL if it didn't work if (!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm)) return NULL; // if no palette is specified, use default palette if (hPal == NULL) hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); // calculate bits per pixel biBits = bm.bmPlanes * bm.bmBitsPixel; // make sure bits per pixel is valid if (biBits <= 1) biBits = 1; else if (biBits <= 4) biBits = 4; else if (biBits <= 8) biBits = 8; else // if greater than 8-bit, force to 24-bit biBits = 24; // initialize BITMAPINFOHEADER bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = biBits; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // calculate size of memory block required to store BITMAPINFO dwLen = bi.biSize + PaletteSize((LPSTR)&bi); // get a DC hDC = GetDC(NULL); // select and realize our palette hPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); // alloc memory block to store our bitmap hDIB = GlobalAlloc(GHND, dwLen); // if we couldn't get memory block if (!hDIB) { // clean up and return NULL SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } // lock memory and get pointer to it lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); /// use our bitmap info. to fill BITMAPINFOHEADER *lpbi = bi; // call GetDIBits with a NULL lpBits param, so it will calculate the // biSizeImage field for us GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); // get the info. returned by GetDIBits and unlock memory block bi = *lpbi; GlobalUnlock(hDIB); // if the driver did not fill in the biSizeImage field, make one up if (bi.biSizeImage == 0) bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; // realloc the buffer big enough to hold all the bits dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage; if (h = GlobalReAlloc(hDIB, dwLen, 0)) hDIB = h; else { // clean up and return NULL GlobalFree(hDIB); hDIB = NULL; SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } // lock memory block and get pointer to it */ lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); // call GetDIBits with a NON-NULL lpBits param, and actualy get the // bits this time if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) { // clean up and return NULL GlobalUnlock(hDIB); hDIB = NULL; SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } bi = *lpbi; // clean up GlobalUnlock(hDIB); SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); // return handle to the DIB return hDIB; }