BITMAPFILEHEADER    bmfHeader; 
    DWORD               dwBitsSize; 
    HANDLE              hDIBtmp;      // Used for GlobalRealloc() //MPB 
    LPBITMAPINFOHEADER  lpbi; 
    DWORD               offBits; 
    DWORD               dwRead; 
     // get length of DIB in bytes for use when reading 
  dwBitsSize = pFile->GetLength();
 
    // Allocate memory for header & color table. We'll enlarge this 
    // memory as needed. 
 
m_hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) + 
            256 * sizeof(RGBQUAD))); 
 
    if (!m_hDIB) 
        return FALSE; 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB); 
 
    if (!lpbi)  
    { 
        GlobalFree(m_hDIB); 
        return FALSE; 
    } 
 
  
    if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER), &dwRead, 
            NULL)) 
{
GlobalFree(m_hDIB);
return FALSE;
}
         
    if (sizeof(BITMAPINFOHEADER) != dwRead) 
{
GlobalFree(m_hDIB);
return FALSE;
}
    if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) 
{
GlobalFree(m_hDIB);
return FALSE;  } lpbi->biBitCount = 8;
lpbi->biClrImportant = 256;
lpbi->biClrUsed = 256;
lpbi->biCompression = BI_RGB;
lpbi->biHeight = 600;
lpbi->biWidth = 600;
lpbi->biPlanes = 1;
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biSizeImage = 0;
lpbi->biXPelsPerMeter = 0;
lpbi->biYPelsPerMeter = 0; m_nColorNum = 256;    // get a proper-sized buffer for header, color table and bits 
 
    GlobalUnlock(m_hDIB); 
    hDIBtmp = GlobalReAlloc(m_hDIB, lpbi->biSize + m_nColorNum * 
            sizeof(RGBQUAD) + lpbi->biSizeImage, 0); 
 
    if (!hDIBtmp) // can't resize buffer for loading 
return FALSE;
    else 
        m_hDIB = hDIBtmp; 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB); 
 
 
    offBits = lpbi->biSize + m_nColorNum * sizeof(RGBQUAD); 
 
    if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi + offBits, lpbi->biSizeImage, &dwRead, 
            NULL)) 
        return FALSE; 
 
    GlobalUnlock(m_hDIB);
    return TRUE;
/////////////////////////////////////////////////////////////////make palette
HPALETTE CBitmapShowDoc::CreateDIBPalette(LPBYTE lpbi) 

    LPLOGPALETTE        lpPal;          // pointer to a logical palette 
    HANDLE              hLogPal;        // handle to a logical palette 
    HPALETTE            hPal  = NULL;// handle to a palette 
    int                 i, wNumColors;  // loop index, number of colors in color table 
    LPBITMAPINFO        lpbmi;          // pointer to BITMAPINFO structure (Win3.0) 
    LPBITMAPCOREINFO    lpbmc;          // pointer to BITMAPCOREINFO structure (OS/2) 
 
    // if handle to DIB is invalid, return NULL 
 
    if (! lpbi) 
        return NULL; 
 
    // get pointer to BITMAPINFO (Win 3.0) 
 
    lpbmi = (LPBITMAPINFO)lpbi; 
 
    // get pointer to BITMAPCOREINFO (OS/2 1.x) 
 
    wNumColors = m_nColorNum; 
 
    // is this a Win 3.0 DIB? 
 
    if (wNumColors) 
    { 
        // allocate memory block for logical palette 
 
        hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + 
                sizeof(PALETTEENTRY) * wNumColors); 
 
        // if not enough memory, clean up and return NULL 
 
        if (!hLogPal) 
            return NULL; 
 
        // lock memory block and get pointer to it 
 
        lpPal = (LPLOGPALETTE)GlobalLock(hLogPal); 
 
        // set version and number of palette entries 
 
        lpPal->palVersion = 0x300; 
        lpPal->palNumEntries = wNumColors; 
 
        // store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB) 
        // into palette 

