IWICBitmapSource を クリップボードに転送するのがうまくいかなかった話
単純にIWICBitmapSource をClipboardに転送しようと思ったら HBITMAPに変換して
SetClipboardData(CF_BITMAP, hBitmap)
実行すればいいものだと思ってました。
最初に参考にしたサイトは、地道に データ作って CreateBitmapするものだった。
HBitmap 自体はちゃんとしたデータなのだけど、コピーできませんでした。
次に参考にしたのが GdiPlus::GetHBITMAPを使うものだったのだけどこれもNG。
試しに、適当な BMPファイルをLoadImageで取り出してみたらコピーできたので
GdiPlus::Saveで前述の Bitmap を保存してからLoadImageで試してみたところ、コピーに失敗した。
どうやら、クリップボードに転送できない BMPデータがあるようだ ・ω・
void SetBitmapSourceonClipboard(IWICBitmapSource* pImage) { HANDLE tt; HBITMAP bitmap; WICPixelFormatGUID format; UINT width = 0, height = 0; pImage->GetSize(&width, &height); HRESULT hr = pImage->GetPixelFormat(&format); UINT bpp = GetBpp(&format); IWICBitmap* copyBMP; int sz = (width * bpp) / 8; BITMAPV5HEADER bi = { 0 }; HGLOBAL global = GlobalAlloc(GMEM_MOVEABLE, sizeof(bi) + height * (sz + 3)/4 * 4 ); bi.bV5Size = sizeof(BITMAPV5HEADER), bi.bV5Width = width; bi.bV5Height = height; bi.bV5Planes = 1; bi.bV5BitCount = (WORD)bpp; bi.bV5Compression = BI_RGB; bi.bV5SizeImage = bpp / 8 * width * height; bi.bV5RedMask = 0x000000ff; bi.bV5GreenMask = 0x0000ff00; bi.bV5BlueMask = 0x00ff0000; bi.bV5AlphaMask = 0xff000000; bi.bV5CSType = LCS_WINDOWS_COLOR_SPACE; bi.bV5Intent = LCS_GM_GRAPHICS; bi.bV5ClrUsed = 0; if (global) { BYTE* buffer = (BYTE*)GlobalLock(global); if (buffer) { WICRect rc; CopyMemory(buffer, &bi, sizeof(bi)); rc.X = 0; rc.Width = width; rc.Height = 1; for(int h=0;h<height;h++) { rc.Y = height - h - 1; pImage->CopyPixels( &rc, sz, sz * 1, buffer + (sz + 3) /4 * 4 * h + sizeof(bi)); } GlobalUnlock(global); EmptyClipboard(); tt=SetClipboardData(CF_DIBV5, global); } GlobalFree(global); } } |
最期に試したのが、DIBV5で転送する方法。
これはうまくいった
Comments