GetDIBits()を使う、以上。
で終わる話なのですが、BITMAPINFOを作成するために必要なメモリサイズを算出するのに手こずったので、結果だけ置いておきます。
なお、このコードで作成されるのは、スクリーンショットを撮ったときに得られるビットマップデータに合わせてbiCompressionがBI_BITFIELDSで、カラーマスクあり、カラーパレットなしの32ビットカラーDIBビットマップです。
BITMAPINFO* createBitmapInfo(HBITMAP hBitmap) { BITMAP bitmap; GetObject(hBitmap, BITMAP.sizeof, &bitmap); HDC hdc = GetDC(null); // Allocates memory of BITMAPINFO const uint bitsPerPixel = bitmap.bmPlanes * 32; // 32 bits color const uint colorMaskBytes = { // Contains color mask when biCompression is BI_BITFIELDS. return 4 * 3; // 4 bytes * 3 masks(R,G,B) }(); const uint numPallet = 0; // Wants that no color palette. const uint widthBytes = (bitmap.bmWidth * bitsPerPixel + 31) / 32 * 4; const uint bitmapBodySize = widthBytes * bitmap.bmHeight; BITMAPINFO* pbi = cast(BITMAPINFO*)new ubyte[ BITMAPINFOHEADER.sizeof + colorMaskBytes + RGBQUAD.sizeof * numPallet + bitmapBodySize]; pbi.bmiHeader.biSize = BITMAPINFOHEADER.sizeof; // First 6 members pbi.bmiHeader.biWidth = bitmap.bmWidth; pbi.bmiHeader.biHeight = bitmap.bmHeight; pbi.bmiHeader.biPlanes = bitmap.bmPlanes; pbi.bmiHeader.biBitCount = 32; // 32 bits color pbi.bmiHeader.biCompression = BI_BITFIELDS; // Contains color mask if (0 == core.sys.windows.wingdi.GetDIBits( hdc, hBitmap, 0, bitmap.bmHeight, cast(ubyte*)pbi + BITMAPINFOHEADER.sizeof + colorMaskBytes + RGBQUAD.sizeof * numPallet, pbi, DIB_RGB_COLORS)) { throw new Exception("createBitmapInfo failure"); } ReleaseDC(null, hdc); return pbi; }