for (i = 0; i < wNumColors; i++) 
        { 
int j;
j = i*3;
lpPal->palPalEntry[i].peRed = j;//lpbmi->bmiColors[i].rgbRed; 
lpPal->palPalEntry[i].peGreen = j;//lpbmi->bmiColors[i].rgbGreen; 
lpPal->palPalEntry[i].peBlue = j;//lpbmi->bmiColors[i].rgbBlue; 
lpPal->palPalEntry[i].peFlags = 0; 

       // create the palette and get handle to it 
 
        hPal = CreatePalette(lpPal); 
 
        // if error getting handle to palette, clean up and return NULL 
 
        if (!hPal) 
        { 
            GlobalUnlock(hLogPal); 
            GlobalFree(hLogPal); 
            return NULL; 
        } 
    } 
 
    // return handle to DIB's palette 
    return hPal; 
///////////////////////////////////////////////////////////show image
BOOL CBitmapShowView::PaintDIB(HDC hDC, HANDLE hDIB, HPALETTE hPal, int colorNum)

    LPBYTE        lpDIBHdr;           // Pointer to BITMAPINFOHEADER 
    LPBYTE        lpDIBBits;          // Pointer to DIB bits 
    BOOL         bSuccess=FALSE;     // Success/fail flag 
    HPALETTE     hOldPal=NULL;       // Previous palette 
 
    // Check for valid DIB handle 
 
    if (!hDIB) 
        return FALSE;     // Lock down the DIB, and get a pointer to the beginning of the bit 
    // buffer 
     
    lpDIBHdr  = (LPBYTE)GlobalLock(hDIB); 
    lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER) + 
                colorNum*sizeof(RGBQUAD);

 
// if no palette provided, create one from DIB    if (hPal) 
    { 
        hOldPal = SelectPalette(hDC, hPal, TRUE); 
        RealizePalette(hDC); 
    } 
 
    // Make sure to use the stretching mode best for color pictures 
 
    SetStretchBltMode(hDC, COLORONCOLOR); 
 
    // Call StretchDIBits() with dwRop
 
CRect pRect;
GetClientRect(pRect);
// ClientToScreen(pRect); bSuccess = ::SetDIBitsToDevice(hDC, 0, 0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biWidth,((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight, 0,0,0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
 
    // Unlock the memory block 
 
    GlobalUnlock(hDIB); 
 
    // Reselect old palette 
 
    if (hOldPal) 
SelectPalette(hDC, hOldPal, FALSE); 
 
    // Return with success/fail flag 
    return bSuccess; 
}

解决方案 »

  1.   

    以下代码测试通过,支持bmp灰度和彩色,你可以参考一下
    void CTestDlg::OnButton1() 
    {
    // TODO: Add your control notification handler code here CFile file;
    file.Open("t.bmp", CFile::modeRead, NULL) //1.读入bmpfileheader
    BITMAPFILEHEADER  bitmapfileheader; 
    file.Read((LPSTR)&bitmapfileheader, sizeof(bitmapfileheader);

    //2.读入bmpinfoheader  
    int nInfoSize=bitmapfileheader.bfOffBits-sizeof(bitmapfileheader);
    BITMAPINFO * lpBitmapinfo=(BITMAPINFO *)new char[nInfoSize];
    file.Read((LPSTR)lpBitmapinfo,nInfoSize);

    //3.读入图像内容
    long nImageSize=bitmapfileheader.bfSize-bitmapfileheader.bfOffBits;
    unsigned char * lpDIBBits=new unsigned char[nImageSize];
    file.ReadHuge(lpDIBBits,nImageSize);

    //4.显示处理
    CClientDC dc(this);
    SetDIBitsToDevice(dc.m_hDC, 100, 0, 
    lpBitmapinfo->bmiHeader.biWidth,lpBitmapinfo->bmiHeader.biHeight, 0,0,0,
    lpBitmapinfo->bmiHeader.biHeight,
    lpDIBBits,lpBitmapinfo,DIB_RGB_COLORS);

    //退出
    delete lpBitmapinfo;
    delete []lpDIBBits;
    file.Close();
    }
    ---------------------
    typedef struct tagBITMAPINFO {
        BITMAPINFOHEADER    bmiHeader;
        RGBQUAD             bmiColors[1];
    } BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;操作2时候将 bmiColors读入, 在SetDIBitsToDevice显示时候就会采用. 你的代码没有读入bmiColors内容.