+ // shouldn't be selected into a DC or GetDIBits() would fail
+ wxASSERT_MSG( !bitmap.GetSelectedInto(),
+ wxT("can't copy bitmap selected into wxMemoryDC") );
+
+ // prepare all the info we need
+ BITMAP bm;
+ HBITMAP hbmp = (HBITMAP)bitmap.GetHBITMAP();
+ if ( !GetObject(hbmp, sizeof(bm), &bm) )
+ {
+ wxLogLastError("GetObject(bitmap)");
+
+ return 0;
+ }
+
+ // calculate the number of bits per pixel and the number of items in
+ // bmiColors array (whose meaning depends on the bitmap format)
+ WORD biBits = bm.bmPlanes * bm.bmBitsPixel;
+ WORD biColors = wxGetNumOfBitmapColors(biBits);
+
+ BITMAPINFO bi2;
+
+ bool wantSizeOnly = pbi == NULL;
+ if ( wantSizeOnly )
+ pbi = &bi2;
+
+ // just for convenience
+ BITMAPINFOHEADER& bi = pbi->bmiHeader;
+
+ bi.biSize = sizeof(BITMAPINFOHEADER);
+ bi.biWidth = bm.bmWidth;
+ bi.biHeight = bm.bmHeight;
+ bi.biPlanes = 1;
+ bi.biBitCount = biBits;
+ bi.biCompression = BI_RGB;
+ bi.biSizeImage = 0;
+ bi.biXPelsPerMeter = 0;
+ bi.biYPelsPerMeter = 0;
+ bi.biClrUsed = 0;
+ bi.biClrImportant = 0;
+
+ // memory we need for BITMAPINFO only
+ DWORD dwLen = bi.biSize + biColors * sizeof(RGBQUAD);
+
+ // first get the image size
+ ScreenHDC hdc;
+ if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, NULL, pbi, DIB_RGB_COLORS) )
+ {
+ wxLogLastError("GetDIBits(NULL)");
+
+ return 0;
+ }
+
+ if ( wantSizeOnly )
+ {
+ // size of the header + size of the image
+ return dwLen + bi.biSizeImage;
+ }
+
+ // and now copy the bits
+ void *image = (char *)pbi + dwLen;
+ if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, image, pbi, DIB_RGB_COLORS) )
+ {
+ wxLogLastError("GetDIBits");
+
+ return 0;
+ }
+
+ return dwLen + bi.biSizeImage;
+}
+
+wxBitmap wxConvertDIBToBitmap(const BITMAPINFO *pbmi)
+{
+ // here we get BITMAPINFO struct followed by the actual bitmap bits and
+ // BITMAPINFO starts with BITMAPINFOHEADER followed by colour info
+ const BITMAPINFOHEADER *pbmih = &pbmi->bmiHeader;
+
+ // offset of image from the beginning of the header
+ DWORD ofs = wxGetNumOfBitmapColors(pbmih->biBitCount) * sizeof(RGBQUAD);
+ void *image = (char *)pbmih + sizeof(BITMAPINFOHEADER) + ofs;
+
+ ScreenHDC hdc;
+ HBITMAP hbmp = CreateDIBitmap(hdc, pbmih, CBM_INIT,
+ image, pbmi, DIB_RGB_COLORS);
+ if ( !hbmp )
+ {
+ wxLogLastError("CreateDIBitmap");
+ }
+
+ wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount);
+ bitmap.SetHBITMAP((WXHBITMAP)hbmp);
+
+ return bitmap;
+}
+
+#ifdef __WXDEBUG__
+
+static const wxChar *GetTymedName(DWORD tymed)
+{
+ static wxChar s_szBuf[128];
+ switch ( tymed ) {
+ case TYMED_HGLOBAL: return wxT("TYMED_HGLOBAL");
+ case TYMED_FILE: return wxT("TYMED_FILE");
+ case TYMED_ISTREAM: return wxT("TYMED_ISTREAM");
+ case TYMED_ISTORAGE: return wxT("TYMED_ISTORAGE");
+ case TYMED_GDI: return wxT("TYMED_GDI");
+ case TYMED_MFPICT: return wxT("TYMED_MFPICT");
+ case TYMED_ENHMF: return wxT("TYMED_ENHMF");
+ default:
+ wxSprintf(s_szBuf, wxT("type of media format %d (unknown)"), tymed);
+ return s_szBuf;
+ }
+}
+
+#endif // Debug
+
+#endif // not using OLE at all