m_ncolortableentries + sizeof(bitmapfileheader); // meaning of bfsize open to interpretation bmfh.bfreserved1 = bmfh.bfreserved2 = 0; bmfh.bfoffbits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader) + sizeof(rgbquad) * m_ncolortableentries; handle hfile = ::createfile(strpathname, generic_write | generic_read, 0, null, create_always, file_attribute_normal, null); assert(hfile != invalid_handle_value); int nsize = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader) + sizeof(rgbquad) * m_ncolortableentries + m_dwsizeimage; handle hmap = ::createfilemapping(hfile, null, page_readwrite, 0, nsize, null); dword dwerr = ::getlasterror(); assert(hmap != null); lpvoid lpvfile = ::mapviewoffile(hmap, file_map_write, 0, 0, 0); // map whole file assert(lpvfile != null); lpbyte lpbcurrent = (lpbyte) lpvfile; memcpy(lpbcurrent, &bmfh, sizeof(bitmapfileheader)); // file header lpbcurrent += sizeof(bitmapfileheader); lpbitmapinfoheader lpbmih = (lpbitmapinfoheader) lpbcurrent; memcpy(lpbcurrent, m_lpbmih, sizeof(bitmapinfoheader) + sizeof(rgbquad) * m_ncolortableentries); // info lpbcurrent += sizeof(bitmapinfoheader) + sizeof(rgbquad) * m_ncolortableentries; memcpy(lpbcurrent, m_lpimage, m_dwsizeimage); // bit image dword dwsizeimage = m_dwsizeimage; empty(); m_dwsizeimage = dwsizeimage; m_nbmihalloc = m_nimagealloc = noalloc; m_lpbmih = lpbmih; m_lpimage = lpbcurrent; m_hfile = hfile; m_hmap = hmap; m_lpvfile = lpvfile; computepalettesize(m_lpbmih->bibitcount); computemetrics(); makepalette(); return true; } bool cdib::attachmemory(lpvoid lpvmem, bool bmustdelete, hglobal hglobal) { // assumes contiguous bitmapinfoheader, color table, image // color table could be zero length empty(); m_hglobal = hglobal; if(bmustdelete == false) { m_nbmihalloc = noalloc; } else { m_nbmihalloc = ((hglobal == null) ? crtalloc : heapalloc); } try { m_lpbmih = (lpbitmapinfoheader) lpvmem; computemetrics(); computepalettesize(m_lpbmih->bibitcount); m_lpimage = (lpbyte) m_lpvcolortable + sizeof(rgbquad) * m_ncolortableentries; makepalette(); } catch(cexception* pe) { afxmessagebox("attachmemory error"); pe->delete(); return false; } return true; } uint cdib::usepalette(cdc* pdc, bool bbackground /* = false */) { if(m_hpalette == null) return 0; hdc hdc = pdc->getsafehdc(); ::selectpalette(hdc, m_hpalette, bbackground); return ::realizepalette(hdc); } bool cdib::draw(cdc* pdc, cpoint origin, csize size) { if(m_lpbmih == null) return false; if(m_hpalette != null) { ::selectpalette(pdc->getsafehdc(), m_hpalette, true); } pdc->setstretchbltmode(coloroncolor); ::stretchdibits(pdc->getsafehdc(), origin.x, origin.y, size.cx, size.cy, 0, 0, m_lpbmih->biwidth, m_lpbmih->biheight, m_lpimage, (lpbitmapinfo) m_lpbmih, dib_rgb_colors, srccopy); return true; } hbitmap cdib::createsection(cdc* pdc /* = null */) { if(m_lpbmih == null) return null; if(m_lpimage != null) return null; // can only do this if image doesn't exist m_hbitmap = ::createdibsection(pdc->getsafehdc(), (lpbitmapinfo) m_lpbmih, dib_rgb_colors, (lpvoid*) &m_lpimage, null, 0); assert(m_lpimage != null); return m_hbitmap; } bool cdib::makepalette() { // makes a logical palette (m_hpalette) from the dib's color table // this palette will be selected and realized prior to drawing the dib if(m_ncolortableentries == 0) return false; if(m_hpalette != null) ::deleteobject(m_hpalette); trace("cdib::makepalette -- m_ncolortableentries = %d\n", m_ncolortableentries); lplogpalette plogpal = (lplogpalette) new char[2 * sizeof(word) + m_ncolortableentries * sizeof(paletteentry)]; plogpal->palversion = 0x300; plogpal->palnumentries = m_ncolortableentries; lprgbquad pdibquad = (lprgbquad) m_lpvcolortable; for(int i = 0; i < m_ncolortableentries; i++) { plogpal->palpalentry[i].pered = pdibquad->rgbred; plogpal->palpalentry[i].pegreen = pdibquad->rgbgreen; plogpal->palpalentry[i].peblue = pdibquad->rgbblue; plogpal->palpalentry[i].peflags = 0; pdibquad++; } m_hpalette = ::createpalette(plogpal); delete plogpal; return true; } bool cdib::setsystempalette(cdc* pdc) { // if the dib doesn't have a color table, we can use the system's halftone palette if(m_ncolortableentries != 0) return false; m_hpalette = ::createhalftonepalette(pdc->getsafehdc()); return true; } hbitmap cdib::createbitmap(cdc* pdc) { if (m_dwsizeimage == 0) return null; hbitmap hbitmap = ::createdibitmap(pdc->getsafehdc(), m_lpbmih, cbm_init, m_lpimage, (lpbitmapinfo) m_lpbmih, dib_rgb_colors); assert(hbitmap != null); return hbitmap; } bool cdib::compress(cdc* pdc, bool bcompress /* = true */) { // 1. makes gdi bitmap from existing dib // 2. makes a new dib fr