+bool wxDIB::Create(const wxBitmap& bmp)
+{
+ wxCHECK_MSG( bmp.Ok(), false, _T("wxDIB::Create(): invalid bitmap") );
+
+ // this bitmap could already be a DIB section in which case we don't need
+ // to convert it to DIB
+ HBITMAP hbmp = GetHbitmapOf(bmp);
+
+ DIBSECTION ds;
+ if ( GetDIBSection(hbmp, &ds) )
+ {
+ m_handle = hbmp;
+
+ // wxBitmap will free it, not we
+ m_ownsHandle = false;
+
+ // copy all the bitmap parameters too as we have them now anyhow
+ m_width = ds.dsBm.bmWidth;
+ m_height = ds.dsBm.bmHeight;
+ m_depth = ds.dsBm.bmBitsPixel;
+
+ m_data = ds.dsBm.bmBits;
+ }
+ else // no, it's a DDB -- convert it to DIB
+ {
+ const int w = bmp.GetWidth();
+ const int h = bmp.GetHeight();
+ int d = bmp.GetDepth();
+ if ( d == -1 )
+ d = wxDisplayDepth();
+
+ if ( !Create(w, h, d) )
+ return false;
+
+ if ( !GetDIBSection(m_handle, &ds) )
+ {
+ // we've just created a new DIB section, why should this fail?
+ wxFAIL_MSG( _T("GetObject(DIBSECTION) unexpectedly failed") );
+
+ return false;
+ }
+
+ if ( !::GetDIBits
+ (
+ ScreenHDC(), // the DC to use
+ hbmp, // the source DDB
+ 0, // first scan line
+ h, // number of lines to copy
+ ds.dsBm.bmBits, // pointer to the buffer
+ (BITMAPINFO *)&ds.dsBmih, // bitmap header
+ DIB_RGB_COLORS // and not DIB_PAL_COLORS
+ ) )
+ {
+ wxLogLastError(wxT("GetDIBits()"));
+
+ return 0;
+ }
+ }
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// Loading/saving the DIBs
+// ----------------------------------------------------------------------------
+
+bool wxDIB::Load(const wxString& filename)
+{
+ m_handle = (HBITMAP)::LoadImage
+ (
+ wxGetInstance(),
+ filename,
+ IMAGE_BITMAP,
+ 0, 0, // don't specify the size
+ LR_CREATEDIBSECTION | LR_LOADFROMFILE
+ );
+ if ( !m_handle )
+ {
+ wxLogLastError(_T("LoadImage(LR_CREATEDIBSECTION | LR_LOADFROMFILE)"));
+
+ return false;
+ }
+
+ return true;
+}
+
+bool wxDIB::Save(const wxString& filename)
+{
+ wxCHECK_MSG( m_handle, false, _T("wxDIB::Save(): invalid object") );
+
+ wxFile file(filename, wxFile::write);
+ bool ok = file.IsOpened();
+ if ( ok )
+ {
+ DIBSECTION ds;
+ if ( !GetDIBSection(m_handle, &ds) )
+ {
+ wxLogLastError(_T("GetObject(hDIB)"));
+ }
+ else
+ {
+ BITMAPFILEHEADER bmpHdr;
+ wxZeroMemory(bmpHdr);
+
+ const size_t sizeHdr = ds.dsBmih.biSize;
+ const size_t sizeImage = ds.dsBmih.biSizeImage;
+
+ bmpHdr.bfType = 0x4d42; // 'BM' in little endian
+ bmpHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + ds.dsBmih.biSize;
+ bmpHdr.bfSize = bmpHdr.bfOffBits + sizeImage;
+
+ // first write the file header, then the bitmap header and finally the
+ // bitmap data itself
+ ok = file.Write(&bmpHdr, sizeof(bmpHdr)) == sizeof(bmpHdr) &&
+ file.Write(&ds.dsBmih, sizeHdr) == sizeHdr &&
+ file.Write(ds.dsBm.bmBits, sizeImage) == sizeImage;
+ }
+ }
+
+ if ( !ok )
+ {
+ wxLogError(_("Failed to save the bitmap image to file \"%s\"."),
+ filename.c_str());
+ }
+
+ return ok;
+}
+