draw_bmp_file.txt
Upload User: sdblgkt
Upload Date: 2007-01-03
Package Size: 2k
Code Size: 3k
Category:

Picture Viewer

Development Platform:

Visual C++

  1. // LoadBMP - Loads a BMP file and creates a logical palette for it.
  2. // Returns - TRUE for success
  3. // sBMPFile - Full path of the BMP file
  4. // phDIB - Pointer to a HGLOBAL variable to hold the loaded bitmap
  5. //   Memory is allocated by this function but should be 
  6. //   released by the caller.
  7. // pPal - Will hold the logical palette
  8. BOOL LoadBMP( LPCTSTR sBMPFile, HGLOBAL *phDIB, CPalette *pPal )
  9. {
  10. CFile file;
  11. if( !file.Open( sBMPFile, CFile::modeRead) )
  12. return FALSE;
  13. BITMAPFILEHEADER bmfHeader;
  14. long nFileLen;
  15. nFileLen = file.GetLength();
  16. // Read file header
  17. if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
  18. return FALSE;
  19. // File type should be 'BM'
  20. if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
  21. return FALSE;
  22. HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
  23. if (hDIB == 0)
  24. return FALSE;
  25. // Read the remainder of the bitmap file.
  26. if (file.ReadHuge((LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER)) !=
  27. nFileLen - sizeof(BITMAPFILEHEADER) )
  28. {
  29. ::GlobalFree(hDIB);
  30. return FALSE;
  31. }
  32. BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
  33. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
  34. 1 << bmInfo.bmiHeader.biBitCount;
  35. // Create the palette
  36. if( nColors <= 256 )
  37. {
  38. UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
  39. LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
  40. pLP->palVersion = 0x300;
  41. pLP->palNumEntries = nColors;
  42. for( int i=0; i < nColors; i++)
  43. {
  44. pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
  45. pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
  46. pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
  47. pLP->palPalEntry[i].peFlags = 0;
  48. }
  49. pPal->CreatePalette( pLP );
  50. delete[] pLP;
  51. }
  52. *phDIB = hDIB;
  53. return TRUE;
  54. }
  55. void DrawDIB( CDC* pDC, HGLOBAL hDIB, CPalette *pPal )
  56. {
  57. LPVOID lpDIBBits; // Pointer to DIB bits
  58. BOOL bSuccess=FALSE;  // Success/fail flag
  59. BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
  60. int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
  61. 1 << bmInfo.bmiHeader.biBitCount;
  62. if( bmInfo.bmiHeader.biBitCount > 8 )
  63. lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
  64. bmInfo.bmiHeader.biClrUsed) +
  65. ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
  66. else
  67. lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
  68. if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) )
  69. {
  70. pDC->SelectPalette(pPal, FALSE);
  71. pDC->RealizePalette();
  72. }
  73. ::SetDIBitsToDevice(pDC->m_hDC,  // hDC
  74.    0, // DestX
  75.    0, // DestY
  76.    bmInfo.bmiHeader.biWidth, // nDestWidth
  77.    bmInfo.bmiHeader.biHeight, // nDestHeight
  78.    0, // SrcX
  79.    0, // SrcY
  80.    0, // nStartScan
  81.    bmInfo.bmiHeader.biHeight, // nNumScans
  82.    lpDIBBits, // lpBits
  83.    (LPBITMAPINFO)hDIB, // lpBitsInfo
  84.    DIB_RGB_COLORS);  // wUsage
  85. }