www.pudn.com > fingerprint.rar > DIBAPI.CPP
// dibapi.cpp // // Source file for Device-Independent Bitmap (DIB) API. Provides // the following functions: // // PaintDIB() - Painting routine for a DIB // CreateDIBPalette() - Creates a palette from a DIB // FindDIBBits() - Returns a pointer to the DIB bits // DIBWidth() - Gets the width of the DIB // DIBHeight() - Gets the height of the DIB // PaletteSize() - Gets the size required to store the DIB's palette // DIBNumColors() - Calculates the number of colors // in the DIB's color table // CopyHandle() - Makes a copy of the given global memory block // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #include "dibapi.h" #include#include DWORD WINAPI BytesPerLine( LPBITMAPINFOHEADER lpBMIH ) { return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);} /************************************************************************* * * PaintDIB() * * Parameters: * * HDC hDC - DC to do output to * * LPRECT lpDCRect - rectangle on DC to do output to * * HDIB hDIB - handle to global memory with a DIB spec * in it followed by the DIB bits * * LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect * * CPalette* pPal - pointer to CPalette containing DIB's palette * * Return Value: * * BOOL - TRUE if DIB was drawn, FALSE otherwise * * Description: * Painting routine for a DIB. Calls StretchDIBits() or * SetDIBitsToDevice() to paint the DIB. The DIB is * output to the specified DC, at the coordinates given * in lpDCRect. The area of the DIB to be output is * given by lpDIBRect. * ************************************************************************/ BOOL WINAPI PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, HPALETTE hPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (hDIB == NULL) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); lpDIBBits = ::FindDIBBits(lpDIBHdr); // Get the DIB's palette, then select it into DC if (hPal) { // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = ::SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP ::GlobalUnlock((HGLOBAL) hDIB); /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; } /************************************************************************* * * FindDIBBits() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * LPSTR - pointer to the DIB bits * * Description: * * This function calculates the address of the DIB's bits and returns a * pointer to the DIB bits. * ************************************************************************/ LPSTR WINAPI FindDIBBits(LPSTR lpbi) { //////// return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi) +MaskSize(lpbi)); /////fixed by countercloc } /************************************************************************* * * DIBWidth() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * DWORD - width of the DIB * * Description: * * This function gets the width of the DIB from the BITMAPINFOHEADER * width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER * width field if it is an other-style DIB. * ************************************************************************/ DWORD WINAPI DIBWidth(LPSTR lpDIB) { LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB /* point to the header (whether Win 3.0 and old) */ lpbmi = (LPBITMAPINFOHEADER)lpDIB; lpbmc = (LPBITMAPCOREHEADER)lpDIB; /* return the DIB width if it is a Win 3.0 DIB */ if (IS_WIN30_DIB(lpDIB)) return lpbmi->biWidth; else /* it is an other-style DIB, so return its width */ return (DWORD)lpbmc->bcWidth; } /************************************************************************* * * DIBHeight() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * DWORD - height of the DIB * * Description: * * This function gets the height of the DIB from the BITMAPINFOHEADER * height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER * height field if it is an other-style DIB. * ************************************************************************/ DWORD WINAPI DIBHeight(LPSTR lpDIB) { LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB /* point to the header (whether old or Win 3.0 */ lpbmi = (LPBITMAPINFOHEADER)lpDIB; lpbmc = (LPBITMAPCOREHEADER)lpDIB; /* return the DIB height if it is a Win 3.0 DIB */ if (IS_WIN30_DIB(lpDIB)) return lpbmi->biHeight; else /* it is an other-style DIB, so return its height */ return (DWORD)lpbmc->bcHeight; } /************************************************************************* * * PaletteSize() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * WORD - size of the color palette of the DIB * * Description: * * This function gets the size required to store the DIB's palette by * multiplying the number of colors by the size of an RGBQUAD (for a * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other- * style DIB). * ************************************************************************/ WORD WINAPI PaletteSize(LPSTR lpbi) { /* calculate the size required by the palette */ if (IS_WIN30_DIB (lpbi)) return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD)); else return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE)); } /********************************************************************* * MaskSize() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * WORD - size of the color mask of the DIB * * Description: * * History: Date Author * 2/08/02 ÚùêÆ³© * **********************************************************************/ WORD WINAPI MaskSize(LPSTR lpbi) { return ((LPBITMAPINFOHEADER)lpbi)->biCompression==BI_BITFIELDS?12:0; } /// /************************************************************************* * * DIBNumColors() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * WORD - number of colors in the color table * * Description: * * This function calculates the number of colors in the DIB's color table * by finding the bits per pixel for the DIB (whether Win3.0 or other-style * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256, * if 24, no colors in color table. * ************************************************************************/ WORD WINAPI DIBNumColors(LPSTR lpbi) { WORD wBitCount; // DIB bit count /* If this is a Windows-style DIB, the number of colors in the * color table can be less than the number of bits per pixel * allows for (i.e. lpbi->biClrUsed can be set to some value). * If this is the case, return the appropriate value. */ if (IS_WIN30_DIB(lpbi)) { DWORD dwClrUsed; dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; if (dwClrUsed != 0) return (WORD)dwClrUsed; } /* Calculate the number of colors in the color table based on * the number of bits per pixel for the DIB. */ if (IS_WIN30_DIB(lpbi)) wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; else wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; /* return number of colors based on bits per pixel */ switch (wBitCount) { case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; } } ////////////////////////////////////////////////////////////////////////// //// Clipboard support //--------------------------------------------------------------------- // // Function: CopyHandle (from SDK DibView sample clipbrd.c) // // Purpose: Makes a copy of the given global memory block. Returns // a handle to the new memory block (NULL on error). // // Routine stolen verbatim out of ShowDIB. // // Parms: h == Handle to global memory to duplicate. // // Returns: Handle to new global memory block. // //--------------------------------------------------------------------- HGLOBAL WINAPI CopyHandle (HGLOBAL h) { if (h == NULL) return NULL; DWORD dwLen = ::GlobalSize((HGLOBAL) h); HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); if (hCopy != NULL) { void* lpCopy = ::GlobalLock((HGLOBAL) hCopy); void* lp = ::GlobalLock((HGLOBAL) h); memcpy(lpCopy, lp, dwLen); ::GlobalUnlock(hCopy); ::GlobalUnlock(h); } return hCopy; } // // Source file for Device-Independent Bitmap (DIB) API. Provides // the following functions: // // SaveDIB() - Saves the specified dib in a file // ReadDIBFile() - Loads a DIB from a file // // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #include #include #include #include "dibapi.h" /* * Dib Header Marker - used in writing DIBs to files */ #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B') /************************************************************************* * * SaveDIB() * * Saves the specified DIB into the specified CFile. The CFile * is opened and closed by the caller. * * Parameters: * * HDIB hDib - Handle to the dib to save * * CFile& file - open CFile used to save DIB * * Return value: TRUE if successful, else FALSE or CFileException * *************************************************************************/ /************************************************************************* Function: ReadDIBFile (CFile&) Purpose: Reads in the specified DIB file into a global chunk of memory. Returns: A handle to a dib (hDIB) if successful. NULL if an error occurs. Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything from the end of the BITMAPFILEHEADER structure on is returned in the global memory handle. *************************************************************************/ HDIB WINAPI ReadDIBFile(HANDLE hFile) { BITMAPFILEHEADER bmfHeader; DWORD dwBitsSize,dwRead; HDIB hDIB; LPSTR pDIB; /* * get length of DIB in bytes for use when reading */ dwBitsSize = GetFileSize(hFile,NULL); /* * Go read the DIB file header and check if it's valid. */ ReadFile(hFile,&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL); if (dwRead!= sizeof(bmfHeader)) return NULL; if (bmfHeader.bfType != DIB_HEADER_MARKER) return NULL; /* * Allocate memory for DIB */ hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize); if (hDIB == 0) { return NULL; } pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); /* * Go read the bits. */ ReadFile(hFile,pDIB,dwBitsSize - sizeof(BITMAPFILEHEADER),&dwRead,NULL); if (dwRead!= dwBitsSize - sizeof(BITMAPFILEHEADER) ) { ::GlobalUnlock((HGLOBAL) hDIB); ::GlobalFree((HGLOBAL) hDIB); return NULL; } ::GlobalUnlock((HGLOBAL) hDIB); return hDIB; } /**************************************************************************** * * FUNCTION: ConvertDIBFormat * * PURPOSE: Creates a new DIB of the requested format, copies the source * image to the new DIB. * * PARAMS: LPBITMAPINFO lpSrcDIB - the source CF_DIB * UINT nWidth - width for new DIB * UINT nHeight - height for new DIB * UINT nbpp - bpp for new DIB * BOOL bStretch - TRUE to stretch source to dest * FALSE to take upper left of image * * RETURNS: LPBYTE - pointer to new CF_DIB memory block with new image * NULL on failure * * History: * July '95 - Created * \****************************************************************************/ BOOL WINAPI CopyColorTable( LPBITMAPINFO lpTarget, LPBITMAPINFO lpSource ) { // What we do depends on the target's color depth switch( lpTarget->bmiHeader.biBitCount ) { // 8bpp - need 256 entry color table case 8: if( lpSource->bmiHeader.biBitCount == 8 ) { // Source is 8bpp too, copy color table memcpy( lpTarget->bmiColors, lpSource->bmiColors, 256*sizeof(RGBQUAD) ); return TRUE; } else { // Source is != 8bpp, use halftone palette HPALETTE hPal; HDC hDC = GetDC( NULL ); PALETTEENTRY pe[256]; UINT i; hPal = CreateHalftonePalette( hDC ); ReleaseDC( NULL, hDC ); GetPaletteEntries( hPal, 0, 256, pe ); DeleteObject( hPal ); for(i=0;i<256;i++) { lpTarget->bmiColors[i].rgbRed = pe[i].peRed; lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen; lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue; lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags; } return TRUE; } break; // end 8bpp // 4bpp - need 16 entry color table case 4: if( lpSource->bmiHeader.biBitCount == 4 ) { // Source is 4bpp too, copy color table memcpy( lpTarget->bmiColors, lpSource->bmiColors, 16*sizeof(RGBQUAD) ); return TRUE; } else { // Source is != 4bpp, use system palette HPALETTE hPal; PALETTEENTRY pe[256]; UINT i; hPal =(HPALETTE) GetStockObject( DEFAULT_PALETTE ); GetPaletteEntries( hPal, 0, 16, pe ); for(i=0;i<16;i++) { lpTarget->bmiColors[i].rgbRed = pe[i].peRed; lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen; lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue; lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags; } return TRUE; } break; // end 4bpp // 1bpp - need 2 entry mono color table case 1: lpTarget->bmiColors[0].rgbRed = 0; lpTarget->bmiColors[0].rgbGreen = 0; lpTarget->bmiColors[0].rgbBlue = 0; lpTarget->bmiColors[0].rgbReserved = 0; lpTarget->bmiColors[1].rgbRed = 255; lpTarget->bmiColors[1].rgbGreen = 255; lpTarget->bmiColors[1].rgbBlue = 255; lpTarget->bmiColors[1].rgbReserved = 0; break; // end 1bpp // no color table for the > 8bpp modes case 32: case 24: case 16: default: return TRUE; break; } return TRUE; } /* End CopyColorTable() *****************************************************/ HDIB WINAPI ConvertDIBFormat( HDIB hSrcDIB, UINT nbpp) { LPBITMAPINFO lpbmi = NULL,lpSrcDIB; LPBYTE lpSourceBits, lpTargetBits, lpResult; HDC hDC = NULL, hSourceDC, hTargetDC; HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap; DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize; HDIB hResult; //////if same bitcount ,then just copy lpSrcDIB=(LPBITMAPINFO)::GlobalLock(hSrcDIB); if(lpSrcDIB->bmiHeader.biBitCount==nbpp){ GlobalUnlock(hSrcDIB); return (HDIB)CopyHandle(hSrcDIB); } // Allocate and fill out a BITMAPINFO struct for the new DIB // Allow enough room for a 256-entry color table, just in case dwTargetHeaderSize = sizeof( BITMAPINFO ) + ( 256 * sizeof( RGBQUAD ) ); lpbmi =(LPBITMAPINFO) malloc( dwTargetHeaderSize ); lpbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); lpbmi->bmiHeader.biWidth = lpSrcDIB->bmiHeader.biWidth ; lpbmi->bmiHeader.biHeight = lpSrcDIB->bmiHeader.biHeight; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiHeader.biBitCount = nbpp; lpbmi->bmiHeader.biCompression = BI_RGB; lpbmi->bmiHeader.biSizeImage = 0; lpbmi->bmiHeader.biXPelsPerMeter = 0; lpbmi->bmiHeader.biYPelsPerMeter = 0; lpbmi->bmiHeader.biClrUsed = 0; lpbmi->bmiHeader.biClrImportant = 0; // Fill in the color table if( ! CopyColorTable( lpbmi, (LPBITMAPINFO)lpSrcDIB ) ) { free( lpbmi ); ::GlobalUnlock(hSrcDIB); return NULL; } ///*************FIX******* dwTargetHeaderSize=sizeof(BITMAPINFOHEADER)+DIBNumColors((LPSTR)lpbmi)*sizeof(RGBQUAD); //// // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em hDC = GetDC( NULL ); hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (void**)&lpTargetBits, NULL, 0 ); hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (void**)&lpSourceBits, NULL, 0 ); hSourceDC = CreateCompatibleDC( hDC ); hTargetDC = CreateCompatibleDC( hDC ); // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine(&(lpSrcDIB->bmiHeader)); dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine(&(lpbmi->bmiHeader)); memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize ); // Select DIBSections into DCs hOldSourceBitmap =(HBITMAP) SelectObject( hSourceDC, hSourceBitmap ); hOldTargetBitmap =(HBITMAP) SelectObject( hTargetDC, hTargetBitmap ); // Set the color tables for the DIBSections if( lpSrcDIB->bmiHeader.biBitCount <= 8 ) SetDIBColorTable( hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors ); if( lpbmi->bmiHeader.biBitCount <= 8 ) SetDIBColorTable( hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors ); // If we are asking for a straight copy, do it BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY ); // Clean up and delete the DCs SelectObject( hSourceDC, hOldSourceBitmap ); SelectObject( hSourceDC, hOldTargetBitmap ); DeleteDC( hSourceDC ); DeleteDC( hTargetDC ); ReleaseDC( NULL, hDC ); // Flush the GDI batch, so we can play with the bits GdiFlush(); // Allocate enough memory for the new CF_DIB, and copy bits hResult =(HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwTargetHeaderSize + dwTargetBitsSize); if(hResult==NULL){ ::GlobalUnlock((HGLOBAL) hSrcDIB); return NULL; } lpResult = (LPBYTE)GlobalLock(hResult); memcpy( lpResult, lpbmi, dwTargetHeaderSize ); memcpy( FindDIBBits((LPSTR) lpResult ), lpTargetBits, dwTargetBitsSize ); // final cleanup DeleteObject( hTargetBitmap ); DeleteObject( hSourceBitmap ); free( lpbmi ); ::GlobalUnlock((HGLOBAL) hResult); ::GlobalUnlock((HGLOBAL) hSrcDIB); return hResult; } /* End ConvertDIBFormat() ***************************************************/ /************************************************************************* * * CreateDIB() * * Parameters: * * DWORD dwWidth - Width for new bitmap, in pixels * DWORD dwHeight - Height for new bitmap * WORD wBitCount - Bit Count for new DIB (1, 4, 8, or 24) * * Return Value: * * HDIB - Handle to new DIB * * Description: * * This function allocates memory for and initializes a new DIB by * filling in the BITMAPINFOHEADER, allocating memory for the color * table, and allocating memory for the bitmap bits. As with all * HDIBs, the header, colortable and bits are all in one contiguous * memory block. This function is similar to the CreateBitmap() * Windows API. * * The colortable and bitmap bits are left uninitialized (zeroed) in the * returned HDIB. * * * History: Date Author Reason * 3/20/92 Mark Bader Created * ************************************************************************/ HDIB WINAPI CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) { BITMAPINFOHEADER bi; // bitmap header LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER DWORD dwLen; // size of memory block HDIB hDIB; DWORD dwBytesPerLine; // Number of bytes per scanline // Make sure bits per pixel is valid if (wBitCount <= 1) wBitCount = 1; else if (wBitCount <= 4) wBitCount = 4; else if (wBitCount <= 8) wBitCount = 8; else if (wBitCount <= 24) wBitCount = 24; else wBitCount = 4; // set default value to 4 if parameter is bogus // initialize BITMAPINFOHEADER bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = dwWidth; // fill in width from parameter bi.biHeight = dwHeight; // fill in height from parameter bi.biPlanes = 1; // must be 1 bi.biBitCount = wBitCount; // from parameter bi.biCompression = BI_RGB; bi.biSizeImage = 0; // 0's here mean "default" bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // calculate size of memory block required to store the DIB. This // block should be big enough to hold the BITMAPINFOHEADER, the color // table, and the bits dwBytesPerLine = WIDTHBYTES(wBitCount * dwWidth); dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); // alloc memory block to store our bitmap hDIB = (HDIB)GlobalAlloc(GHND, dwLen); // major bummer if we couldn't get memory block if (!hDIB) return NULL; // lock memory and get pointer to it lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); // use our bitmap info structure to fill in first part of // our DIB with the BITMAPINFOHEADER *lpbi = bi; // Since we don't know what the colortable and bits should contain, // just leave these blank. Unlock the DIB and return the HDIB. GlobalUnlock(hDIB); //return handle to the DIB return hDIB; }