+HBITMAP wxDIB::CreateDDB(HDC hdc) const
+{
+ wxCHECK_MSG( m_handle, 0, _T("wxDIB::CreateDDB(): invalid object") );
+
+ DIBSECTION ds;
+ if ( !::GetObject(m_handle, sizeof(ds), &ds) )
+ {
+ wxLogLastError(_T("GetObject(hDIB)"));
+
+ return 0;
+ }
+
+ HBITMAP hbitmap = ::CreateCompatibleBitmap
+ (
+ hdc ? hdc : ScreenHDC(),
+ ds.dsBm.bmWidth,
+ ds.dsBm.bmHeight
+ );
+ if ( !hbitmap )
+ {
+ wxLogLastError(_T("CreateCompatibleBitmap()"));
+
+ return 0;
+ }
+
+ MemoryHDC hdcMem;
+ SelectInHDC select(hdcMem, hbitmap);
+ if ( !select )
+ {
+ wxLogLastError(_T("SelectObjct(hBitmap)"));
+ }
+
+ if ( !::SetDIBits
+ (
+ hdcMem,
+ hbitmap,
+ 0,
+ ds.dsBm.bmHeight,
+ ds.dsBm.bmBits,
+ (BITMAPINFO *)&ds.dsBmih,
+ DIB_RGB_COLORS
+ ) )
+ {
+ wxLogLastError(_T("SetDIBits"));
+
+ return 0;
+ }
+
+ return hbitmap;
+}
+
+#if wxUSE_PALETTE
+
+wxPalette *wxDIB::CreatePalette() const
+{
+ wxCHECK_MSG( m_handle, NULL, _T("wxDIB::CreatePalette(): invalid object") );
+
+ DIBSECTION ds;
+ if ( !::GetObject(m_handle, sizeof(ds), &ds) )
+ {
+ wxLogLastError(_T("GetObject(hDIB)"));
+
+ return 0;
+ }
+
+ // how many colours are we going to have in the palette?
+ DWORD biClrUsed = ds.dsBmih.biClrUsed;
+ if ( !biClrUsed )
+ {
+ // biClrUsed field might not be set
+ biClrUsed = 1 << ds.dsBmih.biBitCount;
+ }
+
+ if ( biClrUsed > 256 )
+ {
+ // only 8bpp bitmaps (and less) have palettes, so we surely don't
+ //
+ // NB: another possibility would be to return
+ // GetStockObject(DEFAULT_PALETTE) or even CreateHalftonePalette()?
+ return NULL;
+ }
+
+ // LOGPALETTE struct has only 1 element in palPalEntry array, we're
+ // going to have biClrUsed of them so add necessary space
+ LOGPALETTE *pPalette = (LOGPALETTE *)
+ malloc(sizeof(LOGPALETTE) + (biClrUsed - 1)*sizeof(PALETTEENTRY));
+ wxCHECK_MSG( pPalette, NULL, _T("out of memory") );
+
+ // initialize the palette header
+ pPalette->palVersion = 0x300; // magic number, not in docs but works
+ pPalette->palNumEntries = biClrUsed;
+
+ // and the colour table (it starts right after the end of the header)
+ const RGBQUAD *pRGB = (RGBQUAD *)((char *)&ds.dsBmih + ds.dsBmih.biSize);
+ for ( DWORD i = 0; i < biClrUsed; i++, pRGB++ )
+ {
+ pPalette->palPalEntry[i].peRed = pRGB->rgbRed;
+ pPalette->palPalEntry[i].peGreen = pRGB->rgbGreen;
+ pPalette->palPalEntry[i].peBlue = pRGB->rgbBlue;
+ pPalette->palPalEntry[i].peFlags = 0;
+ }
+
+ HPALETTE hPalette = ::CreatePalette(pPalette);
+
+ free(pPalette);
+
+ if ( !hPalette )
+ {
+ wxLogLastError(_T("CreatePalette"));
+
+ return NULL;
+ }
+
+ wxPalette *palette = new wxPalette;
+ palette->SetHPALETTE((WXHPALETTE)hPalette);
+
+ return palette;
+}
+
+#endif // wxUSE_PALETTE
+