dib.cpp
上传用户:biuytresa
上传日期:2007-12-07
资源大小:721k
文件大小:16k
源码类别:

DNA

开发平台:

Visual C++

  1. // dib.cpp
  2. #include "stdafx.h"
  3. #include "dib.h"
  4. //   - This helper class was borrowed and modifed from
  5. //     David Kruglinski's book Inside Visual C++.
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. IMPLEMENT_SERIAL(CDib, CObject, 0);
  12. CDib::CDib()
  13. {
  14. m_hFile = NULL;
  15. m_hBitmap = NULL;
  16. m_hPalette = NULL;
  17. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  18. Empty();
  19. }
  20. CDib::CDib(CSize size, int nBitCount)
  21. {
  22. m_hFile = NULL;
  23. m_hBitmap = NULL;
  24. m_hPalette = NULL;
  25. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  26. Empty();
  27. ComputePaletteSize(nBitCount);
  28. m_lpBMIH = (LPBITMAPINFOHEADER) new 
  29. char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];
  30. m_nBmihAlloc = crtAlloc;
  31. m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
  32. m_lpBMIH->biWidth = size.cx;
  33. m_lpBMIH->biHeight = size.cy;
  34. m_lpBMIH->biPlanes = 1;
  35. m_lpBMIH->biBitCount = nBitCount;
  36. m_lpBMIH->biCompression = BI_RGB;
  37. m_lpBMIH->biSizeImage = 0;
  38. m_lpBMIH->biXPelsPerMeter = 0;
  39. m_lpBMIH->biYPelsPerMeter = 0;
  40. m_lpBMIH->biClrUsed = m_nColorTableEntries;
  41. m_lpBMIH->biClrImportant = m_nColorTableEntries;
  42. ComputeMetrics();
  43. memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);
  44. m_lpImage = NULL;  // no data yet
  45. }
  46. CDib::~CDib()
  47. {
  48. Empty();
  49. }
  50. CSize CDib::GetDimensions()
  51. {
  52. if(m_lpBMIH == NULL) return CSize(0, 0);
  53. return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);
  54. }
  55. BOOL CDib::AttachMapFile(const char* strPathname, BOOL bShare) // for reading
  56. {
  57. // if we open the same file twice, Windows treats it as 2 separate files
  58. // doesn't work with rare BMP files where # palette entries > biClrUsed
  59. HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ,
  60. bShare ? FILE_SHARE_READ : 0,
  61. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  62. ASSERT(hFile != INVALID_HANDLE_VALUE);
  63. DWORD dwFileSize = ::GetFileSize(hFile, NULL);
  64. HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
  65. DWORD dwErr = ::GetLastError();
  66. if(hMap == NULL) {
  67. AfxMessageBox("Empty bitmap file");
  68. return FALSE;
  69. }
  70. LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
  71. ASSERT(lpvFile != NULL);
  72. if(((LPBITMAPFILEHEADER) lpvFile)->bfType != 0x4d42) {
  73. AfxMessageBox("Invalid bitmap file");
  74. DetachMapFile();
  75. return FALSE;
  76. }
  77. AttachMemory((LPBYTE) lpvFile + sizeof(BITMAPFILEHEADER));
  78. m_lpvFile = lpvFile;
  79. m_hFile = hFile;
  80. m_hMap = hMap;
  81. return TRUE;
  82. }
  83. BOOL CDib::CopyToMapFile(const char* strPathname)
  84. {
  85. // copies DIB to a new file, releases prior pointers
  86. // if you previously used CreateSection, the HBITMAP will be NULL (and unusable)
  87. BITMAPFILEHEADER bmfh;
  88. bmfh.bfType = 0x4d42;  // 'BM'
  89. bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) +
  90. sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER);
  91. // meaning of bfSize open to interpretation
  92. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  93. bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  94. sizeof(RGBQUAD) * m_nColorTableEntries;
  95. HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL,
  96. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  97. ASSERT(hFile != INVALID_HANDLE_VALUE);
  98. int nSize =  sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  99. sizeof(RGBQUAD) * m_nColorTableEntries +  m_dwSizeImage;
  100. HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NULL);
  101. DWORD dwErr = ::GetLastError();
  102. ASSERT(hMap != NULL);
  103. LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file
  104. ASSERT(lpvFile != NULL);
  105. LPBYTE lpbCurrent = (LPBYTE) lpvFile;
  106. memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // file header
  107. lpbCurrent += sizeof(BITMAPFILEHEADER);
  108. LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent;
  109. memcpy(lpbCurrent, m_lpBMIH,
  110. sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // info
  111. lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  112. memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // bit image
  113. DWORD dwSizeImage = m_dwSizeImage;
  114. Empty();
  115. m_dwSizeImage = dwSizeImage;
  116. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  117. m_lpBMIH = lpBMIH;
  118. m_lpImage = lpbCurrent;
  119. m_hFile = hFile;
  120. m_hMap = hMap;
  121. m_lpvFile = lpvFile;
  122. ComputePaletteSize(m_lpBMIH->biBitCount);
  123. ComputeMetrics();
  124. MakePalette();
  125. return TRUE;
  126. }
  127. BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal)
  128. {
  129. // assumes contiguous BITMAPINFOHEADER, color table, image
  130. // color table could be zero length
  131. Empty();
  132. m_hGlobal = hGlobal;
  133. if(bMustDelete == FALSE) {
  134. m_nBmihAlloc = noAlloc;
  135. }
  136. else {
  137. m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc);
  138. }
  139. try {
  140. m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem;
  141. ComputeMetrics();
  142. ComputePaletteSize(m_lpBMIH->biBitCount);
  143. m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntries;
  144. MakePalette();
  145. }
  146. catch(CException* pe) {
  147. AfxMessageBox("AttachMemory error");
  148. pe->Delete();
  149. return FALSE;
  150. }
  151. return TRUE;
  152. }
  153. UINT CDib::UsePalette(CDC* pDC, BOOL bBackground /* = FALSE */)
  154. {
  155. if(m_hPalette == NULL) return 0;
  156. HDC hdc = pDC->GetSafeHdc();
  157. ::SelectPalette(hdc, m_hPalette, bBackground);
  158. return ::RealizePalette(hdc);
  159. }
  160. BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)
  161. {
  162. if(m_lpBMIH == NULL) return FALSE;
  163. if(m_hPalette != NULL) {
  164. ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
  165. }
  166. pDC->SetStretchBltMode(COLORONCOLOR);
  167. ::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,
  168. 0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,
  169. m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);
  170. return TRUE;
  171. }
  172. HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)
  173. {
  174. if(m_lpBMIH == NULL) return NULL;
  175. if(m_lpImage != NULL) return NULL; // can only do this if image doesn't exist
  176. m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
  177. DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
  178. ASSERT(m_lpImage != NULL);
  179. return m_hBitmap;
  180. }
  181. BOOL CDib::MakePalette()
  182. {
  183. // makes a logical palette (m_hPalette) from the DIB's color table
  184. // this palette will be selected and realized prior to drawing the DIB
  185. if(m_nColorTableEntries == 0) return FALSE;
  186. if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
  187. TRACE("CDib::MakePalette -- m_nColorTableEntries = %dn", m_nColorTableEntries);
  188. LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
  189. m_nColorTableEntries * sizeof(PALETTEENTRY)];
  190. pLogPal->palVersion = 0x300;
  191. pLogPal->palNumEntries = m_nColorTableEntries;
  192. LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;
  193. for(int i = 0; i < m_nColorTableEntries; i++) {
  194. pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
  195. pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
  196. pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
  197. pLogPal->palPalEntry[i].peFlags = 0;
  198. pDibQuad++;
  199. }
  200. m_hPalette = ::CreatePalette(pLogPal);
  201. delete pLogPal;
  202. return TRUE;
  203. }
  204. BOOL CDib::SetSystemPalette(CDC* pDC)
  205. {
  206. // if the DIB doesn't have a color table, we can use the system's halftone palette
  207. if(m_nColorTableEntries != 0) return FALSE;
  208. m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());
  209. return TRUE;
  210. }
  211. HBITMAP CDib::CreateBitmap(CDC* pDC)
  212. {
  213.     if (m_dwSizeImage == 0) return NULL;
  214.     HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,
  215.             CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);
  216.     ASSERT(hBitmap != NULL);
  217.     return hBitmap;
  218. }
  219. BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */)
  220. {
  221. // 1. makes GDI bitmap from existing DIB
  222. // 2. makes a new DIB from GDI bitmap with compression
  223. // 3. cleans up the original DIB
  224. // 4. puts the new DIB in the object
  225. if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE;
  226. // compression supported only for 4 bpp and 8 bpp DIBs
  227. if(m_hBitmap) return FALSE; // can't compress a DIB Section!
  228. TRACE("Compress: original palette size = %dn", m_nColorTableEntries); 
  229. HDC hdc = pDC->GetSafeHdc();
  230. HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE);
  231. HBITMAP hBitmap;  // temporary
  232. if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE;
  233. int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  234. LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  235. memcpy(lpBMIH, m_lpBMIH, nSize);  // new header
  236. if(bCompress) {
  237. switch (lpBMIH->biBitCount) {
  238. case 4:
  239. lpBMIH->biCompression = BI_RLE4;
  240. break;
  241. case 8:
  242. lpBMIH->biCompression = BI_RLE8;
  243. break;
  244. default:
  245. ASSERT(FALSE);
  246. }
  247. // calls GetDIBits with null data pointer to get size of compressed DIB
  248. if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,
  249. NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) {
  250. AfxMessageBox("Unable to compress this DIB");
  251. // probably a problem with the color table
  252.   ::DeleteObject(hBitmap);
  253. delete [] lpBMIH;
  254. ::SelectPalette(hdc, hOldPalette, FALSE);
  255. return FALSE; 
  256. }
  257. if (lpBMIH->biSizeImage == 0) {
  258. AfxMessageBox("Driver can't do compression");
  259.   ::DeleteObject(hBitmap);
  260. delete [] lpBMIH;
  261. ::SelectPalette(hdc, hOldPalette, FALSE);
  262. return FALSE; 
  263. }
  264. else {
  265. m_dwSizeImage = lpBMIH->biSizeImage;
  266. }
  267. }
  268. else {
  269. lpBMIH->biCompression = BI_RGB; // decompress
  270. // figure the image size from the bitmap width and height
  271. DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;
  272. if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) {
  273. dwBytes++;
  274. }
  275. dwBytes *= 4;
  276. m_dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression
  277. lpBMIH->biSizeImage = m_dwSizeImage;
  278. // second GetDIBits call to make DIB
  279. LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage];
  280. VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,
  281.      lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS));
  282.     TRACE("dib successfully created - height = %dn", lpBMIH->biHeight);
  283. ::DeleteObject(hBitmap);
  284. Empty();
  285. m_nBmihAlloc = m_nImageAlloc = crtAlloc;
  286. m_lpBMIH = lpBMIH;
  287. m_lpImage = lpImage;
  288. ComputeMetrics();
  289. ComputePaletteSize(m_lpBMIH->biBitCount);
  290. MakePalette();
  291. ::SelectPalette(hdc, hOldPalette, FALSE);
  292. TRACE("Compress: new palette size = %dn", m_nColorTableEntries); 
  293. return TRUE;
  294. }
  295. BOOL CDib::Read(CFile* pFile)
  296. {
  297. // 1. read file header to get size of info hdr + color table
  298. // 2. read info hdr (to get image size) and color table
  299. // 3. read image
  300. // can't use bfSize in file header
  301. Empty();
  302. int nCount, nSize;
  303. BITMAPFILEHEADER bmfh;
  304. try {
  305. nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  306. if(nCount != sizeof(BITMAPFILEHEADER)) {
  307. throw new CException;
  308. }
  309. if(bmfh.bfType != 0x4d42) {
  310. throw new CException;
  311. }
  312. nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
  313. m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  314. m_nBmihAlloc = m_nImageAlloc = crtAlloc;
  315. nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
  316. ComputeMetrics();
  317. ComputePaletteSize(m_lpBMIH->biBitCount);
  318. MakePalette();
  319. m_lpImage = (LPBYTE) new char[m_dwSizeImage];
  320. nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
  321. }
  322. catch(CException* pe) {
  323. AfxMessageBox("Read error");
  324. pe->Delete();
  325. return FALSE;
  326. }
  327. return TRUE;
  328. }
  329. BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */)
  330. {
  331. // new function reads BMP from disk and creates a DIB section
  332. //    allows modification of bitmaps from disk
  333. // 1. read file header to get size of info hdr + color table
  334. // 2. read info hdr (to get image size) and color table
  335. // 3. create DIB section based on header parms
  336. // 4. read image into memory that CreateDibSection allocates
  337. Empty();
  338. int nCount, nSize;
  339. BITMAPFILEHEADER bmfh;
  340. try {
  341. nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  342. if(nCount != sizeof(BITMAPFILEHEADER)) {
  343. throw new CException;
  344. }
  345. if(bmfh.bfType != 0x4d42) {
  346. throw new CException;
  347. }
  348. nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
  349. m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  350. m_nBmihAlloc = crtAlloc;
  351. m_nImageAlloc = noAlloc;
  352. nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
  353. if(m_lpBMIH->biCompression != BI_RGB) {
  354. throw new CException;
  355. }
  356. ComputeMetrics();
  357. ComputePaletteSize(m_lpBMIH->biBitCount);
  358. MakePalette();
  359. UsePalette(pDC);
  360. m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,
  361. DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0);
  362. ASSERT(m_lpImage != NULL);
  363. nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
  364. }
  365. catch(CException* pe) {
  366. AfxMessageBox("ReadSection error");
  367. pe->Delete();
  368. return FALSE;
  369. }
  370. return TRUE;
  371. }
  372. BOOL CDib::Write(CFile* pFile)
  373. {
  374. BITMAPFILEHEADER bmfh;
  375. bmfh.bfType = 0x4d42;  // 'BM'
  376. int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;
  377. bmfh.bfSize = 0;
  378. // bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage;
  379. // meaning of bfSize open to interpretation (bytes, words, dwords?) -- we won't use it
  380. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  381. bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  382. sizeof(RGBQUAD) * m_nColorTableEntries;
  383. try {
  384. pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
  385. pFile->Write((LPVOID) m_lpBMIH,  nSizeHdr);
  386. pFile->Write((LPVOID) m_lpImage, m_dwSizeImage);
  387. }
  388. catch(CException* pe) {
  389. pe->Delete();
  390. AfxMessageBox("write error");
  391. return FALSE;
  392. }
  393. return TRUE;
  394. }
  395. void CDib::Serialize(CArchive& ar)
  396. {
  397. DWORD dwPos;
  398. dwPos = ar.GetFile()->GetPosition();
  399. TRACE("CDib::Serialize -- pos = %dn", dwPos);
  400. ar.Flush();
  401. dwPos = ar.GetFile()->GetPosition();
  402. TRACE("CDib::Serialize -- pos = %dn", dwPos);
  403. if(ar.IsStoring()) {
  404. Write(ar.GetFile());
  405. }
  406. else {
  407. Read(ar.GetFile());
  408. }
  409. }
  410. // helper functions
  411. void CDib::ComputePaletteSize(int nBitCount)
  412. {
  413. if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0)) {
  414. switch(nBitCount) {
  415. case 1:
  416. m_nColorTableEntries = 2;
  417. break;
  418. case 4:
  419. m_nColorTableEntries = 16;
  420. break;
  421. case 8:
  422. m_nColorTableEntries = 256;
  423. break;
  424. case 16:
  425. case 24:
  426. case 32:
  427. m_nColorTableEntries = 0;
  428. break;
  429. default:
  430. ASSERT(FALSE);
  431. }
  432. }
  433. else {
  434. m_nColorTableEntries = m_lpBMIH->biClrUsed;
  435. }
  436. ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256)); 
  437. }
  438. void CDib::ComputeMetrics()
  439. {
  440. if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
  441. TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmapn");
  442. throw new CException;
  443. }
  444. m_dwSizeImage = m_lpBMIH->biSizeImage;
  445. if(m_dwSizeImage == 0) {
  446. DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;
  447. if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32) {
  448. dwBytes++;
  449. }
  450. dwBytes *= 4;
  451. m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression
  452. }
  453. m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);
  454. }
  455. void CDib::Empty()
  456. {
  457. // this is supposed to clean up whatever is in the DIB
  458. DetachMapFile();
  459. if(m_nBmihAlloc == crtAlloc) {
  460. delete [] m_lpBMIH;
  461. }
  462. else if(m_nBmihAlloc == heapAlloc) {
  463. ::GlobalUnlock(m_hGlobal);
  464. ::GlobalFree(m_hGlobal);
  465. }
  466. if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
  467. if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
  468. if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
  469. m_nBmihAlloc = m_nImageAlloc = noAlloc;
  470. m_hGlobal = NULL;
  471. m_lpBMIH = NULL;
  472. m_lpImage = NULL;
  473. m_lpvColorTable = NULL;
  474. m_nColorTableEntries = 0;
  475. m_dwSizeImage = 0;
  476. m_lpvFile = NULL;
  477. m_hMap = NULL;
  478. m_hFile = NULL;
  479. m_hBitmap = NULL;
  480. m_hPalette = NULL;
  481. }
  482. void CDib::DetachMapFile()
  483. {
  484. if(m_hFile == NULL) return;
  485. ::UnmapViewOfFile(m_lpvFile);
  486. ::CloseHandle(m_hMap);
  487. ::CloseHandle(m_hFile);
  488. m_hFile = NULL;
  489. }